2013-09-17 5 views
6

Я занимаюсь программированием. FWIW Я использую XNA, но я сомневаюсь, что это актуально.Преобразование угла в градусах, в вектор

Я хотел бы преобразовать градусы направленного вектора (т.е. X и Y) с величиной 1.

Моим происхождения (0,0) находится в верхнем левом углу.

Так что я хотел бы 0 градусов, чтобы преобразовать в [0, -1]

Я думал, что лучший способ сделать это, чтобы принять мое определение Севера/Up и вращать его с помощью матрицы, но это похоже, не работает.

Вот код ...

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

... и вот мои модульные тесты ...

[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); 
    } 

} 

ли я приближаюсь все это не так? Должен ли я использовать матрицу? Я прищурился и превратился из градусов в радианы в неправильном месте?

Я видел предположения, что это может быть сделано с помощью кода, как:

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

... или иногда ...

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

Однако это, похоже, не работает ни

Может ли кто-то поставить меня на правильный путь ... или еще лучше дать мне код, который приводит к 4 приведенным модульным тестам?

Большое спасибо заранее.

ответ

13

Просто используйте:

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

Обязательно для преобразования из градусов в радианы с этим подходом тоже.

Используется соглашение математика от [1, 0] и движение в направлении [0, 1] (то есть против часовой стрелки с ориентацией, которую математики используют для двух осей).

Чтобы использовать вместо вашей конвенции (начиная с [0, -1] и идет в направлении [1, 0]), вам необходимо:

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

Обратите внимание, что ваш переход из градусов в радианы никогда не может быть точным (она включает в себя что-то с π) , Вы должны допускать некоторую допуск в своих тестах. Кроме того, если вы используете double вместо float для radians, у вас будет дополнительная точность в промежуточном расчете.

+0

@RoryBecker См. Мое редактирование. При работе с 'Sin' и' Cos' вы не можете ожидать точных значений. Однако значения должны быть очень близки к ожидаемому значению. –

+0

Когда я увидел, что мои юнит-тесты потерпели неудачу, я предположил, что это плохо. Однако, как вы отмечаете, это связано с ошибками округления, которые, как оказалось, вполне соответствуют допустимой толерантности. Большое спасибо :) –

+0

Существует действительно восемь различных возможных «условностей» для _ (a) _, который «угол» (пересечение между осью и единичным кругом) начинается с (4 возможности) и _ (b) _, которые (по часовой стрелке или против часовой стрелки) для использования (2 возможности). Это соответствует восьми возможностям выбора _ (i) _ порядка 'Cos' и' Sin' (это 'Cos' first (x), затем' Sin' (y) или наоборот), _ (ii) _ знак (минус или нет) по первой координате и знак (iii) _ на последней координате. –

 Смежные вопросы

  • Нет связанных вопросов^_^