Search code examples
c++openglglut

Take inputs from keyboard and increase/decrease sides of a shape using GLUT


Take inputs from keyboard such as "+" or "-" and increase/decrease sides accordingly. For example if a triangle is currently displayed and if i press "+", it should transform into a rectangle etc. How can I achieve that?

static void DisplayShape(void)
{

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glColor3d(1,0.1,0.6);

    glBegin(GL_POINTS);

    for(int i=0;i<n;++i) // n - sides count
    {
    glVertex2f(); // the n-sided shape is to be drawn here
    }
    glEnd();


    glutSwapBuffers();
}

static void key(unsigned char key, int x, int y)
{
    switch (key)
    {
        case 27 :
        case 'q': // quit
            exit(0);
            break;

        case '+': // increase sides count
            n++;
            break;

        case '-': // decrease sides count
            if (n > 3) // cannot be less than 3
            {
                n--;
            }
            break;
    }

    glutPostRedisplay();
}

static void idle(void)
{
    glutPostRedisplay();
}

int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitWindowSize(640,480);
    glutInitWindowPosition(10,10);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);

    glutCreateWindow("GLUT Shapes");

    glutDisplayFunc(DisplayShape);
    glutKeyboardFunc(key);
    glutIdleFunc(idle);

    glutMainLoop();

    return EXIT_SUCCESS;
}

Solution

  • Distribute the N-points around a circle. Compute the angle between the vectors from the center of the circle to the points (360°/N). Calculate the points using their Polar Coordinates:

    const float x0 = 0.0f;
    const float y0 = 0.0f;
    const float sideLen = 0.5;
    float dist = sideLen / 2.0f / sin(M_PI * 2.0f / n / 2.0f);
    float startAngle = -M_PI * (n - 2) / 2 / n;
            
    glBegin(GL_LINE_LOOP);
    
    for (int i = 0; i < n; ++i) // n - sides count
    {
        float sideAngle = M_PI * 2.0 * i / n + startAngle;
        float x = x0 + dist * cos(sideAngle);
        float y = y0 + dist * sin(sideAngle);
        glVertex2f(x, y);
    }
    glEnd();
    

    Complete example:

    #include <GL/gl.h>
    #include <GL/glu.h>
    #include <GL/freeglut.h>
    #define _USE_MATH_DEFINES
    #include <math.h>
    
    int n = 3;
    
    static void DisplayShape(void)
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glColor3d(1, 0.1, 0.6);
    
        const float x0 = 0.0f;
        const float y0 = 0.0f;
        const float sideLen = 0.5;
        float dist = sideLen / 2.0f / sin(M_PI * 2.0f / n / 2.0f);
        float startAngle = -M_PI * (n - 2) / 2 / n;
            
        glBegin(GL_LINE_LOOP);
    
        for (int i = 0; i < n; ++i) // n - sides count
        {
            float sideAngle = M_PI * 2.0 * i / n + startAngle;
            float x = x0 + dist * cos(sideAngle);
            float y = y0 + dist * sin(sideAngle);
            glVertex2f(x, y);
        }
        glEnd();
    
        glutSwapBuffers();
        glutPostRedisplay();
    }
    
    static void key(unsigned char key, int x, int y)
    {
        switch (key)
        {
        case 27:
        case 'q': // quit
            exit(0);
            break;
    
        case '+': // increase sides count
            n++;
            break;
    
        case '-': // decrease sides count
            if (n > 3) // cannot be less than 3
                n--;
            break;
        }
        glutPostRedisplay();
    }
    
    static void reshape(int width, int height)
    {
        glViewport(0, 0, width, height);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        double aspect = (double)width / height;
        glOrtho(-aspect, aspect, -1.0, 1.0, -1.0, 1.0);
        glMatrixMode(GL_MODELVIEW);
    }
    
    int main(int argc, char* argv[])
    {
        glutInit(&argc, argv);
        glutInitWindowSize(640, 480);
        glutInitWindowPosition(10, 10);
        glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    
        glutCreateWindow("GLUT Shapes");
    
        glutReshapeFunc(reshape);
        glutDisplayFunc(DisplayShape);
        glutKeyboardFunc(key);
    
        glutMainLoop();
    
        return EXIT_SUCCESS;
    }