Использование atan2 для поворота диапазона от - 1 до 1 в градусах - PullRequest
2 голосов
/ 12 апреля 2019

Я пытаюсь использовать 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 Ответ

6 голосов
/ 12 апреля 2019

Вы передаете аргументы в неправильном порядке.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 в зависимости от того, ожидаете ли вы 1034 * джойстика, который поднимается, чтобы вернуть положительное или отрицательное значение.Это зависит от области вашей программы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...