• Forum
  • Lounge
  • Lander physics, how do you like the hand

 
Lander physics, how do you like the handling on your spaceship?

So I thought that a spot of constant gravity and a gradually accumulating thrust would simulate a real world feel, but no, its pretty sensitive to get right any better ideas than;

1
2
3
4
5
6
7
8
9
10
11
12
13


ufo_y -= gravity;

if(keydown)
{
thrust++;
}
if(keyreleased)
{
thrust--;
}
ufo_y += thrust;


Is there a good inertia algorythm?

EDIT: forgot "-=" and "+="
Last edited on
Thrust is constant acceleration; it shouldn't be slowly increasing or decreasing. Your velocity is what should be modified by it, but I can't really tell based on that code what you are doing with it.
need more input
You can't subtract acceleration due to gravity from the vertical component of a velocity because the units and dimensions are different. You need to multiply acceleration due to gravity by the duration of time over which the acceleration occurs, then subtract that from the vertical component of velocity.

A better way to do it is to have the velocity and acceleration as vector quantities. The gravity would then be the vertical component of the acceleration:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
static const double ACCEL_GRAV = 9.806;

struct vector { double x, y; };

// ...

class UFO {
public:
    vector acceleration;
    vector velocity;
    vector position;

    void update(double time)
    {
        velocity.x = acceleration.x * time;
        velocity.y = acceleration.y * time;
        position.x = velocity.x * time;
        position.y = velocity.y * time;
    }
};

// ...

UFO ufo;
ufo.acceleration.y = ACCEL_GRAV;

If you want to smooth the motion out so that it's not so erratic, you should use a moving average:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// ...

class UFO {
public:
    vector acceleration;
    vector position;

    void update(double time)
    {
        vector velocity;
        // ...
        add_velocity(velocity);
    }

    vector get_velocity()
    {
        return mean_velocity();
    }
private:
    std::array<vector, 255> velocities;
    size_t index;

    void add_velocity(const vector& velocity)
    {
        velocities[index++] = velocity;
        if (index > 255)
            index = 0;
    }

    vector sum_velocity()
    {
        vector sum;
        for (const vector& velocity : velocities) {
            sum.x += velocity.x;
            sum.y += velocity.y;
        }
        return sum;
    }

    vector mean_velocity()
    {
        vector velocity = sum_velocity();
        velocity.x /= 255;
        velocity.y /= 255;
    }
};


@firedraco
He's adding to the thrust when a key is pressed and decreasing it when the key is released, which is probably simulating the throttle. It's not technically right because thrust is the force that reacts in opposition to the expulsion of gas out of a rocket's engine, but that's what I think he's doing.
Im finding that hard to follow but thats good because its all totaly relevent to the maths i have been teaching myself
Last edited on
why is gravity 9.806??
devonrevenge wrote:
why is gravity 9.806??
http://en.wikipedia.org/wiki/Gravity_of_Earth
Wikipedia wrote:
The nominal "average" value at the Earth's surface, known as standard gravity is, by definition, 9.80665 m/s2
Last edited on
hey what about inertia and momentum? I havnt looked that up actually, it will proly be in dream in code *sigh* get tor browser going again
That's (approximately) the vertical acceleration due to gravity g of an object in free fall in earth's gravitational field (technically since it's towards the earth it should be -9.806 m s-2). To calculate g for an object of mass M you use the equation g = GM/r2 where G is the universal gravitational constant and r is the distance between the centre of the object and the point you're measuring from. So, at sea level, g on earth is about 6.67x10-11 N m2 kg-2 x 5.972x1024 kg / (6.371x106 m)2 = 9.814 m s-2. The value you get depends on the exact figures you use, so most people use 9.81 because it usually hovers around that value.
Thrust is constant acceleration

I don't think is strictly true :)
1
2
3
4
5
6
7
    void update(double time)
    {
        velocity.x = acceleration.x * time;
        velocity.y = acceleration.y * time;
        position.x = velocity.x * time;
        position.y = velocity.y * time;
    }


I'm don't think the above will work.

It is true that position.y = velocity.y * time, if velocity is constant (no acceleration)
And this is true, velocity.x = acceleration.x * time, if acceleration is const.

What I would use is:
y = y_intial + velocity_y_inital * delta_t + .5 * acceleration_y * delta_t^2

But this is only valid for const acceleration as well. So you need to restart the clock every time acceleration changes, keep track of your velocity and position, and use them as initial conditions in the subsequent chunk of time.

1
2
3
delta_t = 0
y_initial = y
velocity_y_initial = veloctity_y_initial +  delta_t * acceleration_y


now update acceleration

thrust is force. force = mass * acceleration, acceleration = force / mass

Fnet = Fgrav + Fthrust = mass*acceleration_net
Force of gravity = -9.8 * mass
Force of thrust = accleration_thrust * mass

cancel mass
-9.8 + acceleration_thrust = acceleration
So you can just add the accelerations due to gravity and thrust.

Now also consider the way in which thrust is controlled by the user. You might want an upper limit for the throttle value. You might want a non-linear relationship between throttle value and thrust. I would find a function which models the relationship I'm looking for. Probably something logarithmic.

You don't need momentum unless your dealing with collisions where you can use conservation of momentum to determine the results of the collisions.

There might be a better way to do it, I don't know, this is how I have gone about it in the past.
Last edited on
@htirwin
What do you mean, "restart the clock"? The time parameter is the amount of time in seconds that has elapsed since the last call to update() (usually the time taken to render the last frame: this way, the speed of objects doesn't differ depending on how fast the computer is).
You would instead update your position based on the amount of time in seconds since you last updated acceleration.


I guess your method should be like this in the case that time is the amount of time elapsed since the last update.

1
2
3
4
5
6
7
    void update(double time)
    {
        velocity.x += acceleration.x * time;
        velocity.y += acceleration.y * time;
        position.x += velocity.x * time;
        position.y += velocity.y * time;
    }

Last edited on
Topic archived. No new replies allowed.