Вычислить повороты, чтобы посмотреть на трехмерную точку?

StackOverflow https://stackoverflow.com/questions/1251828

Вопрос

Мне нужно вычислить 2 угла (рыскания и тангажа) для 3D-объекта, обращенного к произвольной 3D-точке.Эти вращения известны как вращения "Эйлера" просто потому, что после первого вращения (скажем, 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

Это было полезно?

Решение

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

  • Система координат (x,y,z) такова, что положительный x — вправо, положительный y — вниз, а z — оставшееся направление.В частности, y=0 является плоскостью заземления.
  • Объект в точке (0,0,0), обращенный в данный момент к (0,0,1), поворачивается лицом к (x,y,z).
  • Для этого произойдет вращение вокруг оси X, а затем вокруг оси Y.Наконец, происходит вращение вокруг оси Z, чтобы все было вертикально.

(Терминология «рыскание», «тангаж» и «крен» может сбивать с толку, поэтому я бы хотел избежать ее использования, но, грубо говоря, это соответствие: x=тангаж, y=рыскание, z=крен.)

Вот моя попытка решить вашу проблему с учетом этой настройки:

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. О Х:0
  2. О Ю:atan2(z, x)
  3. О З:atan2(y, sqrt(x*x + z*z))

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

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

  1. О Х:-atan2(y, z)
  2. О Ю:atan2(x, sqrt(y*y + z*z))
  3. О З:0

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top