c++animationopenglglut

rotate and moving circle


I draw a circle with a + sign inside it to see it rotate

void drawcircle(float radius, float x, float y){
    float R = radius; // Radius of circle.
    float X = x; // X-coordinate of center of circle.
    float Y = y; // Y-coordinate of center of circle.
    int numVertices = 25; // Number of vertices on circle.
    float t = 0; // Angle parameter.
    int i;


    glColor3f(1.0, 1.0, 1.0);
    glPolygonMode( GL_FRONT, GL_FILL );
    glBegin(GL_POLYGON);
    for(int i = 0; i < numVertices; ++i)
    {
        glVertex3f(X + R * cos(t), Y + R * sin(t), 0.0);
        t += 2 * PI / numVertices;
    }
    glEnd();

}

and in my display function I want to move it along the same path like a cars tyre and rotate it 30 degrees every time and towards the right of the screen like

glPushMatrix();
    glTranslatef(circle1_x, 0, 0.0f);
    glRotatef(30, 0.0f, 0.0f, 1.0f);
    glTranslatef(-circle1_x, 0, 0.0f);
    drawcircle(20, circle1_x, 350.0);
glPopMatrix();

I translate it to a position and then rotate it and then translate it back to the same position but it comes off like as if moved only once and keeps moving across. I use the idle function and the glutIdleFunc(idle); to move the circle towards the right and reset it to the first position end of the screen.

How can I make it so that the circle can move and both rotate at the same time


Solution

  • A transformation matrix can be constructed as follows:

    M = T * C * R * -C
    
    //or with scale
    
    M = T * C * R * SR * S * -SR * -C
    

    where

    T: position of the object (translation)
    C: center of rotation (translation)
    R: rotation
    SR: scale orientation (rotation)
    S: scale

    In order to translate and rotate an object at the same time:

    //set the position
    glTranslatef(x, y, z);
    //set the center of rotation (pivot point of the circle)
    glTranslatef(dx, dy, dz);
    //rotate around pivot point
    glRotatef(rad, ax, ay, az);
    //restore position
    glTranslatef(-dx, -dy, -dz);
    

    If you would construct your circle around the origin (0,0), like

    glVertex3f(radius_x * cos(rad), radius_y * sin(rad), z);
    

    then you could omit unnecessary matrix multiplications and the above transformation would look like this:

    //set the position (center of circle)
    glTranslatef(x, y, z);
    //rotate around center
    glRotatef(rad, ax, ay, az);
    

    Note: don't forget to set the proper matrix mode (it is not obvious in the presented code above)

    glMatrixMode(GL_MODELVIEW);