Physycs does not follow analytic results

I made function that with given gravity, shooter location, target location, abs(velocity) computes velocity (vector) for hitting target.

http://en.wikipedia.org/wiki/Trajectory_of_a_projectile part Angle theta required to hit coordinate (x,y)



And I created controll that computes location in given time. Using this, I managed to hit target perfectly.



Then I switched to physics.

I set gravity of physicsSpace same as I used for computing direction.

bulletAppState.getPhysicsSpace().setGravity(new Vector3f(0, -grav, 0));



And I set projectile rigidBodyControl’s linear velocity my analiticaly computed velocity.



Projectile almost hit target location, but it systematicaly falls a bit short.



How is it caused?

How can I compensate?



here is code I used for computing direction to hit target.

[java]

package util.balistics;



import com.jme3.math.Vector2f;

import com.jme3.math.Vector3f;

import static com.jme3.math.FastMath.;



public class VacuumBalistics1 {



private float g; // m
s^-2



public VacuumBalistics1() {

g = 10;

}



/**

  • @param g m*s^-2

    */

    public VacuumBalistics1(float g) {

    this.g = g;

    }



    public float distance(float v, float angle, float height) {

    float sin = sin(angle);

    float cos = cos(angle);

    return v * cos / g * (v * sin + sqrt(sqr(v * sin) + 2 * g * height));

    }



    public float distance(float v, float angle) {

    return v * v * cos(2 * angle) / g;

    }



    public float heightAtDist(float v, float angle, float dist, float height0) {

    return height0 + dist * tan(angle) - g * dist * dist / (2 * sqr(v * cos(angle)));

    }



    public float[] angleToHit(float x, float y, float v) {

    float v2 = v * v;

    float v4 = v2 * v2;

    float d = v4 - g * (g * x * x + 2 * y * v2);

    if (d == 0) {

    return new float[]{atan(v2 / (g * x))};

    }

    if (d < 0) {

    return new float[0];

    }

    float sqrt = sqrt(d);

    return new float[]{

    atan((v2 - sqrt) / (g * x)),

    atan((v2 + sqrt) / (g * x))};

    }



    public Vector3f[] dirToHit(Vector3f shooter, Vector3f target, float velocity) {



    float distance = sqrt(sqr(shooter.x - target.x) + sqr(shooter.z - target.z));

    float dh = target.y - shooter.y;

    float[] ath = angleToHit(distance, dh, velocity);

    if (ath.length == 0) {

    return new Vector3f[0];

    }

    float dx = target.x - shooter.x;

    float dz = target.z - shooter.z;

    Vector2f v2 = new Vector2f(dx, dz);

    v2.normalizeLocal();

    if (ath.length == 1) {

    return new Vector3f[]{dirtToHit(ath[0], v2, velocity)};

    }

    return new Vector3f[]{dirtToHit(ath[0], v2, velocity),

    dirtToHit(ath[1], v2, velocity)};

    }



    private Vector3f dirtToHit(float a, Vector2f normToTarget, float velocity) {

    float sa = sin(a);

    float ca = cos(a);

    Vector3f r = new Vector3f(

    ca * normToTarget.x * velocity,

    sa * velocity,

    ca * normToTarget.y * velocity);

    return r;

    }



    }

    [/java]

Ís there a linear dampening on your physicshape?

Dont know, I did not set anything like that. So only if its default.



edit. On controll i tried to setDamping(0,0); and it did not percievably change anything.

How about computing the trajectory with the actual physics of the world (namely bullet physics)? :wink:

I’m trying to aim, so I want analyticaly compute which direction to aim to hit stationary target, then i’ll add some leading for moving targets and inacuraccy. But what should have bean accurate is slightly short.

And drawing predicted trajectory using analytic formula must be much faster than trying to simulate ffew seconds ahaead.



I’m trying to decide, whether to go analyticaly all the way (at least for balistics) (but then things like wind would be hard to add and collision with other things than terrain would mean more coding), or use physics engine and have it much easier.

To get proper Newtonian physics working as expected, I do the following:

[java]

setDamping(0f, 0f);

setFriction(0f);

setSleepingThresholds(0f, 0f);

[/java]



That last one is important because the physics system sets some sleeping values so that if an object is moving slower than the set values it stops the object moving to save memory. This might be whats happening in your program as the default sleeping thresholds are NOT zero.

@kd12 said:
To get proper Newtonian physics working as expected, I do the following:
[java]
setDamping(0f, 0f);
setFriction(0f);
setSleepingThresholds(0f, 0f);
[/java]

That last one is important because the physics system sets some sleeping values so that if an object is moving slower than the set values it stops the object moving to save memory. This might be whats happening in your program as the default sleeping thresholds are NOT zero.


Well... and probably because in floating point physics, 0 motion is almost impossible to achieve naturally. There has to be some threshold or objects will never be at rest. I've never looked at bullet so I'm only guessing based on experience elsewhere.

Well actually thats more because its impulse based, so objects that lie on the groud are in fact very lightly bouncing off it every other frame to keep above it.

Didn’t help

diference between analytic approach:

http://youtu.be/pkIqzD25rAs



and physics
http://youtu.be/B_gPO6gLNO0