2

I have been trying to create a delayed rotation effect with the right analog sticks. The code below takes the angle based on the right analog stick's input and brings the object steadily closer. Due to atan2 being a range of -pi to pi the changing rotation always favors moving through 0 radians as opposed to pi. Is there a way to make the angle travel in the opposite direction?

    private void Angle()
    {
        //Angle to go to
        RotationReference = -(float)(Math.Atan2(YR, XR));

        //Adds on top of rotation to steadily bring it closer
        //to the direction the analog stick is facing
        Rotation += (RotationReference - Rotation) * Seconds *15;
        Console.WriteLine(RotationReference);
    }

Edit:

I tried using InBetween's suggested method which caused the transition between 2pi to 0 a problem. This led me to try something else. I have no idea why it doesn't work.

    private void Angle()
    {
        //Angle to go to
        RotationReference = -(float)(CorrectedAtan2(YR, XR));

        //Adds on top of rotation to steadily bring it closer
        //to the direction the analog stick is facing
        if (Math.Abs(RotationReference - Rotation) > Math.PI)
            Rotation += ((float)(RotationReference + Math.PI * 2) - Rotation) * Seconds * 15;
        else Rotation += (RotationReference - Rotation) * Seconds *15;
        Console.WriteLine(RotationReference);
    }

    public static double CorrectedAtan2(double y, double x)
    {
        var angle = Math.Atan2(y, x);
        return angle < 0 ? angle + 2 * Math.PI: angle;
    }

The idea behind this is that if you need to travel more than 180 degrees you will make the angle to travel to greater than 360 degrees. This should eliminate the need for reversing the direction.

2 Answers2

0

Just correct the angle to fit in the [0, 2·pi] range:

public static double CorrectedAtan2(double y, double x)
{
    var angle = Math.Atan2(y, x);
    return angle < 0 ? angle + 2 * Math.PI : angle;
}
InBetween
  • 32,319
  • 3
  • 50
  • 90
  • I tried something similar to this.(Although your code is better than mine.) However, this inverts the problem when going from 2PI back to zero again. The only solution I can think of would involve using radians less than zero and greater than 2PI, thus eliminating the awkward transition from 2PI to zero. Sadly, my limited programming experience prevents me from knowing how to do this. Thanks for your help by the way. – Jordan Unger Jun 10 '16 at 18:49
0

After some experimentation I managed to make it work. Thanks InBetween for the CorrectedAtan2 method. The for loop is used to go through all of the instances where you would need to add pi to avoid the jarring transition.

    private float Angle(float y, float x)
    {
        //Angle to go to
        RotationReference = -(float)(CorrectedAtan2(y, x));

        for (int i = 0; i < 60; i++)
        {
            if (Math.Abs(RotationReference - Rotation) > Math.PI)
                RotationReference = -(float)(CorrectedAtan2(y, x) +
                    (Math.PI * 2 * i));
        }
        //Adds on top of rotation to steadily bring it closer
        //to the direction the analog stick is facing
        return Rotation += (RotationReference - Rotation) * Seconds * 15;
    }

    public static double CorrectedAtan2(double y, double x)
    {
        var angle = Math.Atan2(y, x);
        return angle < 0 ? angle + 2 * Math.PI: angle;
    }