Académique Documents
Professionnel Documents
Culture Documents
representao de rotaes em 3D
por
Quatrnio e Rotaes
ndice
1
1.1.1
1.1.2
1.1.3
1.2
2
2.2
2.3
Quatrnios................................................................................................ 16
2.3.1
2.3.2
Interpolao de orientaes.............................................................. 23
Descrio da biblioteca............................................................................ 27
3.2
Listagem da biblioteca............................................................................. 28
3.2.1
Arquivo quat.h.................................................................................. 28
3.2.2
Arquivo quat.c.................................................................................. 29
3.2.3
Arquivo quatdemo.c......................................................................... 34
25/2/2002
Quatrnio e Rotaes
25/2/2002
Quatrnio e Rotaes
25/2/2002
Quatrnio e Rotaes
25/2/2002
Quatrnio e Rotaes
1.1.3.1
Gimbal lock
Gimbal lock o nome dado a um fenmeno no muito intuitivo (mas muito real)
com o qual se defrontam animadores que representam a orientao das entidades
em seu universo virtual utilizando ngulos de Euler.
Ao invs de descrever o problema conceitualmente, comecemos por mostrar que
ele existe atravs de um exemplo.
Imaginemos que estamos modelando um avio voando inicialmente para o norte,
com a asa direita voltada para o leste. Suponhamos que o piloto comece a baixar o
nariz do avio aos poucos. Em nossa representao, isso significar uma rotao
anti-horria em torno do eixo leste/oeste, ou seja, o ngulo correspondente
comecar a crescer. Se o piloto baixar o nariz do avio at que esteja voando
diretamente de encontro ao solo, ele ter executado uma rotao de 90 graus, e
portanto sua orientao neste momento ser representada por (0,90,0) e a barriga
do avio estar voltada para o sul.
Suponhamos agora que o piloto decida executar um parafuso, ou seja, girar o
avio em torno de seu eixo longitudinal. Como o avio est indo para baixo, isso
significa girar em torno do eixo vertical, ou seja, se ele girar no sentido antihorrio, a asa esquerda girar para o sul e a direita para o norte. Para que esta
rotao ocorra suavemente, o ngulo de rotao vertical ter que aumentar aos
poucos, at completar a rotao total pretendida. At aqui, no temos qualquer
problema : aps um giro de 90 graus, o avio estar na orientao (0,90,90), com a
barriga para o leste, aps 180 graus em (0,90,180), com a barriga para o norte e,
finalmente, aps uma volta completa, ter voltado a (0,90,0), com a barriga
novamente voltada para o sul.
Digamos, porm, que uma vez indo para baixo, com a barriga para o sul, o piloto
decida, ao invs de executar um parafuso, girar o avio para a sua esquerda,
Sergio C. de Biasi e Marcelo Gattass
25/2/2002
Quatrnio e Rotaes
apontando a asa esquerda para o cu, ou seja, uma rotao anti-horria em torno
do eixo sul/norte. Como executar esta rotao de forma suave, incremental?
Inicialmente, parece razovel supor que basta incrementar aos poucos o ngulo
correspondente rotao sul/norte. S que isso no funciona, pois a rotao em
torno do eixo sul/norte , em nossa conveno, executada antes da rotao em
torno do exito leste/oeste. Surpreendentemente, se incrementarmos a rotao
sul/norte tambm executaremos um parafuso. O leitor deve verificar que
realmente esse o caso.
O fato que, enquanto mantivermos a rotao de 90 graus ao redor do eixo
leste/oeste, no h qualquer mudana nos outros eixos que possa nos levar a
alteraes na orientao em torno do eixo sul/norte. Isso no significa que a nova
posio desejada no tenha representao atravs de nenhuma combinao de
ngulos de Euler; porm, enquanto o ngulo de rotao leste/oeste permanecer em
90 graus, efetivamente perdemos um grau de liberdade de movimento e h
orientaes que nunca poderemos atingir. Essa a situao chamada de gimbal
lock.
25/2/2002
Quatrnio e Rotaes
25/2/2002
Quatrnio e Rotaes
25/2/2002
Quatrnio e Rotaes
10
atravs de uma rotao simples, ao redor de um nico eixo. Logo, dadas duas
orientaes, basta executarmos uma interpolao linear simples no ngulo de
rotao em torno desse eixo, que sabemos que necessariamente existe, para
obtermos uma transio suave, nica (fora o sentido de rotao) e sem desvios.
Esse eixo, porm, no necessariamente um dos eixos coordenados, e a
parametrizao da orientao atravs de ngulos de Euler no leva, de forma
prtica ou natural, realizao de rotao ao redor de eixos arbitrrios. Seria
desejvel encontrar uma parametrizao na qual a transio entre duas orientaes
ocorresse naturalmente ao redor do eixo adequado e no seguindo um caminho
arbitrrio.
(1)
||
25/2/2002
Quatrnio e Rotaes
11
r
r
r . Sabemos que, por definio esta rotao ocorrer num plano paralelo a r e
r
r
perpendicular a n . Logo, se definirmos o vetor v como
r
r r
r r r r
r r
r r r
(3)
v = n r = n ( r r|| ) = n r n r|| = n r
r
n
r
v
r
r||
r
r ( r )
r
r
r
r
v
r
( r )
r
r
x
Figura 1 : Rotao em torno de um eixo
(5)
25/2/2002
Quatrnio e Rotaes
12
r
r
(, n ) em um ponto r
r
r
r r r
r r
( r ) = (cos ) r + (1 cos )(n r ) n + (sen)(n r )
(6)
25/2/2002
Quatrnio e Rotaes
13
25/2/2002
Quatrnio e Rotaes
14
(9)
25/2/2002
Quatrnio e Rotaes
15
(-1, 1)
(1, 1)
(0, 1)
=90
=45
c = ab = ba
(11)
25/2/2002
Quatrnio e Rotaes
16
2.3 Quatrnios
Os quatro parmetros que definem um quatrnio so nmeros reais usualmente
chamados de a, b, c, e d.
De forma similar aos nmeros complexos, os quatrnios possuem uma parte real
e uma imaginria. Ao contrrio dos complexos, porm, os quatrnios apresentam
trs componentes diferentes para sua parte imaginria, s quais chamaremos de i, j
e k.
25/2/2002
Quatrnio e Rotaes
17
(13)
(14)
(15)
(16)
(17)
25/2/2002
Quatrnio e Rotaes
18
(18)
(22)
25/2/2002
Quatrnio e Rotaes
19
(24)
(25)
25/2/2002
Quatrnio e Rotaes
20
r r v
a (b a ) = 0
r r
r r
a b = b a
r r r
r r r r r r
a ( b c ) = (a c ) b ( a b ) c
(25)
r2
Por outro lado, como q = (s, v) unitrio, temos que s 2 + v = 1 . Isso significa
v
que sempre existe um ngulo tal que s = cos e v = sen . Logo, sempre
podemos escrever q como
(26)
r
r
r
q = (s, v) = (cos , sen n ),
n =1
(28)
2sen 2 = (1 cos 2)
2 cos sen = sen 2
25/2/2002
Quatrnio e Rotaes
21
(30)
Isto significa que a rotao composta pode ser representada diretamente por q3 =
q2q1, j que
q 4 = q 3 q 3 pq 4 = q 3 pq 3 = R q 3 (p)
(31)
25/2/2002
Quatrnio e Rotaes
22
(32)
= ( 2 / 2, (0, ( 2 / 2),0))
(33)
(34)
(, (, , ))
25/2/2002
Quatrnio e Rotaes
23
r
q 3 (0, r1 ) q 3 =
(, (, , ))(0, (10,-5,0))(, (, , )) =
(, (, , ))(0 + (10,-5,0)(, , ), 0 + (10,-5,0) (10,-5,0)(, , ))
=
(, (, , ))((10 5+ 0), (10, 5, 0) (5 0, 0 10, 10 (
5))) =
(, (, , ))(5, (10, 5, 0) (5, 10, 15)) =
(, (, , ))(5, (15, 5, 15)) =
(5 (, , )(15, 5, 15), (15, 5, 15) + 5(, , ) +
(, , )(15, 5, 15) =
(5 (15 + 5 15), (15, 5, 15) + (5, 5, 5) +
(15 5, 15 (15), 5 15) =
(5 5, (20, 10, 10) + (20, 30, 10)) =
(0, (0, 40, 20)) =
(0, (0, 10, 5))
(35)
25/2/2002
Quatrnio e Rotaes
24
(37)
(39)
Qual a causa disso? Examinando a questo com mais cuidado, verificaremos que
o subconjunto dos quatrnios que representa rotaes, por ser todo formado por
quatrnios unitrios, define uma hiperesfera (generalizao da esfera para quatro
dimenses) de raio unitrio, assim como o subconjunto dos complexos que
representam rotaes define um circulo.
Se desejssemos interpolar entre as orientaes planas representadas por dois
complexos de forma a obter orientaes intermedirias, no poderamos
simplesmente executar uma interpolao linear componente a componente, pois
estaramos percorrendo uma reta secante ao crculo unitrio que contm todos os
complexos que representam rotaes. Para obter o resultado desejado, deveramos
executar a interpolao ao longo do crculo, dividindo o arco intermedirio em
segmentos de comprimento igual.
25/2/2002
Quatrnio e Rotaes
25
Eixo imaginrio
Todos os complexos
que representam rotaes
t
Eixo real
A
Uma interpolao linear
O correto realizar
simples percorreria
(40)
25/2/2002
Quatrnio e Rotaes
26
sen ( )
sen
+ q2
sen
sen
(41)
sen (1 u )
sen (u)
+ q2
sen
sen
(42)
A expresso acima, que damos sem demonstrao (embora esta no seja difcil
de realizar), produz um quatrnio que est a uma frao u do caminho entre q1 e
q 2.
25/2/2002
Quatrnio e Rotaes
27
Descrio da biblioteca
25/2/2002
Quatrnio e Rotaes
28
#ifndef _QUAT_H_INCLUDED_
#define _QUAT_H_INCLUDED_
typedef struct
{
double s;
double vx;
double vy;
double vz;
} quat_t;
typedef struct
{
double theta;
double nx;
double ny;
double nz;
} quat_rot_t;
typedef struct
{
double x;
double y;
double z;
} quat_pos_t;
25/2/2002
Quatrnio e Rotaes
quat_t
quat_t
quat_t
quat_t
quat_t
double
quat_t
quat_t
quat_t
double
quat_t
29
#endif /* _QUAT_H_INCLUDED_ */
q2.s;
+ q2.vx;
+ q2.vy;
+ q2.vz;
return qr;
}
25/2/2002
Quatrnio e Rotaes
30
quat_t qr;
qr.s = q1.s qr.vx = q1.vx
qr.vy = q1.vy
qr.vz = q1.vz
q2.s;
- q2.vx;
- q2.vy;
- q2.vz;
return qr;
}
return qr;
}
/* Conjugate of a quaternion */
quat_t quatConj(quat_t q)
{
quat_t qr;
qr.s = q.s;
qr.vx = -q.vx;
qr.vy = -q.vy;
qr.vz = -q.vz;
return qr;
}
/* Norm of a quaternion */
double quatNorm(quat_t q)
{
return sqrt(q.s*q.s + q.vx*q.vx + q.vy*q.vy + q.vz*q.vz);
}
25/2/2002
Quatrnio e Rotaes
31
/* Normalize a quaternion */
/* (or return the original quaternion if its norm is zero) */
quat_t quatNormalize(quat_t q)
{
double norm;
if( (norm = quatNorm(q)) == 0.0)
return q;
return quatScale(1.0 / norm, q);
}
cosomega = quatDot(q1,q2);
25/2/2002
Quatrnio e Rotaes
32
{
return quatLinearInterpol(q1, q2, u);
}
omega = acos(cosomega);
sinomega = sin(omega);
s1 = sin( (1.0 - u) * omega ) / sinomega;
s2 = sin( u * omega ) / sinomega;
return quatAdd(quatScale(s1, q1), quatScale(s2, q2));
}
25/2/2002
Quatrnio e Rotaes
33
qr.vx = 0.0;
qr.vy = 0.0;
qr.vz = 0.0;
return qr;
}
halftheta = (r.theta*halfpi)/180;
sinhalftheta = sin(halftheta);
qr.s = cos(halftheta);
qr.vx = sinhalftheta * (r.nx/axisnorm);
qr.vy = sinhalftheta * (r.ny/axisnorm);
qr.vz = sinhalftheta * (r.nz/axisnorm);
return qr;
}
25/2/2002
Quatrnio e Rotaes
34
#include <stdio.h>
#include "quat.h"
void PrintQuat(quat_t q)
{
printf("(%01.2f %01.2f %01.2f %01.2f)", q.s, q.vx, q.vy, q.vz);
}
void PrintPos(quat_pos_t r)
{
printf("(%01.2f %01.2f %01.2f)", r.x, r.y, r.z);
}
int main(void)
{
quat_rot_t rot1;
quat_rot_t rot2;
quat_t q1;
quat_t q2;
quat_t q3;
quat_pos_t r1;
quat_pos_t r2;
rot1.theta = 90;
rot1.nx = 0;
rot1.ny = 1;
rot1.nz = 0;
printf("rot1 = ");
PrintRot(rot1);
printf("\n");
rot2.theta = 90;
rot2.nx = 1;
rot2.ny = 0;
rot2.nz = 0;
printf("rot2 = ");
PrintRot(rot2);
printf("\n");
printf("\n");
25/2/2002
Quatrnio e Rotaes
35
q1 = quatFromRotation(rot1);
printf("q1 = ");
PrintQuat(q1);
printf("\n");
printf("rot(q1) = ");
PrintRot(quatToRotation(q1));
printf("\n");
q2 = quatFromRotation(rot2);
printf("q2 = ");
PrintQuat(q2);
printf("\n");
printf("rot(q2) = ");
PrintRot(quatToRotation(q2));
printf("\n");
q3 = quatMult(q2,q1);
printf("q3 = q2*q1 = ");
PrintQuat(q3);
printf("\n");
printf("rot(q3) = ");
PrintRot(quatToRotation(q3));
printf("\n");
printf("\n");
r1.x = 10;
r1.y = -5;
r1.z = 0;
printf("r1 = ");
PrintPos(r1);
printf("\n");
r2 = quatRotate(r1,rot1);
printf("rot(r1,q1) = ");
PrintPos(r2);
printf("\n");
r2 = quatRotate(r2,rot2);
printf("rot(rot(r1,q1),q2) = ");
PrintPos(r2);
printf("\n");
r2 = quatRotate(r1, quatToRotation(q3));
printf("rot(r1,q3) = ");
PrintPos(r2);
printf("\n");
return 1;
}
25/2/2002