LINUX.ORG.RU
ФорумTalks

Вопрос математикам про кватернионы


0

0

Начал писать простенькую программу, генерирующую 3D-модели для формата .an8
программы Anim8or, http://www.anim8or.com/

Однако, столкнулся с тем, что поворот задается атрибутами тега orientation,
но функция зависимости этих атрибутов от углов поворота вокруг осей неизвестна.

Я сделал несколько пробных поворотов и переписал соответствующие значения orientation:

orientation { (0.70711 0 0 0.70711) } -- это поворот вокруг оси X на 90 градусов;
orientation { (0 0.70711 0 0.70711) } -- это поворот вокруг оси Y на 90 градусов;
orientation { (0 0.25882 0 0.96593) } -- вокруг Y на 30 градусов;
orientation { (0 0.38268 0 0.92388) } -- вокруг Y на 45 градусов;
orientation { (0 0 0.70711 0.70711) } -- это поворот вокруг оси Z на 90 градусов;
orientation { (0.04047 0.22418 0.26830 0.93601) } -- это поворот вокруг оси X на 12.34, Y на 23.45 и Z на 34.56 градусов
orientation { (0.35355 0.35355 -0.14645 0.85355) } -- это поворот вокруг оси X на 45 градусов и вокруг Y на 45 градусов

По-видимому, искомые функции есть сочетание тригонометрических.

1.57079632679 = pi/2
1.0471975512 = pi/3
0.785398163397 = pi/4
0.523598775598 = pi/6
0.392699081699 = pi/8

0.707106781187 = sin(pi/4)

Поискал описание формата .an8 в интернете и нашел упоминание кватернионов,
http://www.anim8or.com/resources/an8_format.txt

<orientation> ::= orientation { <quaternion> }

    This chunk holds the orientation of the component as a quaternion.
    If not present the it is unrotated, with the X coordinate pointing
    to the right, the Y pointing up, and the Z pointing out of the screen
    in a front view of an object.

    For a description of the wonders of quaternions, see a good graphics
    text, or the original paper by Ken Shoemaker.

Вычислил кватернион поворота по статье:
А.О.Ватульян. Кватернионы, Ростовский государственный университет, Ростов-на-Дону, 1999
Статьи Соросовского Образовательного журнала в текстовом формате
http://www.pereplet.ru/obrazovanie/stsoros/783.html

Q1*Q2*Q3 = (
  (cos(alpha/2) + i*sin(alpha/2))*
  (cos(beta/2)  + j*sin(beta/2))*
  (cos(gamma/2) + k*sin(gamma/2))
)

i*i = j*j = k*k = -1
i*j = k, j*k = i, k*i = j
j*i = -k, k*j = -i, i*k = -j

Q1*Q2*Q3 =
  (cos(alpha/2)*cos(beta/2)+
   cos(alpha/2)*j*sin(beta/2)+
   i*sin(alpha/2)*cos(beta/2)+
   i*sin(alpha/2)*j*sin(beta/2))*
  (cos(gamma/2) + k*sin(gamma/2)) =
  = (
   cos(alpha/2)*cos(beta/2)*cos(gamma/2)+      // 1
   cos(alpha/2)*j*sin(beta/2)*cos(gamma/2)+    // j
   i*sin(alpha/2)*cos(beta/2)*cos(gamma/2)+    // i
   i*sin(alpha/2)*j*sin(beta/2)*cos(gamma/2)+  // k
   cos(alpha/2)*cos(beta/2)*k*sin(gamma/2)+    // k
   cos(alpha/2)*j*sin(beta/2)*k*sin(gamma/2)+  // i
   i*sin(alpha/2)*cos(beta/2)*k*sin(gamma/2)+  // -j
   i*sin(alpha/2)*j*sin(beta/2)*k*sin(gamma/2) // 1
  ) =
  = (
   i*(sin(alpha/2)*cos(beta/2)*cos(gamma/2)+cos(alpha/2)*sin(beta/2)*sin(gamma/2))+

   j*(cos(alpha/2)*sin(beta/2)*cos(gamma/2)-sin(alpha/2)*cos(beta/2)*sin(gamma/2))+

   k*(sin(alpha/2)*sin(beta/2)*cos(gamma/2)+cos(alpha/2)*cos(beta/2)*sin(gamma/2))+

   (cos(alpha/2)*cos(beta/2)*cos(gamma/2)+sin(alpha/2)*sin(beta/2)*sin(gamma/2))
  )

Однако, полученный вектор не такой, какой нужен - он расходится с подобранным вручную (отличие в знаках):

   sin(AX/2)*cos(AY/2)*cos(AZ/2)-cos(AX/2)*sin(AY/2)*sin(AZ/2),
   cos(AX/2)*sin(AY/2)*cos(AZ/2)+sin(AX/2)*cos(AY/2)*sin(AZ/2),
   -sin(AX/2)*sin(AY/2)*cos(AZ/2)+cos(AX/2)*cos(AY/2)*sin(AZ/2),
   cos(AX/2)*cos(AY/2)*cos(AZ/2)+sin(AX/2)*sin(AY/2)*sin(AZ/2)

(последний в точности соответствуют значениям атрибутам orientation из примеров)
★★★★★

Где я ошибся при расчете искомого вектора ?

pacify ★★★★★
() автор топика

> расходится с подобранным вручную (отличие в знаках)

похоже, что в выборе координатной системы (лево/право)

> with the X coordinate pointing to the right, the Y pointing up, and the Z pointing out of the screen

это правая система, А.О.Ватульян же видемо подразумевает левую

beastie ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.