Search code examples
copenglglutcoordinate-transformationopengl-compat

Maintain the same triangle with respect to its coordinates both at origin and at the user given points to rotate?


I have been working on rotating a triangle about the origin and at the user specified coordinates. The task is to rotate the same triangle (the same dimensions). So far I'm able to do it at the origin. But when its rotated at the user specified coordinates, the triangle's shape is getting increased.

#include<GL/glut.h>
#include<stdio.h>
int x,y;
int where_to_rotate=2;

void draw_pixel(float x1,float y1)
{
    //glColor3f(0.0,0.0,1.0);
    glPointSize(5.0);
    glBegin(GL_POINTS);
        glVertex2f(x1,y1);
    glEnd();
}

void triangle(int x,int y)
{
    glColor3f(1.0,0.0,0.0);
    glBegin(GL_POLYGON); // this is what is bothering me.I have to maintain the same triangle even at user specified coordinates
        glVertex2f(x,y);
        glVertex2f(x+50,0);
        glVertex2f(0,y+50);
    glEnd();
}

float rotate_angle=0.0;
float translate_x=0.0,translate_y=0.0;

void display()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glLoadIdentity();
    glColor3f(1,1,1);
    draw_pixel(0.0,0.0);
    if(where_to_rotate==1) //Rotate Around origin
    {
        translate_x=0.0;
        translate_y=0.0;
        rotate_angle+=.2;
        draw_pixel(0.0,0.0);
    }
    if(where_to_rotate==2) //Rotate Around Fixed Point
    {
        translate_x=x;
        translate_y=y;
        rotate_angle+=.2;
        glColor3f(0.0,0.0,1.0);
        draw_pixel(x,y);
    }
    glTranslatef(translate_x,translate_y,0.0); //works fine for origin
    glRotatef(rotate_angle,0.0,0.0,1.0);
    glTranslatef(-translate_x,-translate_y,0.0);
    triangle(translate_x,translate_y);
    glutPostRedisplay();
    glutSwapBuffers();
}

void myInit()
{
    glClearColor(0.0,0.0,0.0,1.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(-800.0, 800.0, -800.0, 800.0);
    glMatrixMode(GL_MODELVIEW);
}

void rotateMenu (int option)
{
    if(option==1)
        where_to_rotate=1;
    if(option==2)
        where_to_rotate=2;
    if(option==3)
        where_to_rotate=3;
}
int main(int argc, char **argv)
{
    printf( "Enter Fixed Points (x,y) for Rotation: \n");
    scanf("%d %d", &x, &y);
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
    glutInitWindowSize(800, 800);
    glutInitWindowPosition(0, 0);
    glutCreateWindow("Create and Rotate Triangle");
    myInit();
    glutDisplayFunc(display);
    glutCreateMenu(rotateMenu);
    glutAddMenuEntry("Rotate around ORIGIN",1);
    glutAddMenuEntry("Rotate around FIXED POINT",2);
    glutAddMenuEntry("Stop Rotation",3);
    glutAttachMenu(GLUT_RIGHT_BUTTON);
    glutMainLoop();
}

Solution

  • In the function triangle you have to apply the translation to all vertex coordinates:

    glVertex2f(x,y);
    glVertex2f(x+50,y);
    glVertex2f(x,y+50);
    

    Note, it is sufficient to set the model matrix and to specify a static triangle geometry, and glTranslatef(-translate_x,-translate_y,0.0);cancelates the translation which you set by triangle(translate_x,translate_y);


    If you want that the triangle keeps its position and rotates around a fixed point, then you have to do it like this:

    glTranslatef(translate_x, translate_y, 0.0);
    glRotatef(rotate_angle, 0.0, 0.0, 1.0);
    glTranslatef(-translate_x, -translate_y, 0.0);
    triangle(0.0, 0.0);
    


    Explanation:

    • The top operation on the matrix stack transform the triangle in that way, that its origin is the rotation point:

    glTranslatef(-translate_x, -translate_y, 0.0);

    • The 2nd operation rotates the triangle around its current origin

    glRotatef(rotate_angle,0.0,0.0,1.0);

    • Finally the rotated triangle is moved back:

    glTranslatef(translate_x, translate_y, 0.0);


    See also OpenGL translation before and after a rotation