Рассчитать повороты, чтобы посмотреть на 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)

http://i53.tinypic.com/33lo6jp.jpg


Это моя система.

  • система координат x = вправо, y = вниз, z = дальше назад
  • объект по умолчанию находится в точке (0,0,1), которая обращена назад
  • Вращения имеют порядок X,Y,Z, где вращение на X является шагом, Y - отклонением, а Z - вращением.

моя система

4 ответа

Решение

Вот мои рабочие предположения:

  • Система координат (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) в любой задний квадрант. В передних квадрантах передняя часть объекта всегда будет обращена к точке. В задних квадрантах задняя часть объекта всегда обращена к точке.

Этот код исправляет эффект переворота, поэтому передняя часть объекта всегда обращена к точке. Я столкнулся с этим методом проб и ошибок, поэтому я действительно не знаю, что происходит!

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

Ответ богатого продавца показывает, как повернуть точку из одной трехмерной системы координат в другую систему, учитывая набор углов Эйлера, описывающих вращение между двумя системами координат.

Но звучит так, будто вы просите что-то другое:

У вас есть: трехмерные координаты одной точки

Вы хотите: набор углов Эйлера

Если это то, что вы просите, у вас недостаточно информации. Чтобы найти углы Эйлера, вам понадобятся координаты не менее двух точек в обеих системах координат, чтобы определить поворот из одной системы координат в другую.

Вы также должны знать, что углы Эйлера могут быть неоднозначными: ответ Рича предполагает, что повороты применяются к Z, затем X ', затем Z', но это не стандартизировано. Если вам нужно взаимодействовать с другим кодом, используя углы Эйлера, вам нужно убедиться, что вы используете то же соглашение.

Возможно, вы захотите использовать матрицы вращения или кватернионы вместо углов Эйлера.

Эта серия вращений даст вам то, что вы просите:

  1. О X: 0
  2. О Y: atan2(з, х)
  3. О Z: atan2(у, sqrt(x*x + z*z))

Я не могу сказать вам, что это за термины "крен", "тангаж" и "рыскание", если вы сначала не определите, как вы используете эти термины. Вы не используете их стандартным способом.

РЕДАКТИРОВАТЬ:
Хорошо, тогда попробуйте это:

  1. О X: -atan2(y, z)
  2. О Y: atan2(x, sqrt(y*y + z*z))
  3. О Z: 0

Говоря о вращении осей, я думаю, что шагом 3 должно было стать вращение осей X', Y''и Z' относительно оси Y ''.

Другие вопросы по тегам