Vous êtes sur la page 1sur 35

Utilizao de quatrnios para

representao de rotaes em 3D
por

Sergio Coutinho de Biasi e Marcelo Gattass

Quatrnio e Rotaes

ndice
1

Representao de rotaes em 3D sem o uso de quatrnios............................. 3


1.1

1.1.1

Rotaes tridimensionais no comutam............................................. 4

1.1.2

Representao de orientaes fixas.................................................... 5

1.1.3

Representao de orientaes mutveis............................................. 6

1.2
2

ngulos de Euler ....................................................................................... 3

Rotao ao redor de um eixo ................................................................... 10

Representao de rotaes em 3D com o uso de quatrnios .......................... 13


2.1

Rotaces em 2D e nmeros complexos................................................... 13

2.2

Generalizando os nmeros complexos .................................................... 16

2.3

Quatrnios................................................................................................ 16

2.3.1

Representao e composio de rotaes ........................................ 19

2.3.2

Interpolao de orientaes.............................................................. 23

Uma implementao em C das operaes com quatrnios............................. 27


3.1

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

Sergio C. de Biasi e Marcelo Gattass

25/2/2002

Quatrnio e Rotaes

1 Representao de rotaes em 3D sem o uso de quatrnios


Quando desejamos modelar uma entidade (seja ela um corpo rgido, uma
partcula, uma cmera, um raio de luz, etc) precisamos, em muitas
circunstncias, especificar sua posio e orientao em nosso universo virtual.
A especificao de posies, usualmente dadas como translaes com relao a
uma origem conhecida, no apresenta grandes problemas. Grande parte das vezes
podemos at mesmo simplesmente especificar a posio em coordenadas
cartesianas e a questo est resolvida.
J quanto s orientaes, usualmente dadas como rotaes com relao a uma
origem inicial, no assim to simples. primeira vista, especialmente aos
iniciantes na rea, pode parece que no haja qualquer dificuldade. Afinal, assim
como no caso da posio, temos trs graus de liberdade, e portanto bastariam trs
parmetros para definir a orientao de uma entidade. A questo : qual sistema
de parametrizaco utilizar? Ser que existe algum sistema adequado que use
somente trs parmetros?
Neste trabalho, procuraremos apresentar as dificuldades envolvidas em
representar rotaes e mostraremos que uma das solues mais prticas e
intuitivas para este problema usa quatro parmetros e se baseia na definio do
grupo matemtico dos assim chamados quatrnios.

1.1 ngulos de Euler


A soluo mais imediata para o problema de especificar a orientao de uma
entidade no espao tridimensional fornecer suas rotaes com relao aos eixos
x, y, e z. Inicialmente, parece que isso resolve toda a questo. Porm, h alguns
problemas com essa soluo.
Para sermos mais precisos, a parametrizao proposta aqui a seguinte : para
especificar a orientao de uma entidade, forneceremos trs parmetros, que
representam os ngulos de rotao anti-horria em relao a cada um dos trs
eixos coordenados. Esses ngulos so chamados de ngulos de Euler. Ser que
com isso o problema no est resolvido?
A resposta, um pouco surpreendente quando comeamos a estudar o assunto,
que para muitas aplicaes, esta representao extremamente problemtica.

Sergio C. de Biasi e Marcelo Gattass

25/2/2002

Quatrnio e Rotaes

1.1.1 Rotaes tridimensionais no comutam


A primeira dificuldade est no fato de que operaes de rotao, ao contrio das
de translao, no so comutativas. Ou seja, podemos representar a posio de um
objeto como a soma dos deslocamentos paralelos a cada um dos eixos
coordenados e ao final, no importando a ordem em que aplicarmos os trs
deslocamentos, terminaremos na mesma posio. J com rotaes, isso no
verdade. Se temos uma rotao em torno do eixo x e outra em torno do eixo y, e as
aplicamos nossa entidade, obteremos orientaes finais diferentes dependendo
da ordem em que as rotaes forem aplicadas.
Caso o leitor nunca tenha se dado conta do fato que acabamos de enunciar,
importante que pare alguns momentos para compreender o significado do que foi
afirmado. Descreveremos abaixo uma situao em que isso acontece.
Imagine o leitor que esteja no comando de um avio que voa em linha reta para a
frente, indo para o norte, com a asa direita apontando para o leste e a esquerda
para o oeste. Imagine ento que o leitor gire o avio de 90 graus para a esquerda
(isto , uma rotao anti-horria em torno do eixo vertical), voando agora portanto
para o oeste. Em seguida, imaginemos que o leitor continue a voar para o oeste
mas incline o avio de forma a baixar sua asa direita e erguer a esquerda de 90
graus (isto , uma rotao anti-horria em torno do eixo leste/oeste). Ao final,
teremos o avio voando para o oeste, com a asa direita apontando para o solo e a
esquerda para o cu.
Verifiquemos agora o que ocorre se executarmos exatamente as mesmas duas
rotaes, porm na ordem inversa. Comeando com o avio voando para o norte,
se executarmos a rotao anti-horria de 90 graus em torno do eixo leste/oeste, o
avio passar a voar na vertical, com a cabine voltada para o solo, com a cauda
apontando para o cu e a barriga para o sul. A asa direita continuar apontando
para o leste e a esquerda para o oeste. Se agora executarmos a rotao anti-horria
de 90 graus em torno do eixo vertical, teremos o avio ainda voando para baixo,
mas com a asa direita apontando para o norte, a esquerda para o sul e a barriga
voltada para o leste.
Portanto, como se pode ver no exemplo acima, a ordem em que executamos as
rotaes pode alterar completamente a orientao final obtida. Isso significa que
para descrever a orientao de uma entidade, no suficiente fornecer os ngulos
de rotao em torno dos eixos coordenados; preciso tambm especificar a ordem
em que essas rotaes devem ser executadas.
Mais uma vez, talvez parea ao leitor que no h qualquer problema. Num
primeiro momento, parece razovel pensar que bastaria especificarmos uma ordem
padronizada para as rotaes. Assim, para especificarmos a orientao de uma
entidade, forneceramos os ngulos de rotao em torno dos eixos coordenados e
Sergio C. de Biasi e Marcelo Gattass

25/2/2002

Quatrnio e Rotaes

estaria subentendido que primeiro devemos executar a rotao em torno de x, em


seguida em torno de y e finalmente em torno de z, necessariamente nesta ordem.

1.1.2 Representao de orientaes fixas


Examinemos, portanto, o que acontece se representamos a orientao de uma
entidade atravs de trs ngulos representando rotaes anti-horrias numa ordem
predeterminada em torno dos eixos coordenados.
Voltando ao nosso avio, imaginemos que, aps ler a seo anterior, tenhamos
resolvido fixar a ordem das rotaes como sendo sucessivamente em torno dos
eixos sul/norte, leste/oeste e baixo/cima. (A discusso seria exatamente a mesma
se tivssemos chamado nossos eixos de x, y e z. Se o leitor preferir, pode pensar,
nos exemplos que se seguem, no eixo sul/norte como sendo o eixo x, no leste/oeste
como y e no baixo/cima como z).
Neste sistema de representao, para especificar a orientao inicial voando
para o norte com a asa direita apontando para o leste forneceramos trs ngulos :
(1,2,3) = (0,0,0). Essa seria a origem do nosso sistema de representao de
orientaes, assim como o ponto (x,y,z) = (0,0,0) seria a origem de um sistema de
representao de posies.
Para especificar a orientao obtida ao final da primeira parte de nosso exemplo,
ou seja, voando para o oeste com a asa direita apontando para o solo, no
poderamos usar os ngulos do exemplo, pois nele executamos primeiro a rotao
em torno do eixo vertical e em seguida a rotao em torno do eixo leste/oeste,
contrariando a ordem que escolhemos. Porm, se primeiro inclinarmos o avio
para a direita (rotao em torno do eixo sul/norte) para ento apont-lo para o
oeste (rotao em torno do eixo vertical) obteremos o mesmo resultado. Portanto,
para representar essa orientao usando a ordem que escolhemos, forneceramos
os ngulos (90,0,90). O leitor deve verificar que esta seqncia de rotaes
efetivamente gera a mesma orientao final que a obtida antes.
Finalmente, para especificar a orientao obtida ao final da segunda parte do
exemplo, isto , voando para baixo com a asa direita apontando para o norte, no
h qualquer dificuldade, pois as rotaes j esto na ordem correta, e
simplesmente usaramos os ngulos (0,90,90).
Por enquanto, parece que tudo vai muito bem, e de fato podemos, sem grandes
dificuldades, representar qualquer orientao fixa utilizando este sistema. Se fosse
este nosso nico objetivo, nosso problema provavelmente estaria resolvido de
forma satisfatria.

Sergio C. de Biasi e Marcelo Gattass

25/2/2002

Quatrnio e Rotaes

1.1.3 Representao de orientaes mutveis


Em muitas situaes, porm, desejamos representar orientaes que esto
continuamente sofrendo pequenas alteraes. Ao animarmos o movimento de um
avio, por exemplo, normalmente no desejamos saltar repentinamente entre
orientaes fixas predeterminadas e sim alterar pouco a pouco a orientao do
avio, seja devido a uma pequena correo da rota, seja para executar de forma
suave uma grande correo da rota.
Neste tipo de contexto, a utilizao de ngulos de Euler apresenta duas
dificuldades principais, que examinaremos a seguir.

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.

1.1.3.2 Evitando o Gimbal lock


Ou seja, uma vez que tenhamos nossa entidade em uma determinada orientao,
se desejamos gir-la um pouco mais, mesmo que seja em torno de um dos trs
eixos coordenados e no de um eixo arbitrrio, no basta simplesmente
incrementar um pouco a rotao do eixo correspondente, pois queremos executar a
nova rotao aps as rotaes que j foram previamente executadas.
Levando isso em conta, uma soluo seria simplesmente guardar uma lista de
todas as rotaes executadas sobre a entidade, na exata ordem em que foram
executadas. Porm, isso significaria guardar uma quantidade cada vez maior de
dados, e repetir toda a histria de rotaes cada vez que quisssemos orientar a
entidade. Confuso, ineficiente, e muito pouco prtico.
Outra soluo seria representar diretamente a orientao atravs de uma matriz
de rotao com relao posio inicial e simplesmente multiplicar essa matriz
por cada nova rotao aplicada entidade. Em princpio, isso funcionaria, e no
exigiria o armazenamento de toda a histria de rotao, que estaria condensada em
uma s matriz. Essa soluo, porm, tambm apresenta problemas. Em primeiro
lugar, estamos usando uma matriz 3x3 para representar algo que s tem trs graus
de liberdade ou seja, com certeza estamos guardando desnecessariamente
informao redundante. Pior do que isso, as sucessivas multiplicaes executadas
sobre a matriz inevitavelmente acumulam erros, fazendo com que a orientao
final se distancie da pretendida ou, pior ainda, a transformao representada pela

Sergio C. de Biasi e Marcelo Gattass

25/2/2002

Quatrnio e Rotaes

matriz pode at mesmo deixar de ser uma rotao, distorcendo a entidade


representada. Este ltimo problema pode ser resolvido renormalizando-se
periodicamente a matriz que representa a orientao, mas isto acrescenta ainda
mais custo, complexidade e fontes de impreciso.
Finalmente, poderamos, a cada pequena rotao, recalcular os trs ngulos de
Euler que representam essa rotao. O problema com essa soluo que os novos
ngulos de Euler no estaro necessariamente relacionados de nenhuma forma
bvia com os ngulos antes da rotao. Como j vimos antes, s vezes para girar
em torno de um eixo precisamos executar uma outra rotao prvia em torno de
outro eixo. Prximo aos pontos de gimbal lock haveria saltos ainda menos bvios.
O que precisamos de um sistema de representao em que operaes como gire
ao redor do eixo tal possam ser executadas de forma natural e automtica.

1.1.3.3 O problema da interpolao de orientaes


A segunda dificuldade importante apresentada pela representao atravs de
ngulos de Euler surge quando desejarmos interpolar entre duas orientaes, isto
, produzir uma seqncia de orientaes intermedirias entre duas orientaes
dadas.
Mesmo que no se incorra no problema de gimbal lock, ainda assim no bvio
como fazer com que uma entidade execute uma transio suave entre duas
orientaes.
Novamente, temos aqui uma situao bem diferente do caso da translao
simples, na qual a interpolao, pelo menos no caso mais trivial, imediata. Se
desejamos que uma entidade se mova de forma suave entre duas posies
percorrendo uma linha reta, simplesmente interpolamos linearmente cada uma de
suas coordenadas, de forma independente, e o problema est resolvido teremos
produzidos tantas posies intermedirias quantas quisermos ao longo da linha
reta que liga as duas posies.
No caso de uma mudana de orientao, se estivermos trabalhando com ngulos
de Euler, no entanto, essa soluo no gera resultados muito satisfatrios. A
interpolao aplicada sobre cada um dos ngulos de rotao gerar rotaes
independentes em torno desses eixos, ao invs de uma rotao suave e natural em
torno do eixo desejado.
Como exemplo, consideremos o caso de nosso avio imaginrio. Suponhamos
que, ao realizar uma animao de seu movimento, desejemos que ele execute uma
rotao da orientao (0,0,0) at a orientao (0,180,180).
A primeira orientao aquela que j conhecemos, do avio voando de cabea
para cima para o norte.
Sergio C. de Biasi e Marcelo Gattass

25/2/2002

Quatrnio e Rotaes

A segunda, pode-se concluir facilmente, corresponde ao avio voando de cabea


para baixo para o norte. Basta verificar que a rotao de 180 graus em torno do
eixo leste/oeste deixa o avio voando de cabea para baixo em direo ao sul, e a
posterior rotao em torno do eixo vertical o coloca voando de novo em direo ao
norte, mas ainda de cabea para baixo.
Se simplesmente utilizarmos uma interpolao linear entre (0,0,0) e (0,180,180),
produziremos orientaes intermedirias que parecero muito pouco naturais. Para
virar de cabea para baixo, o avio poderia simplesmente girar 180 graus em torno
do eixo sul/norte. Com a interpolao linear de (0,0,0) a (0,180,180), entretanto,
ele executar uma cambalhota estranha na qual girar simultaneamente em torno
dos eixos leste/oeste e do vertical. A orientao final ser a mesma, mas o
movimento intermedirio no. O leitor deve procurar compreender a diferena
entre as duas formas descritas de interpolar entre as duas orientaes.
Transies entre outros pares de orientaes utilizando interpolao linear dos
ngulos de Euler em geral geraro movimentos igualmente estranhos e
imprevisveis.

1.1.3.4 A interpolao natural entre orientaes


Isso nos leva questo : afinal, qual seria a forma natural de determinar
posies intermedirias entre duas orientaes? Em outras palavras, qual o
caminho que uma entidade deve seguir para transicionar suavemente de uma
orientao para outra?
Para colocar melhor a questo, examinemos o caso da interpolao entre
posies. Se desejamos que uma entidade se mova suavemente de uma posio
para outra, devemos determinar uma seqncia de posies intermedirias entre as
posies inicial e final. Porm, dadas duas posies no espao tridimensional, h
uma infinidade de curvas que as ligam. A entidade poderia mover-se de uma
posio a outra em zigue-zague, ou passando primeiro por uma outra posio
longnqua, ou atravs de outros caminhos arbitrariamente convolutos. No caso da
translao, a soluo mais simples e imediata para o problema percorrer
simplesmente uma linha reta, sem que a entidade execute quaisquer desvios
desnecessrios.
No caso da transio entre duas orientaes, desejamos, em princpio, algo
semelhante, ou seja, que a transio no inclua voltas e cambalhotas que nos
paream desnecessrias para chegar orientao final. Como formalizar esse
conceito?
Felizmente, h uma soluo bastante natural para a questo. Ela surge do fato
(demonstrado por Euler) que sempre possvel chegar de uma orientao a outra
Sergio C. de Biasi e Marcelo Gattass

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.2 Rotao ao redor de um eixo


A forma mais natural de expressar tanto orientaes como rotaes arbitrrias
seria, portanto, a especificao de um eixo e de um ngulo de rotao. Porm,
como fazer para, a partir de um ponto no espao, um eixo dado e um ngulo de
rotao, determinar a nova posio do ponto aps sofrer a rotao especificada?
De forma mais precisa, seja um ponto no 3 representado por um vetor
r
r = (rx , ry , rz ) . Seja ,nr uma rotao anti-horria de um ngulo em torno de um
r
eixo que intercepta a origem definido por um vetor unitrio n = (n x , n y , n z ) .
r
Desejamos determinar uma expresso para ( r ) , ou seja, para o vetor que
r
representa o ponto obtido aps aplicarmos a r a rotao .
r
r
O problema pode ser resolvido decompondo r em suas componentes normal r e
r
r
paralela r|| ao vetor n , aplicando a rotao separadamente a essas componentes e
r
somando os resultados. Para obtermos a magnitude da componente de r paralela
r
r r
ao vetor n , basta realizarmos o produto escalar entre n e r .
Pensando assim, obtemos que
r r r
r = r|| + r
r
r r r
r|| = (n r ) n
r
r r r r r r
r = r r|| = r (n r ) n

(1)

A componente r|| , naturalmente, permanece inalterada por uma rotao em torno


r
do eixo definido por n , de forma que temos
r
r
(2)
( r ) = r
||

Sergio C. de Biasi e Marcelo Gattass

||

25/2/2002

Quatrnio e Rotaes

11

Portanto, o problema que nos resta determinar qual o resultado da rotao de

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

teremos que n , r e v formaro um triedro direto, e em particular que r e v


sero perpendiculares e estaro no plano onde ocorrer a rotao. Alm disso,
r
r
r
como n unitrio, v ter a mesma norma que r . Portanto, imediato verificar
(4)
que
r
r
r
( r ) = (cos ) r + (sen) v

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

Somando as componentes, encontramos que


r
r r
( r ) = ( r|| + r )
r
r
= ( r|| ) + ( r )
r
r
r
= r|| + (cos ) r + (sen) v
r r r
r r r r
r r
= (n r ) n + (cos )( r (n r ) n ) + (sen)(n r )
r r r
r
r r r
r r
= (n r ) n + (cos ) r (cos )(n r ) n + (sen)(n r )
r
r r r
r r
= (cos ) r + (1 cos )(n r ) n + (sen)(n r )

Sergio C. de Biasi e Marcelo Gattass

(5)

25/2/2002

Quatrnio e Rotaes

12

Desta forma, conclumos que o ponto resultante da realizao de uma rotao

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 )

Sergio C. de Biasi e Marcelo Gattass

(6)

25/2/2002

Quatrnio e Rotaes

13

2 Representao de rotaes em 3D com o uso de quatrnios

Como se pde observar, a realizao de rotaes em torno de eixos arbitrrios


leva a expresses extensas e pouco intuitivas se operarmos diretamente com eixos
cartesianos e ngulos. Os quatrnios nos fornecem um sistema de representao
bem mais adequado para operar sobre rotaes.

2.1 Rotaces em 2D e nmeros complexos


Sob vrios aspectos, os quatrnios podem ser encarados como uma
generalizao, no espao tridimensional, do que os nmeros complexos
representam para o espao bidimensional. Portanto, comearemo por relembrar
algumas caractersticas dos nmeros complexos.
Um nmero complexo definido atravs de dois parmetros, nmeros reais
usualmente chamados de a e b. O parmetro a chamado de parte real do nmero
complexo, e o parmetro b, de parte imaginria. A unidade dos nmeros
imaginrios, ou seja, o nmero complexo (0,1), normalmente chamada de i.
Portanto, outra forma de representar um nmero complexo da forma
(7)
c = a+bi
As propriedades de adio e multiplicao dos nmeros complexos so definidas
de tal forma que, entre outras propriedades importantes, eles podem ser utilizados
para representar rotaes no plano.
Como cada nmero complexo dado por dois parmetros, podemos interpretlos como coordenadas cartesianas planas. Dessa forma, o parmetro a corresponde
coordenada x e o parmetro b coordenada y. Podemos, portanto, pensar em um
nmero complexo como um vetor no plano.
Uma outra forma de representao, que ser importante ao operarmos com
rotaes, a forma polar, na qual um vetor descrito atravs de sua norma
(comprimento cartesiano) e e de seu deslocamento angular (rotao anti-horria
em torno da origem a partir do eixo dos x).
Em resumo, podemos pensar em um nmero complexo como uma soma
algbrica de um nmero real com um nmero imaginrio, na forma a+bi, como
um vetor cartesiano (a,b) ou como um vetor polar (r,).

Sergio C. de Biasi e Marcelo Gattass

25/2/2002

Quatrnio e Rotaes

14

A soma de dois nmeros complexos dada simplesmente pela soma vetorial


cartesiana, componente a componente, com a qual estamos acostumados, ou seja :
(8)
a1+b1i + a2+b2i = a1+a2 + (b1+b2)i
Isto exatamente o mesmo que dizer que
(a1, b1) + (a2, b2) = (a1+a2, b1+b2)

(9)

J a multiplicao, porm, tem a seguinte propriedade : quando multiplicamos


dois nmeros complexos, obtemos um vetor cuja norma o produto das normas
dos vetores sendo multiplicados e cujo deslocamento angular a soma dos
deslocamentos angulares de cada vetor. Em coordenadas polares, isso resulta
(10)
simplesmente que :
(r1, 1) (r2, 2) = (r1r2, 1+2)
A propriedade dos deslocamentos angulares se somarem significa que podemos
pensar na multiplicao entre dois complexos como uma operao de rotao. No
caso de um complexo com norma unitria, teremos a representao de uma
rotao pura, que numa operao de multiplicao alterar apenas a orientao de
um outro vetor sem modificar sua norma. Em particular, o imaginrio puro i, que
corresponde ao vetor polar (1,90), representar sempre uma rotao anti-horria de
90 graus em torno da origem.
Examinemos um exemplo concreto. Se multiplicamos o vetor cartesiano (1,1),
que corresponde ao vetor polar ( 2 ,45), pelo vetor cartesiano (0,1), que
corresponde ao vetor polar (1,90), obteremos, pelo enunciado acima, o vetor polar
( 2 ,45)(1,90) = ( 2 ,90+45) = ( 2 ,135), que corresponde ao vetor cartesiano (1,1). Este resultado pode ser pode ser interpretado tanto como o vetor cartesiano
(1,1) rotacionado de 90 graus no sentido anti-horrio quanto como o vetor (1,0)
escalado por um fator de 2 e rotacionado de 45 graus no sentido anti-horrio.

Sergio C. de Biasi e Marcelo Gattass

25/2/2002

Quatrnio e Rotaes

15

(-1, 1)

(1, 1)

(0, 1)
=90
=45

c = ab = ba

Figura 2 : Rotao com complexos


De fato, fcil verificar que como tanto a multiplicao de normas quanto a
soma de ngulos de rotao plana so comutativas, ento a multiplicao de
nmeros complexos , conseqentemente, sempre comutativa, como pudemos
observar no exemplo acima.
Como realizar tais operaes de forma algbrica, operando diretamente sobre as
coordenadas cartesianas?
Se realizarmos a multiplicao entre dois complexos da forma algbrica usual,
obteremos que
(a1+b1i)(a2+b2i) =
a1a2 + a1b2i + b1ia2 + b1ib2i =

(11)

a1a2 + (a1b2 + a2b1)i + b1b2i2


A questo : o que fazer com o termo i2 que surgiu? Qual o seu significado?
Como queremos fazer valer as propriedades previamente enunciadas para a
multiplicao, ento somos obrigados a concluir que i2 dever calculado como a
multiplicao do vetor cartesiano (0,1) por si mesmo. Isso significa multiplicar o
vetor polar (1,90) por si mesmo, cujo resultado (1,180). Voltando s coordenadas
cartesianas, verificamos que obtivemos o vetor (-1,0). Em outras palavras, o
nmero i, ao operar uma rotao de 90 graus sobre o vetor (0,1), produz o vetor ((12)
1,0). Ou seja, conclumos que
i2 = -1
Com base nisso, podemos agora escrever a expresso final para a multiplicao :
(13)
(a1+b1i)(a2+b2i) = (a1a2-b1b2) + (a1b2 + a2b1)i

Sergio C. de Biasi e Marcelo Gattass

25/2/2002

Quatrnio e Rotaes

16

Com estas definies para as operaes envolvendo nmeros complexos,


podemos representar e operar sobre orientaes e rotaes bidimensionais de
forma prtica e automtica.

2.2 Generalizando os nmeros complexos


Apresentada esta soluo para o problema de rotao bidimensional, pode
parecer que no seria muito difcil construir um sistema semelhante para o
tratamento de rotaes tridimensionais.
Infelizmente, porm, a generalizao dos complexos para o espao
tridimensional no to imediata e exigiu muito esforo at ser concebida.
Talvez um dos principais impecilhos tenha sido o fato de que parece intuitivo
imaginar que uma tal generalizao se basearia em trs parmetros, ou seja, no
acrscimo de um parmetro extra para a dimenso extra acrescentada.
No entanto, embora apenas um grau de liberdade tenha sido acrescentado
translao, o impacto disso sobre as possibilidades de rotao bem mais forte.
O fato que, num mundo bidimensional, existe apenas um grau de liberdade de
orientao, isto , o que corresponde rotao em torno da origem. Ao
parametrizar uma rotao, precisamos especificar apenas seu ngulo, pois o eixo
obrigatoriamente o perpendicular ao plano considerado. Portanto, quando
acrescentamos a terceira dimenso, ganhamos no um mas dois graus de liberdade
de rotao, que precisam, para serem representados de forma similar dos
complexos, de uma unidade imaginria cada um.
O resultado que a generalizao dos complexos para o mundo tridimensional
usa naturalmente no trs mas quatro parmetros e correspondetemente
constituda por nmero chamados de quatrnios.

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.

Sergio C. de Biasi e Marcelo Gattass

25/2/2002

Quatrnio e Rotaes

17

Um quatrnio, portanto, um nmero da forma q = (a,b,c,d) ou,


equivalentemente,
q = a+bi+cj+dk

(13)

Podemos tambm expressar um quatrnio de forma ainda mais condensada


r
r
dizendo que q = (s, v) , onde s um escalar que representa sua parte real e v =
(vx,vy,vz) um vetor de trs componentes que representa sua parte imaginria.
As propriedades de i, j e k so generalizaes das propriedades do i dos
complexos. As definies que levam s propriedades desejadas exigiram,
historicamente, muita reflexo antes de serem adequadamente formuladas, e so
apresentadas a seguir.
De forma similar aos complexos, temos que
i2 = j2 = k2 = -1

(14)

Porm, ao contrrio dos complexos, precisamos lidar tambm com


multiplicaes entre imaginrios de natureza diferente. Isso resolvido definindo
que
ij = k
ji = -k
Da definio acima, fcil verificar que
ij = k ijk = kk ijk = -1 iijk = -i -jk = -i jk = i
Assim como que
jk = i jki = ii jki = -1 jjki = -j -ki = -j ki = j

(15)

(16)

(17)

Observe-se que o produto de dois quatrnios, ao contrrio dos complexos, no


comutativo, como alis seria de se esperar, j que as rotaes tridimensionais, ao
contrrio das planas, no comutam.
A soma de dois quatrnios simplesmente a soma algbrica usual componente a
componente.

Sergio C. de Biasi e Marcelo Gattass

25/2/2002

Quatrnio e Rotaes

18

A relevncia dos quatrnios reside em sua operao de multiplicao. A partir


das definies acima, podemos verificar que, dados dois quatrnios q1 e q2, seu
produto ser :
q1q2 = (a1+b1i+c1j+d1k)(a2+b2i+c2j+d2k) =
= a1(a2+b2i+c2j+d2k) + b1i(a2+b2i+c2j+d2k) +
c1j(a2+b2i+c2j+d2k) + d1k(a2+b2i+c2j+d2k) =
= a1a2+ a1b2i+ a1c2j+ a1d2k + b1ia2+ b1ib2i+ b1ic2j+ b1id2k +
c1ja2+ c1jb2i+ c1jc2j+ c1jd2k + d1ka2+ d1kb2i + d1kc2j+ d1kd2k =

(18)

= a1a2+ b1b2i2+ c1c2j2+ d1d2k2 + a1b2i + a1c2j+ a1d2k + b1a2i +


c1a2j + d1a2k+ b1c2ij+ b1d2ik + c1b2ji+ c1d2jk + d1b2ki + d1c2kj =
= a1a2 (b1b2 + c1c2 + d1d2) + a1(b2i + c2j+ d2k) + a2(b1i + c1j +
d1k) + b1c2k b1d2j c1b2k+ c1d2i + d1b2j d1c2i =
= a1a2 (b1b2 + c1c2 + d1d2) + a1(b2i + c2j+ d2k) + a2(b1i + c1j +
d1k) + (c1d2 d1c2)i + (d1b2 b1d2)j + (b1c2 c1b2)k

Coletando os termos obtidos acima e expressando o resultado em termos de


produtos escalares e vetoriais, podermos escrever esta frmula como
(19)
r
r
r r
r
r r r
q 1q 2 = (s1 , v1 )(s 2 , v 2 ) = (s1s 2 v1 v 2 , s1 v 2 + s 2 v1 + v1 v 2 )

O conjugado de um quatrnio q = (s, v) representado por q e definido como


r
(20)
q = (s, v)
O inverso de um quatrnio q representado por q-1 e definido como o quatrnio
tal que
(21)
qq-1 = q-1q = 1
A magnitude de um quatrnio obtida atravs do produto do quatrnio por seu
conjugado :
r
r
r r
r r r r
2
q = qq = (s, v)(s, v) = (s 2 v v, sv + sv + v v) =
r r
r2
= (s 2 + v v, 0) = s 2 + v

Sergio C. de Biasi e Marcelo Gattass

(22)

25/2/2002

Quatrnio e Rotaes

19

2.3.1 Representao e composio de rotaes


Dadas essas definies, passemos agora a descrever como os quatrnios podem
ser usados para representar rotaes.
r

O ponto r = (rx , ry , rz ) sobre o qual queremos executar uma rotao ser


r
representado por um quatrnio p = (0, r ) com parte real nula.
r

A rotao que aplicaremos sobre o ponto r ser representada por um quatrnio


r
unitrio q = (s, v) , isto , um quatrnio q tal que qq = 1 .
Passaremos agora a demonstrar que o resultado da rotao de p por q poder ser
obtido atravs da expresso
(23)
1
R q (p) = qpq

Como q unitrio, temos que o inverso de q seu conjugado, pois


qq = 1 q 1qq = q 1 q = q 1

Logo, a expresso de rotao pode ser escrita como


R q (p) = qpq

(24)

(25)

Expandindo esta expresso, obtemos :


qpq =
r
r
r
(s, v)(0, r )(s, v) =
r r
r
r r r
r
(s, v)(0 s r v, 0 v + s r + r v) =
r r r r r r
(s, v)( r v, s r r v) =
r r r r r r
r r r
r r r r
r r r
(24)
(s ( r v) v (s r r v), s (s r r v) + ( r v) v + v (s r r v)) =
r r r r r
r r
r r r r r r r r r
r r
(s ( r v) v s r v ( r v), s 2 r s r v + ( r v) v + v s r + v ( r v) =
r r
r r r r r
r r r r r r r r r r r
(s ( r v) s ( r v) + v ( r v), s 2 r + sv r + ( r v) v + sv r + v ( v r ) =
r r r r
r r r
r r r r r r r r
( v ( r v), s 2 r + ( r v) v + 2 sv r + ( v r ) v ( v v) r =
r r r r
r r r
r r
(0, s 2 r ( v v) r + 2 ( v r ) v + 2 sv r )

Observao : na deduo acima, utilizamos as identidades a seguir :

Sergio C. de Biasi e Marcelo Gattass

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

Se substituirmos agora esta interpretao de q na expresso obtida anteriormente


para o resultado da rotao, obteremos
r r r r
r r r
r r
(0, s 2 r ( v v) r + 2 ( v r ) v + 2 sv r ) =
r
r
r r
r r
r
r r
(0, (cos 2 ) r (sen n sen n ) r + 2 (sen n r )sen n + 2 cos (sen n ) r ) =
r
r r r
r r r
r r
(0, (cos 2 ) r (sen 2 n n ) r + (2 sen 2 ) (n r ) n + (2 cos sen) n r ) =
r
r
r r r
r r
(0, (cos 2 ) r (sen 2 ) r + (1 cos 2) (n r ) n + (sen 2) n r ) =
(27)
r
r r r
r r
2
2
(0, ( cos sen ) r + (1 cos 2) (n r ) n + ( sen 2) n r ) =
r
r r r
r r
(0, ( cos 2) r + (1 cos 2) (n r ) n + (sen 2) n r )

Observao : na deduo acima, utilizamos as identidades a seguir :


r r r2
a a = a
cos 2 sen 2 = cos 2

(28)

2sen 2 = (1 cos 2)
2 cos sen = sen 2

Se compararmos agora a parte imaginria da expresso obtida acima com a que


derivamos ao final da seo 1.3 para a rotaao em torno de um eixo, verificamos
que so exatamente idnticas com exceo do fator 2 associado ao ngulo .
r

Isso significa que se desejamos aplicar a um ponto r uma rotao anti-horria de


r
um ngulo ao redor do eixo definido pelo vetor unitrio n , podemos resolver a
questo com quatrnios do seguinte modo :
r

Represente r pelo quatrnio p = (0, r )


r

Represente a rotao desejada pelo quatrnio q = (cos( / 2), sen ( / 2) n )


Sergio C. de Biasi e Marcelo Gattass

25/2/2002

Quatrnio e Rotaes

21

Realize a operao R q (p) = qpq


A parte real do resultado ser zero e a parte imaginria conter o resultado
da rotao
Essa pode parecer, a princpio, uma forma tortuosa de obter o mesmo resultado.
Porm, examinemos o que ocorre com a composio de duas rotaes.
Suponhamos dois quatrnios q1 e q2 representando duas rotaes distintas.
Aplicando sobre um ponto p a rotao composta de q1 seguida de q2 obteramos
(29)
R q 2 (R q1 (p)) = R q 2 (q 1 pq1 ) = q 2 q 1 pq1 q 2 = q 3 pq 4

Por outro lado, temos que


r
r
r r
r
r r r
q 3 = q 2 q1 = (s 2 , v 2 )(s1 , v1 ) = (s 2 s1 v 2 v1 , s 2 v1 + s1 v 2 + v 2 v1 )
r r
r
r r r
q 3 = (s 2 s1 v 2 v1 , s 2 v1 s1 v 2 v 2 v1 )
r r
r
r r r
= (s 2 s1 v 2 v1 , s 2 v1 s1 v 2 + v1 v 2 )
r
r
r r
r
r r r
q 4 = q1q 2 = (s1 , v1 )(s 2 , v 2 ) = (s1s 2 v1 v 2 , s1 v 2 s 2 v1 + v1 v 2 ) = q 3

(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)

Portanto, com essa parametrizao, obtemos uma grande vantagem : a


composio de rotaes realizada naturalmente pela prpria lgebra dos
quatrnios. Se dispomos de dois quatrnios unitrios que representam duas
rotaes de ngulos diferentes em torno de eixos distintos, e desejamos encontrar
uma representao para a rotao que resulta da composio dessas duas rotaes,
basta multiplicarmos os dois quatrnios. Como resultado, obteremos
automaticamente um novo quatrnio unitrio cuja parte imaginria ser um vetor
na direo e sentido do eixo da rotao resultante e a parte real o cosseno do
ngulo de rotao. Desse modo, estaremos sempre descrevendo nossas rotaes da
forma natural (e nica salvo o sentido de rotao) que buscvamos.
Para ilustrar esse fato, voltemos ao nosso exemplo da orientao de um avio.
Resolvamos, agora com quatrnios, o exemplo em que o piloto, inicialmente
voando para o norte, primeiro realiza uma rotao de 90 graus em torno do eixo
leste/oeste (voltando o nariz para o solo) e depois outra de 90 graus em torno do
eixo sul/norte (voltando a asa esquerda para o cu).

Sergio C. de Biasi e Marcelo Gattass

25/2/2002

Quatrnio e Rotaes

22

A primeira rotao ser representada pelo quatrnio


q1 = (cos(90 / 2), sen (90 / 2)(0,1,0)
= ( 2 / 2, ( 2 / 2)(0,1,0))

(32)

= ( 2 / 2, (0, ( 2 / 2),0))

E a segunda rotao pelo quatrnio


q 2 = (cos(90 / 2), sen (90 / 2)(1,0,0)
= ( 2 / 2, ( 2 / 2)(1,0,0))
= ( 2 / 2, (( 2 / 2),0,0))

(33)

A rotao composta, portanto, ser


q3 =
q2q1 =
( 2 /2, (( 2 /2), 0, 0))( 2 /2, (0, ( 2 /2), 0)) =
(( 2 /2)( 2 /2) (( 2 /2), 0, 0)(0, ( 2 /2), 0), ( 2 /2)(0, ( 2 /2),
0) + ( 2 /2)(( 2 /2), 0, 0) + (( 2 /2), 0, 0)(0, ( 2 /2), 0)) =
( (0+0+0), (0, , 0) + (, 0, 0) + (1,0,0)(0,1,0)) =
(, (, , 0) + (0,0,1)) =
(, (, , 0) + (0,0, )) =

(34)

(, (, , ))

Isso corresponde a uma rotao anti-horria de = 2arccos() = 120 graus em


torno do eixo definido pelo vetor (, , ).
Para conferir que esta rotao simples em torno de um nico eixo realmente
corresponde composio das duas rotaes dadas, vamos aplic-la ao nosso
avio. Suponhamos um ponto na asa direita do avio, com ele voando em sua
orientao inicial, voltado para o norte. Imaginemos que esse ponto ocupe a
r
posio r1 = (10, 5, 0) , ou seja, a dez unidades a norte da origem, cinco para o
leste e a zero de altura. J sabemos que aps as duas rotaes, o avio dever estar
voando para o oeste, com a asa direita apontando para o solo, ou seja, com
r
r2 = (0,10,5) .
r

Aplicando a rotao deduzida acima sobre r1 , obtemos :

Sergio C. de Biasi e Marcelo Gattass

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)

Ou seja, simplesmente multiplicando quatrnios, somos capazes de descobrir a


parametrizao em coordenadas naturais da composio de um nmero
arbitrrio de rotaes e de aplicar essas rotaes a pontos dados. Dessa forma, para
representar a orientao de uma entidade, precisamos de somente um quatrnio.
Mais do que isso, estamos livres tambm do problema de gimbal lock. No
existem eixos preferenciais ou perda de graus de liberdade nesta parametrizao.
A partir de qualquer rotao ou posio, podemos aplicar qualquer outra rotao,
sem restries.

2.3.2 Interpolao de orientaes


Podemos agora retornar questo da interpolao de orientaes. Dadas duas
orientaes, representadas por um quatrnio cada uma, como determinar os
quatrnios que representam uma seqncia de orientaes intermedirias?
Poderamos, ingenuamente, imaginar que seria suficiente executar uma
interpolao linear entre os dois quatrnios, componente a componente. Esse
procedimento, porm, no gera o resultado desejado. fcil verificar que esse o
caso atravs de um exemplo.
Sergio C. de Biasi e Marcelo Gattass

25/2/2002

Quatrnio e Rotaes

24

Voltando ao nosso avio, imaginemos que desejamos iniciar a interpolao na


orientao inicial de voando para o norte com a barriga para o solo, que
atingida atravs de uma rotao de zero graus em torno de qualquer eixo, e
portanto representada pelo quatrnio
(36)
r
q1 = (cos(0/2), sen(0/2) n ) = (1, (0,0,0))
e terminar na orientao voando para o norte com a barriga para o cu, que
atingida atravs de uma rotao de 180 graus em torno do eixo sul/norte, e
portanto representada pelo quatrnio
q2 = (cos(180/2), sen(180/2)(1, 0, 0)) = (0, (1, 0, 0))

(37)

Para determinar um nico quatrnio intermedirio por interpolao linear, basta


tomar a mdia dos dois quatrnios, isto ,
q = (q +q ) = ( (1, (0,0,0)) + (0, (1, 0, 0)) ) = (, (, 0, 0)) (38)
3

imediato verificar que o quatrnio q3 no a orientao que desejamos. Na


verdade, o quatrnio encontrado sequer atende ao requisito para representar uma
rotao, pois no unitrio. De fato, se calculamos sua norma, verificamos que
q3

= ()2 + (()2 + 02 + 02) = + = q 3 = 2

(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.

Sergio C. de Biasi e Marcelo Gattass

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

uma interpolao ao longo

Figura 3 : Interpolao entre orientaes com complexos


Com isso, esbarramos em outra questo : ao contrrio da interpolao linear, h
dois caminhos igualmente vlidos para realizarmos a interpolao, pois
podemos percorrer o crculo tanto no sentido horrio como no anti-horrio e em
ambos os casos chegaremos orientao final desejada. A escolha natural
escolher o caminho mais curto (que corresponder ao menor ngulo de rotao)
mas preciso escolher um dos dois. Mesmo assim, h o caso limite das duas
orientaes ocuparem posies diamentralmente opostas no crculo e portanto os
dois caminhos terem igual comprimento; nessa situao, no h uma escolha
natural por um ou por outro e somos obrigados a selecionar arbitrariamente um
dos dois. Em termos concretos, essa situao surge quando queremos girar uma
entidade de 180 graus; podemos girar tanto no sentido anti-horrio como no
horrio que obteremos o mesmo resultado com o mesmo esforo.
Toda essa discusso se generaliza, sem grandes mudanas, para o caso dos
quatrnios e rotaes tridimensionais. Ao executar uma interpolao entre dois
quatrnios que representam rotaes, devemos procurar o caminho mais curto
sobre a superfcie da hiperesfera unitra que contm todos os quatrnios que
representam rotaes e dividi-lo em segmentos de comprimento igual.
Executar a operao acima no to complicado como possa parecer. Em
primeiro lugar, devemos determinar a distncia angular entre os dois quatrnios na
superfcie da hiperesfera. Como ambos so unitrios, o produto escalar dos dois
produzir o cosseno do ngulo :
q1q2 = cos = arccos(q1q2)

Sergio C. de Biasi e Marcelo Gattass

(40)

25/2/2002

Quatrnio e Rotaes

26

A expresso para o quatrnio que corresponde a uma posio angular


intermediria entre q1 e q2, ou seja, com um deslocamento entre zero e com
relao a q1, dada por
q 3 = q1

sen ( )
sen
+ q2
sen
sen

(41)

Substituindo por u, onde u[0,1], obtemos


q 3 = q1

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.

Sergio C. de Biasi e Marcelo Gattass

25/2/2002

Quatrnio e Rotaes

27

3 Uma implementao em C das operaes com quatrnios


3.1

Descrio da biblioteca

Nesta biblioteca, escrita em C, implementamos rotinas que permitem a realizao


de todas as operaes descritas neste trabalho. O usurio precisa apenas incluir o
arquivo cabealho quat.h e poder usar qualquer das funes da biblioteca. Foi
includo tambm um pequeno programa de demonstrao que resolve as contas
apresentadas ao final da seo 2.4.1.
A biblioteca define e ulitiza trs tipos bsicos : um para conter quatrnios, dados
pelos seus quatro parmetros usuais, um para conter rotaes sob a forma de
ngulo em graus e eixo de rotao (descrita no trabalho e utilizada, por exemplo,
pelo OpenGL) e, finalmente, um tipo que contm uma posio, em coordenadas
cartesianas, no espao tridimensional.
quatAdd retorna a soma de dois quatrnios.
quatSub retorna a diferena de dois quatrnios.
quatScale retorna o produto de um escalar por um quatrnio.
quatMult retorna o produto de dois quaternios.
quatConj retorna o conjugado de um quatrnio.
quatNorm calcula a norma de um quatrnio.
quatNormalize normaliza um quatrnio (isto , aplica a ele uma escala tal que
ele se torne unitrio ou retorna o prprio quatrnio se sua norma for zero).
quatInv calcula o inverso multiplicativo de um quatrnio (isto , retorna o
quatrnio que multiplicado pelo quatrnio dado resulta no valor real 1 ou o prprio
quatrnio se sua norma for zero).
quatLinearInterpol retorna um quatrnio intermedirio entre dois quatrnios
dados, obtido por interpolao linear simples componente a componente e situado
a uma frao dada (entre 0 e 1) da distncia linear entre os dois. Essa funo,
apesar de disponibilizada ao usurio, foi implementada basicamente para uso
interno pela biblioteca.
quatDot retorna o produto escalar entre dois quatrnios.
quatAngularInterpol retorna um quatrnio intermedirio entre dois quatrnios
dados, obtido por interpolao angular sobre a hiperesfera unitria e situado a uma
frao dada (entre 0 e 1) da distncia angular entre os dois.

Sergio C. de Biasi e Marcelo Gattass

25/2/2002

Quatrnio e Rotaes

28

quatToRotation retorna a rotao codificada por um quatrnio.


quatFromRotation retorna o quatrnio correspondente a uma rotao.
quatToPosition retorna a posio correspondente a um quatrnio.
quatFromPosition retorna o quatrnio correspondente a uma posio.
quatCompose retorna a rotao correspondente composio de duas rotaes
sucessivas.
quatRotate retorna a posio correspondente aplicao de uma rotao dada
sobre uma posio dada.

3.2 Listagem da biblioteca


3.2.1 Arquivo quat.h
/* quat.h */
/* Copyright (c) 2001 Sergio Biasi <sbiasi@sbiasi.com> */
/* Distribution and use of this is completely free */

#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;

Sergio C. de Biasi e Marcelo Gattass

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

quatAdd(quat_t q1, quat_t q2);


quatSub(quat_t q1, quat_t q2);
quatScale(double s, quat_t q1);
quatMult(quat_t q1, quat_t q2);
quatConj(quat_t q);
quatNorm(quat_t q);
quatNormalize(quat_t q);
quatInv(quat_t q);
quatLinearInterpol(quat_t q1, quat_t q2, double t);
quatDot(quat_t q1, quat_t q2);
quatAngularInterpol(quat_t q1, quat_t q2, double u);

quat_rot_t quatToRotation(quat_t q);


quat_t quatFromRotation(quat_rot_t r);
quat_pos_t quatToPosition(quat_t q);
quat_t quatFromPosition(quat_pos_t p);
quat_rot_t quatCompose(quat_rot_t r1, quat_rot_t r2);
quat_pos_t quatRotate(quat_pos_t p, quat_rot_t r);

#endif /* _QUAT_H_INCLUDED_ */

3.2.2 Arquivo quat.c


/* quat.c */
/* Copyright (c) 2001 Sergio Biasi <sbiasi@sbiasi.com> */
/* Distribution and use of this is completely free */
#include <math.h>
#include "quat.h"

const double halfpi = 1.57079632679489661923132169164;


const double epsilon = 0.000001;

/* Sum of two quaternions */


quat_t quatAdd(quat_t q1, quat_t q2)
{
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;
}

/* Difference of two quaternions */


quat_t quatSub(quat_t q1, quat_t q2)
{

Sergio C. de Biasi e Marcelo Gattass

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

/* Product of a quaternion and a scalar */


quat_t quatScale(double s, quat_t q1)
{
quat_t qr;
qr.s = s * q1.s;
qr.vx = s * q1.vx;
qr.vy = s * q1.vy;
qr.vz = s * q1.vz;
return qr;
}

/* Product of two quaternions */


quat_t quatMult(quat_t q1, quat_t q2)
{
quat_t qr;
qr.s = q1.s*q2.s qr.vx = q1.s*q2.vx
qr.vy = q1.s*q2.vy
qr.vz = q1.s*q2.vz

q1.vx*q2.vx - q1.vy*q2.vy - q1.vz*q2.vz;


+ q2.s*q1.vx + q1.vy*q2.vz - q1.vz*q2.vy;
+ q2.s*q1.vy + q1.vz*q2.vx - q1.vx*q2.vz;
+ q2.s*q1.vz + q1.vx*q2.vy - q1.vy*q2.vx;

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

Sergio C. de Biasi e Marcelo Gattass

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

/* Multiplicative inverse of a quaternion */


/* (or return the original quaternion if its norm is zero) */
quat_t quatInv(quat_t q)
{
double norm;
if( (norm = quatNorm(q)) == 0.0)
return q;
return quatScale(1.0 / norm, quatConj(q));
}

/* Linear interpolation of two quaternions */


quat_t quatLinearInterpol(quat_t q1, quat_t q2, double t)
{
return quatAdd(quatScale((1.0 - t), q1), quatScale(t, q2));
}

/* Dot (scalar) product of two quaternions */


double quatDot(quat_t q1, quat_t q2)
{
return sqrt(q1.s*q2.s + q1.vx*q2.vx + q1.vy*q2.vy + q1.vz*q2.vz);
}

/* Angular interpolation of two quaternions */


quat_t quatAngularInterpol(quat_t q1, quat_t q2, double u)
{
double cosomega;
double sinomega;
double omega;
double s1, s2;

if( quatNorm(quatSub(q1,q2)) > quatNorm(quatAdd(q1,q2)) )


q2 = quatScale(-1,q2);

cosomega = quatDot(q1,q2);

if( (1.0 - cosomega) < epsilon )

Sergio C. de Biasi e Marcelo Gattass

25/2/2002

Quatrnio e Rotaes

32

{
return quatLinearInterpol(q1, q2, u);
}

if( (1.0 + cosomega) < epsilon )


{
quat_t q2a;
q2a.s = -q2.vx;
q2a.vx = q2.s;
q2a.vy = -q2.vz;
q2a.vz = q2.vy;
s1 = sin( (1.0 - u) * halfpi );
s2 = sin( u * halfpi );
return quatAdd(quatScale(s1, q1), quatScale(s2, q2a));
}

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

/* Recover a (theta,n) rotation from a quaternion */


/*
theta is the angle of counter-clockwise rotation in degrees */
/*
n is a vector for the axis of rotation */
quat_rot_t quatToRotation(quat_t q)
{
quat_rot_t rr;
rr.theta = (acos(q.s)*180)/halfpi;
rr.nx = q.vx;
rr.ny = q.vy;
rr.nz = q.vz;
return rr;
}

/* Encode a (theta,n) rotation in a unit quaternion */


/*
theta is the angle of counter-clockwise rotation in degrees */
/*
n is a vector for the axis of rotation */
/* (return a quaternion for a null rotation if the vector n is too small) */
quat_t quatFromRotation(quat_rot_t r)
{
quat_t qr;
double halftheta;
double sinhalftheta;
double axisnorm;
if( (axisnorm = sqrt(r.nx*r.nx + r.ny*r.ny + r.nz*r.nz)) < epsilon)
{
qr.s = 1.0;

Sergio C. de Biasi e Marcelo Gattass

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

/* Recover a position from a quaternion */


quat_pos_t quatToPosition(quat_t q)
{
quat_pos_t pr;
pr.x = q.vx;
pr.y = q.vy;
pr.z = q.vz;
return pr;
}

/* Encode a position in a quaternion */


quat_t quatFromPosition(quat_pos_t p)
{
quat_t qr;
qr.s = 0.0;
qr.vx = p.x;
qr.vy = p.y;
qr.vz = p.z;
return qr;
}

/* Compose two rotations using quaternions */


quat_rot_t quatCompose(quat_rot_t r1, quat_rot_t r2)
{
return quatToRotation(quatMult(quatFromRotation(r2),quatFromRotation(r1)));
}

/* Rotate a given position using a given rotation */


quat_pos_t quatRotate(quat_pos_t p, quat_rot_t r)
{
return quatToPosition( quatMult( quatFromRotation(r),
quatMult( quatFromPosition(p),
quatConj(quatFromRotation(r)) )
));
}

Sergio C. de Biasi e Marcelo Gattass

25/2/2002

Quatrnio e Rotaes

34

3.2.3 Arquivo quatdemo.c


/* quatdemo.c */
/* Copyright (c) 2001 Sergio Biasi <sbiasi@sbiasi.com> */
/* Distribution and use of this is completely free */

#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 PrintRot(quat_rot_t rot)


{
printf("(%01.2f %01.2f %01.2f %01.2f)", rot.theta, rot.nx, rot.ny, rot.nz);
}

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

Sergio C. de Biasi e Marcelo Gattass

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

Sergio C. de Biasi e Marcelo Gattass

25/2/2002

Vous aimerez peut-être aussi