Reputation: 51
I'm programming a starship-game and have just finished the part which manages the rotating. I used a simple if/else-statement to check if the ship must rotate positive or negative in order to face the target as fast as possible. But I saw that the Rotation-Value can get negative, and then the ship does rotate to the wrong direction (It still faces the target-point in the end, but it takes longer). Please tell me what I did wrong :(
The function:
public bool RotateOrMove(Vector2 position)
{
if (IsRotationg == null) //todo
{
Vector2 direction = Position - position;
direction.Normalize();
FinalRotation = (float)Math.Atan2(-direction.X, direction.Y);
IsRotationg = true;
}
if (Equals(FinalRotation, Rotation))
IsRotationg = false;
if (IsRotationg == false)
{
Position = position;
return true;
}
else
{
if (FinalRotation >= Rotation)
{
Rotation += RotationVelocity;
if (FinalRotation - Rotation < RotationVelocity)
{
Rotation = FinalRotation;
IsRotationg = false;
}
}
if (FinalRotation < Rotation)
{
Rotation -= RotationVelocity;
if (FinalRotation - Rotation > -RotationVelocity)
{
Rotation = FinalRotation;
IsRotationg = false;
}
}
return false;
}
}
The Player-Class owns the Ship. When the player press the right mouse-button, this method will be called once per frame until the ship reaches the position where the cursor is pointing at.
if (!Ship.RotateOrMove(Position))
Position -= Velocity;
So if the ship had to rotate and couldn't move, it will remove the velocity it added just before to ensure that the ship won't move.
Hope you understand my problem^^
Upvotes: 0
Views: 176
Reputation: 5762
Math.Atan2 return values from -pi to pi.
to get a smooth rotation you can use this code got from here
private float CurveAngle(float from, float to, float step)
{
if (step == 0) return from;
if (from == to || step == 1) return to;
Vector2 fromVector = new Vector2((float)Math.Cos(from), (float)Math.Sin(from));
Vector2 toVector = new Vector2((float)Math.Cos(to), (float)Math.Sin(to));
Vector2 currentVector = Slerp(fromVector, toVector, step);
return (float)Math.Atan2(currentVector.Y, currentVector.X);
}
private Vector2 Slerp(Vector2 from, Vector2 to, float step)
{
if (step == 0) return from;
if (from == to || step == 1) return to;
double theta = Math.Acos(Vector2.Dot(from, to));
if (theta == 0) return to;
double sinTheta = Math.Sin(theta);
return (float)(Math.Sin((1 - step) * theta) / sinTheta) * from + (float)(Math.Sin(step * theta) / sinTheta) * to;
}
Upvotes: 1