Ir ao conteúdo

C Rotacionar, transladar e escalar um objeto no OpenGL


Ir à solução Resolvido por V!OLADOR,

Posts recomendados

Postado

Preciso determinar a sequência de operações em OpenGL que fazem com que o polígono vermelho seja desenhada na posição do polígono azul.

 

#include <GL/glut.h>
 
void init() {
    glClearColor(0.0, 0.0, 0.0, 0.0);
    gluOrtho2D(0.0, 6.0, 0.0, 6.0);
}
 
void display() {
    glClear(GL_COLOR_BUFFER_BIT);
 
    glLineWidth(2.0);
    
    glBegin(GL_LINES);
        glColor3f(1.0, 0.0, 0.0); // poligono vermelho
        glVertex2f(3.0, 4.0);   
        glVertex2f(4.0, 5.0);   
        glVertex2f(4.0, 5.0);  
        glVertex2f(5.0, 4.0);  
        glVertex2f(5.0, 4.0);   
        glVertex2f(4.0, 3.0);  
        glVertex2f(4.0, 3.0);   
        glVertex2f(3.0, 4.0);   
        
        glColor3f(0.0, 0.0, 1.0); // poligono azul
        glVertex2f(3.0, 5.0);   
        glVertex2f(5.0, 5.0);   
        glVertex2f(5.0, 5.0);   
        glVertex2f(5.0, 3.0);  
        glVertex2f(5.0, 3.0);   
        glVertex2f(3.0, 3.0);   
        glVertex2f(3.0, 3.0); 
        glVertex2f(3.0, 5.0);   
    glEnd();
    glFlush();
}
 
int main(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(500, 500);
    glutCreateWindow("poligonos");
    init();
    glutDisplayFunc(display);
    glutMainLoop();
    return 0;
}

 

poly.png

  • Curtir 1
Postado

Para desenhar o polígono vermelho na posição do polígono azul, você precisa aplicar uma matriz de transformação que realize uma translação e uma rotação. A translação é necessária para mover o centro do polígono vermelho para o centro do polígono azul, que é (4,4). A rotação é necessária para girar o polígono vermelho em 45 graus no sentido anti-horário em torno do centro (4,4).

Uma forma de fazer isso é usar as funções glTranslatef e glRotatef do OpenGL, que modificam a matriz GL_MODELVIEW. Essas funções multiplicam a matriz atual pelo resultado da transformação especificada. Você pode usar a seguinte sequência de operações no seu código, antes de desenhar o polígono vermelho:

Citação

glPushMatrix(); // salva a matriz atual na pilha

glLoadIdentity(); // carrega a matriz identidade

glTranslatef(4.0, 4.0, 0.0); // translada o sistema de coordenadas para o centro do polígono azul

glRotatef(45.0, 0.0, 0.0, 1.0); // rotaciona o sistema de coordenadas em 45 graus no eixo z

glTranslatef(-4.0, -4.0, 0.0); // translada o sistema de coordenadas de volta para a origem

// desenha o polígono vermelho aqui

glPopMatrix(); // restaura a matriz anterior da pilha

Essa matriz é o resultado da multiplicação das matrizes de translação e rotação, na ordem inversa. Você pode verificar isso usando uma calculadora de matrizes online.

 

 

 

Se você quiser saber mais sobre como as matrizes de transformação funcionam em OpenGL, você pode consultar os seguintes recursos:

LearnOpenGL - Transformations: um tutorial que explica os conceitos básicos de transformações em OpenGL, incluindo matrizes de modelo, visão e projeção.

OpenGL Transformation - Song Ho: um artigo que mostra como construir e usar as matrizes de transformação em OpenGL, com exemplos de código e ilustrações.

Porting Matrix and Transformation Functions - Win32 apps: um guia que compara as funções de transformação do OpenGL com as do Direct3D, destacando as diferenças e semelhanças.

OpenGL Transformations OpenGL Matrices - cs.kent.edu: uma apresentação em PDF que resume os principais aspectos das transformações em OpenGL, com fórmulas e diagramas.

  • Curtir 1
  • Amei 1
Postado

@Otávio Amorim Assim? A saída foi apenas o polígono azul.

void display() {
    glClear(GL_COLOR_BUFFER_BIT);
 
    glLineWidth(2.0);
    
    glPushMatrix(); // salva a matriz atual na pilha

	glLoadIdentity(); // carrega a matriz identidade

	glTranslatef(4.0, 4.0, 0.0); // translada o sistema de coordenadas para o centro do polígono azul
	glRotatef(45.0, 0.0, 0.0, 1.0); // rotaciona o sistema de coordenadas em 45 graus no eixo z
	glTranslatef(-4.0, -4.0, 0.0); // translada o sistema de coordenadas de volta para a origem

	glBegin(GL_LINES);
        glColor3f(1.0, 0.0, 0.0); // poligono vermelho
        glVertex2f(3.0, 4.0);   
        glVertex2f(4.0, 5.0);   
        glVertex2f(4.0, 5.0);  
        glVertex2f(5.0, 4.0);  
        glVertex2f(5.0, 4.0);   
        glVertex2f(4.0, 3.0);  
        glVertex2f(4.0, 3.0);   
        glVertex2f(3.0, 4.0);
	glEnd();

	glPopMatrix(); // restaura a matriz anterior da pilha
	 
	glBegin(GL_LINES);        
        glColor3f(0.0, 0.0, 1.0); // poligono azul
        glVertex2f(3.0, 5.0);   
        glVertex2f(5.0, 5.0);   
        glVertex2f(5.0, 5.0);   
        glVertex2f(5.0, 3.0);  
        glVertex2f(5.0, 3.0);   
        glVertex2f(3.0, 3.0);   
        glVertex2f(3.0, 3.0); 
        glVertex2f(3.0, 5.0);   
    glEnd();
    glFlush();
}
 

 

  • Curtir 1
Postado

@Otávio Amorim  Eu fiz assim, mas acho que não foi a abordagem correta, na saída o polígono aparece fora de posição.

// Centra as coordenadas do polígono vermelho em (0,0)
float centerX = (3.0 + 4.0 + 4.0 + 5.0) / 4.0;
float centerY = (4.0 + 5.0 + 5.0 + 4.0) / 4.0;


glTranslatef(-centerX, -centerY, 0.0); // Translada para centralizar o polígono vermelho

glTranslatef(4.0, 4.0, 0.0); // Translada o sistema de coordenadas para o centro do polígono azul
glRotatef(45.0, 0.0, 0.0, 1.0); // Rotaciona o sistema de coordenadas em 45 graus no eixo z
glTranslatef(-4.0, -4.0, 0.0); // Translada o sistema de coordenadas de volta para a origem

 

saida.png

  • Curtir 1
Postado
4 horas atrás, Beatriz Yakamura disse:

@Otávio Amorim  Eu fiz assim, mas acho que não foi a abordagem correta, na saída o polígono aparece fora de posição.

// Centra as coordenadas do polígono vermelho em (0,0)
float centerX = (3.0 + 4.0 + 4.0 + 5.0) / 4.0;
float centerY = (4.0 + 5.0 + 5.0 + 4.0) / 4.0;


glTranslatef(-centerX, -centerY, 0.0); // Translada para centralizar o polígono vermelho

glTranslatef(4.0, 4.0, 0.0); // Translada o sistema de coordenadas para o centro do polígono azul
glRotatef(45.0, 0.0, 0.0, 1.0); // Rotaciona o sistema de coordenadas em 45 graus no eixo z
glTranslatef(-4.0, -4.0, 0.0); // Translada o sistema de coordenadas de volta para a origem

 

saida.png

 

 

 

 

Tenta ajustar a sequência de operações para que a translação para centralizar o polígono vermelho seja aplicada primeiro

  1. glPushMatrix(); // salva a matriz atual na pilha
  2. glTranslatef(-centerX, -centerY, 0.0); // Translada para centralizar o polígono vermelho
  3. glTranslatef(4.0, 4.0, 0.0); // Translada o sistema de coordenadas para o centro do polígono azul
  4. glRotatef(45.0, 0.0, 0.0, 1.0); // Rotaciona o sistema de coordenadas em 45 graus no eixo z
  5. glTranslatef(-4.0, -4.0, 0.0); // Translada o sistema de coordenadas de volta para a origem
  6. // desenha o polígono vermelho aqui

glPopMatrix(); // restaura a matriz anterior da pilha

 

Os códigos estão meio confusos porque não sei anexar códigos aqui 

  • Curtir 1
  • Solução
Postado
Em 07/12/2023 às 12:07, Beatriz Yakamura disse:
glTranslatef(-centerX, -centerY, 0.0); // Translada para centralizar o polígono vermelho

glTranslatef(4.0, 4.0, 0.0); // Translada o sistema de coordenadas para o centro do polígono azul
glRotatef(45.0, 0.0, 0.0, 1.0); // Rotaciona o sistema de coordenadas em 45 graus no eixo z
glTranslatef(-4.0, -4.0, 0.0); // Translada o sistema de coordenadas de volta para a origem

 

Bom, mas esta parte não tá claramente errada? O que eu tô lendo ai acima: transladamos o objeto pro ponto (-centerX, -centerY), em seguida transladamos novamente pra posição inicial (4, 4), aplicamos uma rotação e então transladamos novamente pra posição aleatória (-4, -4).

 

De qualquer maneira, assumindo que o polígono já esteja inicialmente centrado na posição (4, 4), pelos valores dos próprios vértices, faça uma translação pra origem do sistema de coordenadas, ou seja (0, 0), aplique a rotação ali e translada o objeto novamente pra posição inicial (4, 4). Talvez funcione.

  • Amei 1
Postado

@V!OLADOR Funcionou, depois só precisei aplicar o scaling para que o polígono vermelho ficasse do tamanho do polígono azul. Obrigada!

 

void display() {
    glClear(GL_COLOR_BUFFER_BIT);
 
    glLineWidth(2.0);

    // Desenhar polígono vermelho
    glPushMatrix();	// Salva a matriz atual na pilha
    
    glTranslatef(4.0, 4.0, 0.0);	// Translada para a posição final desejada
    glRotatef(45.0, 0.0, 0.0, 1.0);	// Rotaciona o sistema de coordenadas em 45 graus no eixo z
    glScalef(1.4, 1.4, 1.4);	// Escala para o mesmo tamanho do polígono azul;
    glTranslatef(-4.0, -4.0, 0.0);	// Translada para a origem (0, 0)
    
    glBegin(GL_LINES);
    	glColor3f(1.0, 0.0, 0.0);
    	glVertex2f(3.0, 4.0);   
    	glVertex2f(4.0, 5.0);   
    	glVertex2f(4.0, 5.0);  
    	glVertex2f(5.0, 4.0);  
   		glVertex2f(5.0, 4.0);   
    	glVertex2f(4.0, 3.0);  
    	glVertex2f(4.0, 3.0);   
    	glVertex2f(3.0, 4.0);
    glEnd();

    glPopMatrix(); // Restaura a matriz anterior da pilha
    
    // Desenhar polígono azul
    glBegin(GL_LINES);        
    	glColor3f(0.0, 0.0, 1.0);
    	glVertex2f(3.0, 5.0);   
    	glVertex2f(5.0, 5.0);   
    	glVertex2f(5.0, 5.0);   
    	glVertex2f(5.0, 3.0);  
    	glVertex2f(5.0, 3.0);   
    	glVertex2f(3.0, 3.0);   
    	glVertex2f(3.0, 3.0); 
    	glVertex2f(3.0, 5.0);   
    glEnd();

    glFlush();
}

 

  • Curtir 1
  • Obrigado 1

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!