Capítulo 4. Transformações geométricas – cubos4
- Índice
- 4.1. Descrição
do programa cubos4.c- 4.2. Transformações geométricas – braço robótico
- 4.3. Outros programas relacionados
- 4.4. Exercícios
- 4.1. Descrição
O propósito desta lição é compreender como as transformações geométricas são
realizadas sobre os objetos em relação a um determinado sistema de coordenadas.
No OpenGL existem funções para realizar translação, rotação e escalamento,
bastando apenas ao usuário ajustar os seus parâmetros para obter o efeito
desejado. Será analisado um programa simples composto de 4 cubos dispostos em uma janela conforme ilustra a Figura
4-1
O programa que implementa os 4 cubos é mostrado no Exemplo
4-1. Para finalizar o programa, basta digitar ESC. As teclas e
suas respectivas ações estão definidas na função keyboard().
Exemplo 4-1. programa cubos4.c
#include <GL/glut.h> #include <stdlib.h> void init(void){ glClearColor (0.0, 0.0, 0.0, 0.0); } void display(void){ glClear (GL_COLOR_BUFFER_BIT); glPushMatrix(); /* Cubo 1 */ glPushMatrix(); glTranslatef (-2.0, 0.0, 0.0); glScalef (3.0, 2.0, 5.0); glutWireCube (1.0); glPopMatrix(); /* Cubo 2 */ glPushMatrix(); glRotatef (25.0, 0.0, 0.0, 1.0); glTranslatef (2.0, 0.0, 0.0); glScalef (2.0, 1.0, 4.0); glutWireCube (1.0); glPopMatrix(); /* Cubo 3 */ glPushMatrix(); glTranslatef (0.0, 2.0, 0.0); glScalef (2.0, 1.0, 4.0); glutWireCube (1.0); glPopMatrix(); /* Cubo 4 */ glPushMatrix(); glTranslatef (0.0, -2.0, 0.0); glScalef (2.0, 1.0, 4.0); glutWireCube (1.0); glPopMatrix(); glPopMatrix(); glutSwapBuffers(); } void reshape (int w, int h){ glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective(65.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef (0.0, 0.0, -10.0); } void keyboard(unsigned char key, int x, int y){ switch (key) { case 27: // tecla Esc (encerra o programa) exit(0); break; } } int main(int argc, char** argv){ glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); init (); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; } |
Para compilar e executar o programa cubos4.c, salve-o juntamente com o
arquivo Makefile em um diretório e execute a seguinte seqüência de
comandos:
$ make cubos4
$ ./cubos4
|
4.1. Descrição do programa cubos4.c
void init(void){ glClearColor (0.0, 0.0, 0.0, 0.0); } |
Especifica as intensidade de vermelho (RED), verde (GREEN) e azul (BLUE) utilizadas para limpar a janela. Neste caso, a janela terá cor de fundo preta. O último
parâmetro é o canal alfa, utilizado para tratar com transparências.
void display(void) { glClear (GL_COLOR_BUFFER_BIT); glPushMatrix(); |
Uma vez que as transformações geométricas no espaço são representadas por
matrizes, o uso de uma pilha de matrizes de transformação ajuda a lembrar a
seqüência de transformações realizadas. No OpenGL, esta facilidade é provida
pelas funções glPushMatrix(), que insere a matriz de
transformação corrente na pilha, e glPopMatrix(), que
retira a matriz do topo da pilha e torna esta última a matriz de transformação
corrente. Neste exemplo, a função glPushMatrix() serve
para lembrar os parâmetros de translação, rotação e escalamento no início das
operações de desenho.
/* Cubo 1 */ glPushMatrix(); glTranslatef (-2.0, 0.0, 0.0); glScalef (3.0, 2.0, 5.0); glutWireCube (1.0); glPopMatrix(); |
O conjunto de transformações sobre o primeiro cubo a ser desenhado é delimitado pelo
glPushMatrix() e glPopMatrix().
A origem do sistema de coordenadas é levado para o ponto (x,y,z)=(-2.0,0.0,0.0)
através da função glTranslatef(), definindo a coordenada
de origem (pivô) para o desenho do cubo. Em seguida, usando a função glScalef(), o sistema de coordenadas é ampliado em (Sx,Sy,Sz)=(3.0,2.0,5.0),
e, finalmente, desenhado um cubo aramado através de glutWireCube().
/* Cubo 2 */ glPushMatrix(); glRotatef (25.0, 0.0, 0.0, 1.0); glTranslatef (2.0, 0.0, 0.0); glScalef (2.0, 1.0, 4.0); glutWireCube (1.0); glPopMatrix(); |
A função glRotatef() possui o seguinte protótipo:
void glRotatef
(GLfloat angle, GLfloat x,
GLfloat y, GLfloat z);
Quando chamada, glRotatef() efetua uma rotação de angle graus no sistema de coordenadas na direção
contra o sentido do relógio em torno de um vetor que vai da origem ao ponto
(x,y,z)
Observe que os cubos 3 e 4 não são também rotacionados mesmo estando após o uso da função glRotatef()
sobre o cubo 2, em função da delimitação da pilha de execução delimitada por glPushMatrix() e
glPopMatrix().
/* Cubo 3 */ glPushMatrix(); glTranslatef (0.0, 2.0, 0.0); glScalef (2.0, 1.0, 4.0); glutWireCube (1.0); glPopMatrix(); |
/* Cubo 4 */ glPushMatrix(); glTranslatef (0.0, -2.0, 0.0); glScalef (2.0, 1.0, 4.0); glutWireCube (1.0); glPopMatrix(); |
Os outros dois cubos são desenhados, segundo às mesmas orientações dadas acima.
glPopMatrix(); glutSwapBuffers(); |
A função glPopMatrix() remove a matriz de
transformação do topo da pilha, fazendo-a corrente, retornando assim o sistema
de coordenadas original. Quando glutSwapBuffers() é
chamada, os buffers de desenho e de apresentação são alternados e a nova imagem
dos cubos é apresentada.
void reshape (int w, int h) { glViewport (0, 0, (GLsizei) w, (GLsizei) h); |
Define a área dentro da janela de desenho no sistema de coordenadas atual,
origem (x,y), largura (w) e altura (h), que OpenGL pode utilizar para efetuar
desenhos. Este trecho de código permite que toda a área da janela possa ser
utilizada quando a janela sofrer redimensionamento.
glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective(65.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0); |
A função glMatrixMode() especifica a pilha de
matrizes que será o alvo das operações matriciais subseqüentes; neste caso, a
pilha de matrizes de projeção. A função glLoadIdentity()
inicia a matriz de projeção corrente como a matriz identidade. A função gluPerspective() define a transformação de perspectiva usada
no exemplo. Projeções geométricas não são alvo desta lição e por enquanto não
serão estudadas.
glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef (0.0, 0.0, -10.0); |
A função glMatrixMode() especifica agora que a pilha
de matrizes de modelview, usadas para definir
translação, rotação e escalamento, será o alvo das transformações subseqüentes.
A função glLoadIdentity() inicia a matriz de modelview corrente como a matriz identidade. Finalmente,
o objeto é deslocado em -10 unidades para o fundo da tela, melhorando a sua
visualização.
glutReshapeFunc(reshape); |
Especifica a função de retorno para redimensionamento de janela, possuindo o
seguinte protótipo:
funcao
(int width, int height);