Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert an angle in degrees, to a vector

I'm doing some game programming. FWIW I'm using XNA, but I'm doubtful that this is relevant.

I'd like to convert degrees to a directional vector (ie X and Y) with magnitude 1.

My origin (0,0) is in the upper left.

So I'd like 0 degrees to convert to [0, -1]

I thought the best way to do this was to take my definition of North/Up and rotate it using a matrix, but this does not seem to be working.

Here is the Code...

public class Conversion
{
    public static Vector2 GetDirectionVectorFromDegrees(float Degrees)
    {
        Vector2 North= new Vector2(0, -1);
        float Radians = MathHelper.ToRadians(Degrees);

        var RotationMatrix = Matrix.CreateRotationZ(Radians);
        return Vector2.Transform(North, RotationMatrix);
    }
}

... and here are my unit tests...

[TestFixture]
public class Turning_Tests
{
    [Test]
    public void Degrees0_Tests()
    {
        Vector2 result = Conversion.GetDirectionVectorFromDegrees(0);
        Assert.AreEqual(0, result.X);
        Assert.AreEqual(-1, result.Y);
    }
    [Test]
    public void Degrees90_Tests()
    {
        Vector2 result = Conversion.GetDirectionVectorFromDegrees(90);
        Assert.AreEqual(1, result.X);
        Assert.AreEqual(0, result.Y);
    }
    [Test]
    public void Degrees180_Tests()
    {
        Vector2 result = Conversion.GetDirectionVectorFromDegrees(180);
        Assert.AreEqual(0, result.X);
        Assert.AreEqual(1, result.Y);
    }
    [Test]
    public void Degrees270_Tests()
    {
        Vector2 result = Conversion.GetDirectionVectorFromDegrees(270);
        Assert.AreEqual(-1, result.X);
        Assert.AreEqual(0, result.Y);
    }

}

Am I approaching this all wrong? Should I be using a matrix? Have I screwed up and converted from degrees to radians in the wrong place?

I've seen suggestions that this can be done using code like:

new Vector2((float)Math.Cos(Angle), (float)Math.Sin(Angle));

...or sometimes...

new Vector2((float)Math.Sin(Angle), (float)Math.Cos(Angle));

However these don't seem to work either

Can someone put me on the right path... or better yet give me some code which causes the 4 provided unit tests to path?

Many thanks in advance.

like image 748
Rory Becker Avatar asked Sep 17 '13 13:09

Rory Becker


1 Answers

Just use:

new Vector2((float)Math.Cos(radians), (float)Math.Sin(radians))

Be sure to convert from degrees to radians with this approach too.

This uses the mathematician's convention of starting from [1, 0] and going in the direction towards [0, 1] (that is counter-clockwise with the orientation that mathematicians use for the two axes).

To use instead your convention (starting from [0, -1] and going in the direction of [1, 0]) you need:

new Vector2((float)Math.Sin(radians), -(float)Math.Cos(radians))

Note that your conversion from degrees to radians can never be exact (it involves something with π). You should allow for some tolerance in your tests. Also, if you use double instead of float for the radians, you will have some extra precision in the intermediate calculation.

like image 120
Jeppe Stig Nielsen Avatar answered Sep 27 '22 20:09

Jeppe Stig Nielsen