Hi, I am writing a game in which an object at a PointF travelling at a current velocity (Vector2) is trying to reach a destination PointF (which can change between movement steps)
At each step of movement I need to decide the acceleration vector that will get to the point the fastest.
So the result should be the ship adjusts its current velocity so that it always moves towards the target point at stead acceleration unless doing so would mean there isn't enough time to slow down before reaching it in which case it should begin decelerating.
This has been doing my head in a bit and the code I have at the moment seems to just make the ships orbit the point:
Vector2 v_target = new Vector2(target.X,target.Y);
Vector2 v_currentLocation = new Vector2(this.Location.X,this.Location.Y);
Vector2 v_currentVelocity = new Vector2(f_velocityX, f_velocityY);
//calculate vector in direction of target of length f_accelleration
//this line here is fundamentally flawed it can't just acclerate towards the target it has to take into account the current velocity direction somehow (which might not be in the direction of the current target)
Vector2 v_acceleration = new Vector2(target.X - Location.X, target.Y - Location.Y);
v_acceleration.Normalize();
v_acceleration.Multiply(f_acceleration);
//if we keep decelerating from current velocity
int i_shouldDecelerate = VectorShouldDecelerate(v_target, v_currentLocation, v_currentVelocity, v_acceleration);
if (i_shouldDecelerate ==-1)
{
f_velocityX += v_acceleration.X;
f_velocityY += v_acceleration.Y;
}
else
if (i_shouldDecelerate == 1)
{
f_velocityX -= v_acceleration.X;
f_velocityY -= v_acceleration.Y;
}
this.Location = new PointF(this.Location.X + f_velocityX, this.Location.Y + f_velocityY);
}
private int VectorShouldDecelerate(Vector2 in_target, Vector2 in_location, Vector2 in_currentVelocity, Vector2 in_acceleration)
{
if (in_location.Equals(in_target))
return 0;
//if we start decelerating now, will we overshoot
Vector2 velocityWhenDecelerating = in_currentVelocity;
Vector2 stoppingPoint = in_location;
float f_previousLength = velocityWhenDecelerating.Length();
while (velocityWhenDecelerating.Length() < in_acceleration.Length())
{
//reduce velocity
velocityWhenDecelerating.Subtract(in_acceleration);
//calculate stopping point
stoppingPoint.Add(velocityWhenDecelerating);
f_previousLength = velocityWhenDecelerating.Length();
}
//if we have arrived
stoppingPoint.Subtract(in_target);
if (stoppingPoint.Length() < in_acceleration.Length())
return 1;
else return -1;
}