Project 1e - Detect off-road, increase Friction, Shake camera
Goal: The goal of this phase of the project was to handle the case when the car accidentally goes off of the road. When this is detected, the camera shakes to simulate driving on rocky terrain. Also, the cars ability to go fast is greatly hampered, giving the driver incentive to stay on the road.

System: My project was written on Windows XP using Processing (http://processing.org). The Java wrapper used by Processing should make it cross-platform compatible.

Off-Road Detection: I used a simple but effective algorithm to determine whether a car is off the road or not. First I loop through every known point on the centerline of the road. I take the minimum distance between these points and the car. If this minimum distance is less than the radius of the road, then the car is off the road. Here is my algorithm in pseudocode:

function isOffRoad() {

min_distance = -1;
len;

//find the minimum distance
for (each point on road centerline) {
len = distance from point to car
if(len < min_distance || min_distance == -1)
min_distance = len;
}

// if min_distance is too big we are off road
if(min_distance > toad width / 2.0)
return true;

//otherwise we are still on road
return false;
}

Friction: When the car is determined to be off of the road, a strong friction force is applied to simulate driving on rough terrain. This is easily accomplished by scaling the maximum velocity of the car by a factor of one fourth.

Camera Shake: Camera shake occurs when the car leaves the road and is proportional to the cars speed. If the car is going fast there will appear to be a lot of camera shake. Obviously if the car is stopped the camera won't shake. First I initialize variables for X, Y, and Z that will be my "nudge factors". These are initially set to zero and won't be changed if the car is still on the road. If the car is off the road I call a random number for the pixels the camera will be nudged and multiply it by two factors. One of these is the speed of the vehicle (taken using the distance between the last two positions of the car). Therefore if the speed is zero than the nudge factor on all axis will be zero. The second factor is the camera distance from the car. I found that in overhead mode, the camera shake isn't noticeable because the objects are so far away. Therefore the farther away the camera is, the more shake their needs to be in order to seem consistent. This is ultimately the code I used to determine the nudge factors:

float multiplier = ((-1.0 * car1_camdistance) + 510) / 2000;
float shake_ammount = (multiplier + .3) * linelen(c2x, c2y, c2x_before1, c2y_before1);

if(isOffRoad())
{
xnudge=random(shake_ammount) - shake_ammount/2.0;
ynudge=random(shake_ammount) - shake_ammount/2.0;
znudge=random(shake_ammount) - shake_ammount/2.0;
}

Now, when each object is drawn (the road, the computer controlled car, and the human controlled car) their positions get equally adjusted by the nudge factors. Since this occurs at 15 frames per second, the camera appears to shake when the vehicle is off road.

Applet Instructions:
Drag the vertices to edit the track.
Drag midpoints (small dots) to create a new vertex.
Press 1 to enable editing mode.
Press 2 to enable 2D racing mode.
Press 3 to enable 3D racing mode.
Press UP ARROW or DOWN ARROW in racing modes to change the camera angle.
Press LEFT ARROW or RIGHT ARROW in racing modes to change the camera distance.
Press + or - in editing mode to create less or more interpolated curves.
Use your mouse to control the car. Up/Down = Acceleration. Left/Right = Turn.

Applet:
To view this content, you need to install Java from java.com


Source Code: p1e.pde

Demo Video: p1e-demo-divx.avi (10 MB, DivX Required)

Demo Pictures:
(click to enlarge)

edit
The green human controlled car racing the red computer controlled car.

Copyright Info :: W3C :: CSS