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