Realidade Virtual
Aula 4
Remis Balaniuk
Exercício de Montagem de um
objeto 3D
– Escreva um projeto no Chai que crie um
cubo, centrado na origem do sistema de
coordenadas (0,0,0), com lados tendo
tamanho 1.
– Programe uma tecla que dê uma volta com a
câmera ao redor do cubo.
– Programe uma tecla que dê uma volta com a
luz ao redor do cubo.
Transformações
• Os modelos (topologias) dos objetos de uma
cena virtual normalmente não mudam durante
uma simulação, e quando precisam mudar por
exigência da aplicação isso requer algoritmos e
interfaces que podem ser bastante complexos.
• Já a representação dos objetos mudam
constantemente e isso pode ser feito por uma
série de operações matemáticas razoavelmente
simples chamadas de transformações.
Transformações
• As transformações de Translação, Escala e
Rotação que serão apresentadas neste módulo
são o “coração” de todas as aplicações em
Computação Gráfica.
• Veremos que as transformações podem ser
expressas de forma simples, através da
Multiplicação Matricial e que as Coordenadas
Homogêneas permitem um tratamento uniforme
para as transformações.
• Começaremos estudando as transformações
em 2D para depois extende-las a 3D.
Princípios das Transformações 2D
• Transformações são usadas para gerar um novo
ponto (x’, y’) a partir das coordenadas (x,y) de
um ponto que descreve o objeto original.
• Se o objeto original é uma linha, é suficiente
aplicar as transformações aos pontos extremos
e então desenhar a linha entre os dois pontos
transformados para obter a transformação da
linha.
• O mesmo é verdade para polígonos e objetos.
• Ou seja, se temos que, por exemplo, rotacionar
um objeto tridimensional complexo, basta
aplicar a mesma operação de rotação a todos
os seus pontos e este terá sido rotacionado.
Princípios das Transformações 2D
• As transformações ditas “rígidas” são aquelas
que não mudam a topologia ou a forma do
objeto, só a sua representação.
• As tranformações rígidas básicas são a
translação, rotação e a mudança de escala.
• Qualquer movimentos complexo em 3D pode
ser decomposto nessas 3 transformações
básicas.
• Por exemplo, um objeto que cai está ao mesmo
tempo se transladando e rodando (rotacionando
em torno de sí mesmo) ao mesmo tempo.
Princípios das Transformações 2D
• Como as transformações são aplicadas vértice a vértice do
objeto, a aplicação uma a uma de cada transformação
básica para compor um movimento complexo causaria
movimentos não realistas e seria muito custoso em termos
de performance.
• Por isso é importante que múltiplas transformações possam
ser “concatenadas”, ou combinadas de forma a definir um
movimento mais complexo numa única operação a ser
aplicada sobre os vértices.
• Duas transformações combinadas então devem produzir
uma única transformação que tem o mesmo efeito que a
aplicação seqüencial das duas transformações originais.
• Assim, se T é uma transformação de translação e R uma
transformação de rotação, pela propriedade da
concatenação C = TR é uma transformação que produz o
efeito combinado das duas transformações originais –
translação e rotação.
Dica
• Se você não conhece ou não lembra os
conceitos básicos de matrizes (soma,
multiplicação, transposição, matriz
identidade, etc) procure estuda-los para
aproveitar melhor esse capítulo do curso.
Transformação de Translação
(Translation)
• Pontos do Plano XY podem ser deslocados
(transladados) para novas posições através da
adição de um deslocamento às coordenadas
desses pontos.
• Considerando um vetor de deslocamento
d=(dx,dy), consideramos que dx representa um
deslocamento paralelo ao eixo X e dy um
deslocamento paralelo ao eixo Y.
• Assim, para um ponto p=(x,y), a translação
definirá uma nova posição p’=(x’,y’)=(x,y) +
(dx,dy) = (x+dx,y+dy).
• Em notação matricial: P=(x y), T=(dx dy) e
P’=P+T
Exemplo de translação
dx=150,dy=50
Transformação de Escala (Scale)
• Pontos podem ser submetidos a transformação
de escala segundo os valores sx e sy (fatores de
escala) que significam compressão (se 0<s<1)
ou estiramento (se s>1) segundo as direções
dos eixos X e Y respectivamente.
• Para o ponto p=(x,y) sua nova posição pode ser
obtida pela multiplicação de seus valores,
segundo as seguintes equações:
– x’=x*sx e
y’=y* sy
Transformação de Escala (Scale)
• Vamos considerar um ponto P(x y) como sendo
uma Matriz [1x2]. Se multiplicarmos por uma
Matriz [2x2], obteremos uma outra Matriz,
também [1x2], que podemos interpretar como
sendo um outro ponto:
 x'
• Se
y '   x
 sx 0 

S  
 0 sy 
 sx 0 

y .
 0 sy 
então P’=P.S e (x’,y’)=(x.Sx, y.Sy)
Transformação de Escala (Scale)
• exemplos de escala para o polígono do exemplo anterior:
•a esquerda: (sx=1 sy=0.5), a direita: (sx=1, sy=2)
Transformação de Escala (Scale)
• Note-se que a operação de escala é relativa à origem do sistema de
coordenadas.
• O polígono torna-se menor e mais próximo dos eixos quando o fator
de escala é menor que 1.0.
• Se os fatores de escala forem maiores que 1.0, o polígono será
maior e mais afastado dos eixos.
• Para evitar esse efeito de afastamento/aproximação deve-se
primeiro fazer uma translação do objeto para a origem do sistema
de coordenada, seguida da escala, seguida da translação oposta
para que volte à posição original.
• Note que as proporções do polígono também mudaram devido às
escalas diferenciadas.
• Temos uma escala diferenciada quando sx  sy e uma escala
uniforme quando sx = sy.
• Numa escala uniforme as proporções não são afetadas pela
transformação.
Transformação de Rotação
(Rotation)
• Pontos podem sofrer rotação de um ângulo 
(phi) relativa à origem.
• A rotação 2D, no sentido anti-horário, é
definida matematicamente como:
x'  x. cos( )  y. sin( )
y '  x. sin( )  y. cos( )
• Na forma matricial: ( x' y' )  ( x
 cos( ) sin( ) 

y).
  sin( ) cos( ) 
 cos( ) sin( ) 
• Se R  
 então P’=P.R
  sin( ) cos( ) 
Transformação de Rotação
(Rotation)
• Ângulos positivos são medidos no sentido anti-horário, de X para Y
e sentido horário para ângulos negativos.
• As equações que definem matematicamente a rotação são melhor
entendidas se aplicarmos os princípios da Trigonometria a partir da
ilustração da fig. abaixo:
X=L.cos() e y= L.sin()
x’=L.cos(+) = L.cos()cos()-L.sin()sin() =
x. cos()-y. sin()
y’=L.sin(+) = L.sin()cos()+L.cos()sin() =
x. sin()+y. cos()
Transformação de Rotação
(Rotation)
• Exemplo de rotação do polígono anterior com
=30°:
Transformação de Rotação
(Rotation)
• Note-se novamente que a rotação ocorre
relativa à origem do sistema de
coordenadas e não em torno de sí mesmo
• Para obter uma rotação em torno de sí
mesmo deve-se primeiro fazer uma
translação do objeto para a origem do
sistema de coordenada, seguida da
rotação, seguida da translação oposta
para que volte à posição original.
Coordenadas Homogêneas
• A representação matricial para translação,
escala e rotação é, respectivamente:
– P’=P+T, P’=P.S e P’=P.R
• Infelizmente, segundo essas equações, a
translação é tratada diferentemente (como uma
adição) em comparação com a escala e a
rotação (multiplicações).
• Seria importante podermos tratar todas as três
transformações de forma uniforme ou
homogênea e assim poder facilmente combinálas (concatená-las). Veremos agora como fazer
isso.
Coordenadas Homogêneas
• Se expressarmos os pontos em Coordenadas
Homogêneas, as três transformações poderão ser
tratadas como multiplicações matriciais.
• Coordenadas homogêneas foram desenvolvidas na
Geometria e posteriormente aplicadas na Computação
Gráfica.
• Em coordenadas homogêneas, um ponto P (x, y) é
representado como P (w.x, w.y, w) para qualquer fator de
escala w  0.
• Assim, dado um Ponto P (x, y, w) em Coordenadas
Homogêneas podemos obter sua representação em
coordenadas cartesianas 2D efetuando o seguinte
cálculo:
x=x/w
e
y=y/w
Coordenadas Homogêneas
• No espaço Bi-Dimensional , w será adotado como igual a
1 e portanto não executaremos as divisões.
• Neste caso, o uso das coordenadas homogêneas tem
somente o objetivo de permitir a combinação das três
transformações geométricas básicas.
• Em coordenadas homogêneas a representação matricial
da transformação de Translação é:
( x'
y ' 1)  ( x
 1 0 0


y 1). 0 1 0 
 dx dy 1 


– A matriz da direita é chamada de “matriz de transformação”
Coordenadas Homogêneas
• De forma semelhante, a representação
matricial da transformação de Escala é:
( x'
y ' 1)  ( x
 Sx 0 0 


y 1). 0 Sy 0 
 0 0 1


• Finalmente, a representação matricial da
transformação de Rotação é:
( x'
y ' 1)  ( x
 cos( ) sin( ) 0 


y 1).  sin( ) cos( ) 0 
 0
0
1 

Coordenadas Homogêneas
• Como exemplo do uso de coordenadas homogêneas, vamos
imaginar o que acontece se um ponto P é transladado por T1 com
deslocamento (dx1 , dy1) para P’ e então transladado por T2 com
deslocamento (dx2 , dy2) para P’’.
• Intuitivamente podemos esperar que o resultado seja uma
translação composta e igual a (dx1 + dx2, dy1 + dy2).
• Então vejamos: P’=P. T1 e P’’=P’. T2 , logo P’’=(P. T1). T2 , ou seja
P’’=P. T1. T2 , ou:
( x' '
y ' ' 1)  ( x
0 0
 1 0 0  1



y 1). 0 1 0  . 0
1 0  (x
 dx1 dy1 1   dx 2 dy 2 1 



0
0
 1


y 1). 0
1
0
 dx1  dx 2 dy1  dy 2 1 


• A matriz resultante de T1.T2 é chamado de composição ou
concatenação das duas translações.
Combinação das Transformações
2D
• A idéia básica da composição de transformações reside no fato de
que é mais eficiente aplicar uma única transformação composta a
um ponto do que uma série de transformações simples, uma após a
outra.
• Consideremos o problema da rotação de um objeto em torno de um
ponto arbitrário P1.
• Como somente conhecemos a rotação em torno da origem, vamos
converter nosso problema original (desconhecido) em três
diferentes problemas (já conhecidos).
• Assim, para rotacionar em torno de P1, uma seqüência de três
Transformações Fundamentais serão necessárias.
– (1) – Transladar todo o objeto de forma de forma que P1 seja a nova
origem;
– (2) – Rotacionar todo o objeto e
– (3) – Transladar o objeto todo de volta de forma que a origem volte a
ser a inicial.
Combinação das Transformações
2D
• Considerando que P1 = (x1,y1), a primeira translação é de
(-x1 , -y1) e a última translação é o inverso (x1 , y1).
Combinação das Transformações
2D
Combinação das Transformações
2D
• Um processo semelhante é usado na transformação de Escala de
um Objeto relativa a um Ponto arbitrário P1 (para que esse ponto
não se mova após a operação terminada).
• A sequência é a mesma do exemplo anterior: translação do objeto
de forma que P1 esteja na origem, escala, translação do objeto para
que P1 volte à sua posição original.
• A Composição dessas Transformações é:
Combinação das Transformações
2D
• Esta Composição de transformações, aqui demonstrada,
será continuamente utilizada em nossas operações de
visualização 2D e 3D.
• Devemos observar que normalmente a escolha de P1 centro de rotação e de escala - não é arbitrária, mas
convenientemente adotada como sendo o centro
geométrico (ou de gravidade) do objeto.
• Desta forma, garantimos que as operações relacionadas
com a origem do sistema de coordenadas (rotação e
escala) não produzirão deslocamentos ou distorções
indesejáveis nas imagens transformadas.
Exercício
• Para a figura abaixo, calcule a posição
dos vértices após uma rotação de 90 em
torno do ponto p2.
y
p4=(3.5,5)
p1=(2,3)
p2=(5,3)
p3=(3.5,1)
x
Transformações em 3D
• A extensão de 2D para 3D é imediata nos
casos de translação e escala:
– Translação:
 x'
y ' z ' w'  x
y
1 0 0

0 1 0
z w.
0 0 1

 dx dy dz

– Escala
 x'
y ' z ' w'  x
y
0

0
0

1 
 Sx 0 0 0 


 0 Sy 0 0 
z w.
0 0 Sz 0 


 0 0 0 1


Transformações em 3D
• No caso da rotação é um pouco mais
complicado.
• Um rotação 2D ocorre sempre em torno do eixo
que “sai” do plano (z).
• Já uma rotação 3D pode ocorrer em torno de
qualquer eixo.
• As rotações básicas, em torno dos eixos x,y e z
do sistema de coordenadas do objeto, são
chamadas de roll (em torno de x), pitch (em
torno de z) e yaw (em torno de y)
Transformações em 3D
• A notação mais usada para definir uma
rotação, usada pelo OpenGL e pelo Chai,
é definida por um vetor 3D representando
o eixo de rotação e um escalar
representando o ângulo de rotação:
– glRotate*(a,x,y,z)
Transformações em 3D
• A matriz de transformação no caso das
rotações básicas seriam então definidas
por:
0
0
0
1


 0 cos a sin a 0 
glRotate* a, 1, 0, 0 : 
0  sin a cos a 0 


0
0
0
1   cos a


 0
glRotate* a, 0, 1, 0 : 
sin a

 0
 cos a sin a 0 0  


  sin a cos a 0 0 
glRotate* a, 0, 0, 1 : 
0
0
1 0


 0
0
0 1 

0  sin a
1
0
0 cos a
0
0
0

0
0

1 
Transformações em 3D
• Para uma rotação em torno de um eixo qualquer
(x,y,z) para um ângulo a a matriz de rotação é
definida da seguinte forma:
– v=(x,y,z)T
– u=v/||v||=(x’,y’,z’)T
( ||v|| =
x2  y2  z 2 )
 0  z' y' 


S   z'
0  x' 
  y ' x'

0


– e M=uuT + (cos a)(I-uuT)+(sin a) S (I é a matriz
identidade)
–
Transformações em 3D
• A matriz de transformação será definida
por:
 m m m 0


 m m m 0
 m m m 0


 0 0 0 1


• onde m representa os elementos da matriz
de rotação M
Transformações no SAI
• Na classe cGenericObject as transformações são obtidas usando os
seguintes métodos:
//! Translate this object by a specified offset
void translate(const cVector3d& a_translation);
//! Translate this object by a specified offset
void translate(const double a_x, const double a_y,
const double a_z);
//! Rotate this object by multiplying with a specified
rotation matrix
void rotate(const cMatrix3d& a_rotation);
//! Rotate this object around axis a_axis by angle
a_angle (radians)
void rotate(const cVector3d& a_axis, const double
a_angle);
Transformações no SAI
• Note que a rotação pode ser definida pela
matriz de rotação ou pelo formato OpenGL com
um eixo de rotação e um ângulo.
• As transformações no Chai ocorrem com
relação à origem e orientação do sistema de
coordenadas local.
• Não é possível concatenar transformações no
Chai. Cada transformação pedida é realizada
isoladamente, o que impede a mudança do
centro da rotação por exemplo.
• Mudança de escala ainda não foi implementada
no Chai.
Transformações no SAI
• A hierarquia de objetos tem um papel
importante no resultado das
transformações pois a origem e a
orientação do sistema de coordenadas
local de um objeto é definido pelo objeto
pai (se for o objeto raiz será com relação à
origem da cena).
• Veremos isso em detalhe na aula 5.
Exercícios
1) Adicione teclas aos projeto anterior do cubo de forma
que seja possível mover e rotacionar o cubo em torno
dos eixos principais usando as transformações nativas
do Chai.
2) Adapte o cubo gerado de forma que ele não esteja
definido em torno da origem e sim a uma distância de
0.5 da origem. Teste as teclas de rotação nessa
configuração.
3) Reimplemente as operações de movimento do objeto
calculando a matriz de transformação. Nessa
implementação faça com que a rotação do objeto seja
em torno de um ponto arbitrário definido como
parâmetro.
4) Implemente um cubo que orbita continuamente em torno
do centro e em torno de sí mesmo ao mesmo tempo.
Implementando rotações e
translações diretamente
• No projeto aula3.bpr são propostas 4
rotinas que implementam rotações e
translações manipulando matrizes de
transformação (ao invés de simplesmente
chamar os métodos translate e rotate do
Chai).
• Essas rotinas ilustram os conceitos
apresentados nessa aula e dão mais
flexibilidade às transformações rígidas.
Implementando rotações e
translações diretamente
• A rotina “roda” implementa a rotação de um objeto
passado como parâmetro.
• A rotação é feita em torno de um centro de rotação
(centroRot) seguindo um eixo de rotação (eixo) e com
um certo ângulo (ângulo).
• O centro de rotação pode ser uma posição absoluta
(nesse caso deve-se usar recalCentro=false) ou uma
posição definida no sistema de coordenadas do próprio
objeto (nesse caso deve-se usar recalCentro=true para
que a posição global do centro seja recalculada).
void roda(cMesh *obj,cVector3d centroRot,
cVector3d eixo, double angulo, bool
recalCentro);
Implementando rotações e
translações diretamente
• As rotinas “rotacao”, “translacao” e “multiplica” são
subrotinas usadas para implementar “roda”.
• Note que “roda” lê a matriz de transformação atual do
objeto através de obj->getPos() e obj->getRot() que
fornecem respectivamente os dados de translação e
rotação.
• Em seguida essa matriz é manipulada através dos
métodos da classe cMatrixGL.
• No final de “roda” a matriz de transformação
recalculada é colocada de volta no objeto usando:
obj->setRot(matriz.getRot());
obj->setPos(matriz.getPos());