# Hover Craft Algorithm

I have a hover craft and I would like to implement it but I don't know what the algorithm or equation of how the physics work is. The variables I think would be the falling speed, the aircraft position and the distance from the ground. Based on that I need it to return the velocity. What makes it so hard is that it needs to work regardless of the situation like falling off a big cliff. Lets say it falls from a very high altitude. Once the craft is at a certain position from the ground the jets should gradually bring the craft down to speed and shoot it up from the ground a little depending on the height. Here is a picture illustrating what I'm talking about.

Could I get some help on what the algorithm would be determining the hover craft's vertical velocity?

Thanks.

• What language and framework are you using? The question is so broad is looks like you just have an idea but no clue how to program, which would bring me to suggest start at a much easier programming project than a game. – brandon Jul 16 '12 at 3:12

Use physics. First you'll need to establish this:

1. Hovercraft physics principles

The hovercraft's engines will produce an upwards force of magnitude F, that is opposite in direction to the gravitational force G. The vertical component of the sum of all forces acting on the hovercraft at any given time will be:

sum_of_forces.y = G - F


The First Law of Newton says that force equals mass times acceleration. If the hovercraft's mass is m and the gravitational acceleration is 9.8 [m/s2], then G = 9.8 * m. As for F, its acceleration will be variable, so we'll call it f. Therefore, F = f * m. Replacing G and F in the equation above, we have:

sum_of_forces.y = 9.8 * m - f * m;
sum_of_forces.y = (9.8 - f) * m;


All you care about is the acceleration, which we'll name a:

a.y = sum_of_forces.y / m
a.y = 9.8 - f


The value of a.y should be recalculated every time f changes, or to make things simpler, it should be recalculated on every frame.

The y component of the hovercraft's velocity will be called v.y. Speed changes based on acceleration, and since you're recalculating the acceleration on every frame, you'll do the same with the velocity:

v.y = v.y + a.y;


And consequently the position. But you probably knew that already:

y = y + v.y;


2. Accelerating based on distance to the ground

Now let's get to the fun part. The hovercraft's vertical acceleration must vary according to its distance from the ground, right? So if h is the distance from the hovercraft to the ground, both F (the upwards force opposed to gravity) and f (the upwards acceleration) are functions of it. Therefore, our previous equation F = f * m is now:

F (h) = f (h) * m


In order to keep the hovercraft floating at a constant height IDEAL_HEIGHT from the ground, F must be equal or greater to the magnitude of the gravitational force. Therefore, this must be true:

F (IDEAL_HEIGHT) = 9.8 * m


and since F = f * m, this must be true:

f (IDEAL_HEIGHT) = 9.8


As the hovercraft nears the ground, f should increase. But to be realistic, we'll want to cap f at a maximum value of f_max. And as the hovercraft gets farther away from the ground, it should push less. With that in mind, f(h) must fulfill these two conditions:

f (0)                = f_max;
f (IDEAL_HEIGHT)     = 9.8;
f (h > IDEAL_HEIGHT) < 9.8;


The simplest possible solution here is to make f (h) a linear function of the form:

f (h) = m * h + b


To find the m and b factors, we do:

m = (9.8 - f_max) / (IDEAL_HEIGHT - 0) = (9.8 - f_max) / IDEAL_HEIGHT
b = f (0) = f_max


Therefore f(h) looks like this:

f (h) = h * (9.8 - f_max) / IDEAL_HEIGHT + f_max


In pseudocode:

function f ( h ) {
return max ( 0, h * (9.8 - f_max) / IDEAL_HEIGHT + f_max );
}


(Note that I'm using the max() function to prevent f from becoming negative.)

3. Putting it all together

So to put it simply, you should just do this on every frame:

// calculate the distance from the hovercraft to the ground
h = hovercraft.y - ground.y;

// calculate the acceleration
a.y = (9.8 - f(h)) * m; // see definition of f() above

// calculate the speed
v.y = v.y + a.y;

// and the position
y = y + v.y;

• Sorry about the verbosity, I just wanted to make sure I left nothing unexplained. I'm making it community wiki in case anyone wants to make it more concise. – User not found Jul 16 '12 at 8:33
• "sorry about the verbosity?" This is an amazing answer, keep up the good work. I am going to ask a mod to un-wiki this as it isn't the correct use for the cwiki (basically the mods will decide if you should wiki something). – Jonathan Dickinson Jul 16 '12 at 8:53
• Thank you! This is off-topic, but where can I find the official policy on when/whether an answer should be made community wiki? I searched in SO meta, but I could only find information relating to cw'ing questions. – User not found Jul 16 '12 at 9:18
• Nobody really knows what it's for anymore and it varies between SE sites (they did consider removing it at one stage). Basically, if you are never turning it on you are doing it right. Remember people can suggest improvements in the comments, which you can then add (or give them permission to add). – Jonathan Dickinson Jul 16 '12 at 9:41
• Wait you said you're using the Min() function to prevent f from becoming negative. That means f should be positive but then the f() function will only ever return 0, because that's the smallest number. – ProgrammerGuy123 Jul 18 '12 at 21:01