Search code examples
c++openglglutcoordinate-transformationopengl-compat

Rotate object like a real wind turbine


#include <stdio.h>
#include <math.h>
#include "glut.h"

void init() {
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glMatrixMode(GL_PROJECTION);
    gluOrtho2D(0.0, 400, 0.0, 300.0);
}

void drawTurbine() {
    // draw the tower
    glBegin(GL_LINES);
    glColor3f(1.0, 1.0, 1.0);
    glVertex2f(160, 40);
    glVertex2f(163, 180);
    glVertex2f(160, 40);
    glVertex2f(175, 40); 
    glVertex2f(175, 40);
    glVertex2f(172, 180);
    glEnd();
    // Rotate object
    glPushMatrix();
    glRotatef(100, 0, 1, 0);
    // draw first rotor blade
    glBegin(GL_TRIANGLES);
    glColor3f(1.0, 1.0, 1.0);
    glVertex2f(173, 180);
    glVertex2f(163, 180);
    glVertex2f(168, 270);
    glEnd();
    // draw second rotor blade
    glBegin(GL_TRIANGLES);
    glColor3f(1.0, 1.0, 1.0);
    glVertex2f(170, 174);
    glVertex2f(175, 180);
    glVertex2f(247, 140);
    glEnd();
    // draw third rotor blade
    glBegin(GL_TRIANGLES);
    glColor3f(1.0, 1.0, 1.0);
    glVertex2f(162, 180);
    glVertex2f(167, 174);
    glVertex2f(88, 140);
    glEnd();
    // circle in the middle
    float theta;
    glBegin(GL_POLYGON);
    glColor3f(1.0, 1.0, 1.0);
    for (int i = 0; i <= 360; i++) {
           theta = i * 3.142 / 180;
           glVertex2f(168 + 7 * cos(theta), 180 + 6.5 * sin(theta));
    }
    glEnd();
    glPopMatrix();
}

void display() {
    glClear(GL_COLOR_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    drawTurbine();
    glFlush();
    glutSwapBuffers();
    glutPostRedisplay();
}

void idle() {
    display();
}

int main(int argc, char** argv) {
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(700, 600);
    glutInitWindowPosition(10, 10); 
    glutCreateWindow("Wind Turbine");
    init(); 
    glutIdleFunc(idle);
    glutDisplayFunc(display);
    glutMainLoop();
    return 0;
}

I have created a wind turbine and I am trying to rotate the rotor blades, but the code just makes it disappear. I want it to rotate clockwise. I just need an idea on how I can make it rotate like a real wind turbine. I am new to using glRotatef, and this will be my first time rotating an object with OpenGL.


Solution

  • You need a variable for the current angle of the wind turbine (current_angle) and the rotation angle per frame (step_angle). Further you have to know the center of the wind turbine (center_x, center_y):

    float current_angle = 0.0f;
    float step_angle = 0.2f;
    float center_x = 168.0f;
    float center_y = 180.0f;
    

    To rotate around a pivot you have to define a model matrix, which displace by the inverted pivot, then rotates and final transforms back by to the pivot. The rotation axis is the z axis (0, 0, 1) because your geometry is drawn in the xy-plane:

    glTranslatef( center_x, center_y, 0.0f );
    glRotatef(current_angle, 0, 0, 1);
    current_angle += step_angle;
    glTranslatef(-center_x, -center_y, 0.0f );
    

    Preview:

    Complete code of the function drawTurbine:

    void drawTurbine() {
        // draw the tower
        glBegin(GL_LINES);
        glColor3f(1.0, 1.0, 1.0);
        glVertex2f(160, 40);
        glVertex2f(163, 180);
        glVertex2f(160, 40);
        glVertex2f(175, 40); 
        glVertex2f(175, 40);
        glVertex2f(172, 180);
        glEnd();
        // Rotate object
        glPushMatrix();
    
        glTranslatef( center_x, center_y, 0.0f );
        glRotatef(current_angle, 0, 0, 1);
        current_angle += step_angle;
        glTranslatef(-center_x, -center_y, 0.0f );
    
        // draw first rotor blade
        glBegin(GL_TRIANGLES);
        glColor3f(1.0, 1.0, 1.0);
        glVertex2f(173, 180);
        glVertex2f(163, 180);
        glVertex2f(168, 270);
        glEnd();
        // draw second rotor blade
        glBegin(GL_TRIANGLES);
        glColor3f(1.0, 1.0, 1.0);
        glVertex2f(170, 174);
        glVertex2f(175, 180);
        glVertex2f(247, 140);
        glEnd();
        // draw third rotor blade
        glBegin(GL_TRIANGLES);
        glColor3f(1.0, 1.0, 1.0);
        glVertex2f(162, 180);
        glVertex2f(167, 174);
        glVertex2f(88, 140);
        glEnd();
        // circle in the middle
        float theta;
        glBegin(GL_POLYGON);
        glColor3f(1.0, 1.0, 1.0);
        for (int i = 0; i <= 360; i++) {
               theta = i * 3.142 / 180;
               glVertex2f(168 + 7 * cos(theta), 180 + 6.5 * sin(theta));
        }
        glEnd();
        glPopMatrix();
    }