Использование atan2 для поворота диапазона от - 1 до 1 в градусах
Я пытаюсь использовать atan2, чтобы превратить диапазон от 1 до 1 в радианы, а затем из радианов в градусы.
Однако atan2(0,1) равен 0, когда он должен быть равен 90.0, что я тут делаю?
float radians = atan2(0, 1);
float degrees = (radians * 180 / PI);
if(radians < 0)
{
degrees += 360;
}
Изменить: Хорошо, поэтому я подключил значения правильно в этот раз.
float xaxisval = controller->left_stick_x_axis();
float yaxisval = controller->left_stick_y_axis();
// plug values into atan2
float radians = atan2(yaxisval, xaxisval);
float degrees = (radians * 180 / PI);
if (radians < 0)
{
degrees += 360;
}
Для контекста xaxisval и yaxisval получают значение с аналогового джойстика с максимальным значением 1 справа и минимальным значением - 1 слева. Поэтому, когда я нажимаю аналоговый джойстик вправо, yaxisval равен 0, а xaxisval равен 1.
Это должно вернуть 90 градусов, как будто вы представляете аналоговый джойстик как полный круг на 360 градусов. Направление вверх - 360/0, вправо - 90, вниз - 180, слева - 270 и т. Д.
Я вставил эти значения в отладчик, и это то, что он вернул.
xaxisval: 1.00000
yaxisval: 0.00000
degrees: 0.00000
Однако я хочу, чтобы это направление поднялось до 90 градусов, оно, кажется, подпрыгнуло на 90 градусов, и я проверил позицию вниз, и она была равна 90. Есть предложения?
Вывод отладки: положение джойстика вверх
xaxisval: 0.00000
yaxisval: -1.00000
degrees: 270.00000
Джойстик Правое положение
xaxisval: 1.00000
yaxisval: 0.00000
degrees: 0.00000
Положение джойстика вниз
xaxisval: 0.00000
yaxisval: 1.00000
degrees: 90.00000
Джойстик в левом положении
xaxisval: -1.00000
yaxisval: 0.00000
degrees: 180.00000
Джойстик на северо-восток
xaxisval: 0.929412
yaxisval: 0.592157
degrees: 327.497528
1 ответ
Вы передаете аргументы в неправильном порядке. std::atan2
ожидает аргументы в порядке y,x
не x,y
,
Да, это невероятно глупо, но это связано с тем, как касательная функция определяется в первую очередь (которая определяется как отношение компонента y к компоненту x, а не наоборот), и, как и многие другие обозначения ошибки в математике, инерция возникли тысячи лет назад, и вы не можете противостоять ей, не будучи чудаком.
Поэтому напишите свой код так:
float radians = atan2(1, 0);
Или, если вы хотите, чтобы все было как можно более явным:
float x = 0, y = 1;
float radians = atan2(y, x); //Yes, that's the correct order, don't @ me
И вы получите ожидаемые результаты.
Ваша вторая проблема заключается в том, что ценности, которые atan2
соответствовать не совпадают с направлениями, которые вы хотите. То, что вы хотите, это круг, где верхняя часть равна 0°, правая сторона - 90°, нижняя - 180°, а левая сторона - 270°. Пробивая значения в atan2
вместо этого он будет производить значения, где правая сторона равна 0°, верхняя сторона равна 90°, левая равна 180°, а нижняя равна 270°.
Кроме того, по сравнению с моим собственным оборудованием, моя ось Y перевернута по сравнению с вашей. У меня есть y+↑, тогда как ваша установка выглядит как y-↑
Так что если вы хотите преобразовать нормальный atan2
вращение в нужное вам вращение, вам нужно преобразовать его так:
float radians = atan2(yaxisval, xaxisval);
float degrees = (radians * 180 / PI);
degrees = 90 - degrees;
if(degrees < 0)
degrees += 360;
Затем все, что вам нужно сделать, - это, возможно, преобразовать ось Y в зависимости от того, ожидаете ли вы, что нажатый джойстик вернет положительное или отрицательное значение. Это зависит от области вашей программы.