Search code examples
c#xnarotation

XNA Negative Rotation?


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^^


Solution

  • 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;
    }