Рассчитать повороты, чтобы посмотреть на 3D-точку?
Мне нужно рассчитать 2 угла (рыскание и тангаж) для трехмерного объекта, чтобы столкнуться с произвольной трехмерной точкой. Эти вращения известны как вращения Эйлера просто потому, что после первого вращения (скажем, Z, на основе рисунка ниже) ось Y также вращается вместе с объектом.
Это код, который я использую, но он не работает полностью. Когда на плоскости земли (Y = 0) объект правильно вращается, чтобы смотреть на точку, но как только я перемещаю точку вверх по Y, вращения не выглядят правильными.
// x, y, z represent a fractional value between -[1] and [1]
// a "unit vector" of the point I need to rotate towards
yaw = Math.atan2( y, x )
pitch = Math.atan2( z, Math.sqrt( x * x + y * y ) )
Знаете ли вы, как рассчитать 2 угла Эйлера для данной точки?
На рисунке ниже показано, как я вращаюсь. Это углы, которые мне нужно рассчитать. (Единственная разница в том, что я вращаю объект в порядке X, Y, Z, а не Z, Y, X)
![pic]()
![enter image description here]()
Это моя система.
- система координат x = вправо, y = вниз, z = дальше назад
- объект по умолчанию находится в точке (0,0,1), которая обращена назад
- Вращения имеют порядок X, Y, Z, где вращение на X является шагом, Y - отклонением, а Z - вращением.
![my system]()
Ответы
Ответ 1
Вот мои рабочие предположения:
- Система координат (x, y, z) такова, что положительное x находится вправо, положительное y - вниз, а z - оставшееся направление. В частности, y = 0 - плоскость заземления.
- Объект в точке (0,0,0), обращенный в направлении (0,0,1), поворачивается в направлении (x, y, z).
- Чтобы достичь этого, произойдет поворот вокруг оси x, за которой следует одна вокруг оси y. Наконец, есть поворот вокруг оси z, чтобы иметь вещи в вертикальном положении.
(Терминология рыскания, высоты тона и рулона может быть запутанной, поэтому я бы хотел избежать ее использования, но грубо говоря, соответствие x = pitch, y = yaw, z = roll.)
Вот моя попытка решить вашу проблему с учетом этой настройки:
rotx = Math.atan2( y, z )
roty = Math.atan2( x * Math.cos(rotx), z )
rotz = Math.atan2( Math.cos(rotx), Math.sin(rotx) * Math.sin(roty) )
Надеюсь, это правильно до знака. Я думаю, что самый простой способ исправить признаки - проб и ошибок. Действительно, вы, кажется, получили знаки на rotx
и roty
правильные - включая тонкую проблему относительно z - так что вам нужно только зафиксировать знак на rotz
.
Я ожидаю, что это будет нетривиальным (возможно, в зависимости от того, в каком октане вы находитесь), но, пожалуйста, попробуйте несколько вариантов, прежде чем говорить об этом неправильно. Удачи!
Вот код, который, наконец, работал у меня.
Я заметил эффект "флип", который произошел, когда объект переместился из любого переднего квадранта (положительный Z) в любой задний квадрант. В передних квадрантах фронт объекта всегда будет стоять перед точкой. В задних квадрантах назад объекта всегда стоит точка.
Этот код корректирует эффект flip, поэтому перед объектом всегда стоит точка. Я столкнулся с этим с помощью проб и ошибок, поэтому я не знаю, что происходит!
rotx = Math.atan2( y, z );
if (z >= 0) {
roty = -Math.atan2( x * Math.cos(rotx), z );
}else{
roty = Math.atan2( x * Math.cos(rotx), -z );
}
Ответ 2
Богатый ответ продавца показывает вам, как поворачивать точку из одной трехмерной системы координат в другую систему, учитывая набор углов Эйлера, описывающих поворот между двумя системами координат.
Но похоже, что вы просите что-то другое:
У вас есть: 3-D координаты одной точки
Вы хотите: набор углов Эйлера
Если это то, о чем вы просите, у вас недостаточно информации. Чтобы найти углы Эйлера,
вам понадобятся координаты, по крайней мере, двух точек в обеих системах координат, чтобы определить поворот из одной системы координат в другую.
Вы также должны знать, что углы Эйлера могут быть двусмысленными: богатый ответ предполагает
повороты применяются к Z, то X ', то Z', но это не стандартизировано. Если вам нужно взаимодействовать с другим кодом с использованием углов Эйлера, вам нужно убедиться, что вы используете одно и то же соглашение.
Возможно, вы захотите рассмотреть использование матриц вращения или кватернионов вместо углов Эйлера.
Ответ 3
Эта серия поворотов даст вам то, о чем вы просите:
- О X: 0
- О Y: atan2 (z, x)
- О Z: atan2 (y, sqrt (x * x + z * z))
Я не могу сказать вам, что это такое с точки зрения "roll", "pitch" и "yaw", если вы не определяете, как вы используете эти условия. Вы не используете их стандартным способом.
РЕДАКТИРОВАТЬ:
Хорошо, тогда попробуйте следующее:
- О X: -atan2 (y, z)
- О Y: atan2 (x, sqrt (y * y + z * z))
- О Z: 0
Ответ 4
Говоря о вращении осей, я думаю, что шаг 3 должен был быть поворот X'-, Y '' - и Z'-осей вокруг оси Y '.