Начал писать простенькую программу, генерирующую 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 из примеров)