How to make the bullet stop accurately when destination is reached?

In the below code, is the method I use to move a bullet to its destination and stop when bullet is near to destination. But the problem is the bullet is stopping not accurately, sometimes there's a small offset or span or sometimes is accurate depends on the angle.

public Vector2 getVelocity(Vector2 currentPosition, Vector2 targetPosition) {
Vector2 targetDirection = targetPosition.cpy().sub(currentPosition);
return targetDirection
.nor();
}

final float SPEED = 6;
float pos = bulletPosition.len();
float des = bullet.destination.len();
float tol = Constants.TIME_STEP * SPEED;

if(MathUtils.isEqual(pos,des, tol)) {
body.setLinearVelocity(0,0);
} else {
body.setLinearVelocity(getVelocity(bulletPosition, destination).scl(SPEED));
}


[SOLVED]

if(MathUtils.isEqual(pos, des, tol)) {
// quick & dirty way
body.setTransform(destination, angle);
// better way
...
}

• What does MathUtils.isEqual do exactly, is it a direct comparision or an approximation? Jul 30 '16 at 14:30
• here is the link for MathUtils java doc link Jul 30 '16 at 15:16

Quick & Dirty Way:
You can simply teleport the bullet to location you want after it stops.

Long & Better Way:
For the last moments of movement, you can disable the physics and control the movement yourself by lerp'ing (or any other way, lerp is my favorite) towards the target. This way, you can stop the bullet whenever you want.

Edit
I would solve the situation like this in Unity, and actually this might be a better way than the two above:

float minDisableDistance, minStopDistance, bulletSpeed;
Transform target;

// I'm skipping the parts that you create the bullet, and simply do the job on these:
GameObject bullet; //Assuming this is the bullet.
Rigidbody bulletRigidbody; //Assuming this is the rigidbody of bullet.

void Update()
{
Vector3 relPos = target.position - bullet.postion;
float distance = relPos.magnitude;

if(distance > minDisableDistance)
{
//use physics.
}
else
{
bulletRigidbody.velocity = 0;

if(distance > minStopDistance)
{
bullet.position += bulletSpeed * relPos.normalized * time.deltaTime;
}
else
{
bullet.position = target.position;
}
}
}

• ***** it works perfectly! I just tried the "quick & dirty way" . I want to try the better way Jul 30 '16 at 15:23
• can you give me a little pseudo-code on how do I properly do the properway? Jul 30 '16 at 15:25
• @ronscript I can't, I have never used libgdx or box2d. The wikipedia article about lerp is great, take a look: en.wikipedia.org/wiki/Linear_interpolation Jul 30 '16 at 15:28
• On the lerp method third parameter t. Because my bullet is speed is 6. the t is also 6? Jul 30 '16 at 15:33
• @ronscript No, the third parameter indicates the "ratio" of movement from beginning to end (and third parameter should be in between 0-1 in general). For example if it is 0.5, it means the result is exactly the middle of start and end points. Jul 30 '16 at 15:39

I found out the best way! I just use the Vector2 dst method to get the distance between the destination. And hooray!! it was accurate!

float distance = bulletPosition.cpy().dst(destination);

float tol = (Constants.TIME_STEP * SPEED) / 2;

if(distance <= tol) {

body.setLinearVelocity(0, 0);

}