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; // ms^-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]