[OpenGL] 绘制五星红旗

       

[OpenGL] 绘制五星红旗_第1张图片

配置openGL

 

        dll里的东西放在windows/system32下,include放在编译器的include/gl文件夹里,如果没有gl文件夹可以新建一个,lib放在编译器的lib文件夹里。

        这时候在程序开头加上#include<gl/glut.h>就可以。

        头文件已成功引入,但出现了链接错误,在include之前加上这样一句宏定义

 

        #define GLUT_DISABLE_ATEXIT_HACK。

 

计算五角星的顶点坐标


 
 

[OpenGL] 绘制五星红旗_第2张图片

        传入参数:中心坐标( x0, y0 ), 某一顶点坐标(x1,y1)

        以传入顶点坐标(x1,y1)为基准逆时针旋转计算出各个顶点的坐标       

 

        在计算顶点时,使用了极坐标,如下所示:

 
 

 [OpenGL] 绘制五星红旗_第3张图片


        由图可知两条直线的夹角为   ,在已知原坐标和旋转角度时,我们可以求出B的坐标:

 
 

        我们先求出五角星外部五个顶点的坐标,以(x0,y0)为原点,先求出起始坐标的cos,sin,极坐标半径,再以起始坐标为基准,用以上公式依次旋转75度,得到各点的坐标。存入一个point二维数组。

         再计算五角星内部五个顶点的坐标,首先我们要算出它的极坐标半径:

     [OpenGL] 绘制五星红旗_第4张图片

 

            如图,我们已知O,A坐标,我们需要求OO’的长度r,也就是内点的极坐标半径。

            可以求出∠AON = 36°,∠O’AN = 36°,利用OA坐标求出OA长度为R,则:

        

        求出极坐标半径后,同理,以(x0,y0)为原点,第一次旋转36°,之后旋转72°,依次求出各内点坐标。

 

        使用函数:

 [OpenGL] 绘制五星红旗_第5张图片

 

        绘制多边形。

        由于该函数只能绘制凸多边形,所以我们将五角星划分成多个多边形:

 

 
 
        [OpenGL] 绘制五星红旗_第6张图片

        也就是一个五边形和五个三角形。

        绘制多个三角形时,使用函数:

 
 
[OpenGL] 绘制五星红旗_第7张图片

         虽然还有更少几何形体的分割方式,但是这样在绘制三角形时方便通过循环来控制。

 

绘制红旗并调用星星函数摆放星星


        给出的样例代码已经使用以下函数绘制出红旗:

[OpenGL] 绘制五星红旗_第8张图片

        稍作改动,把原来的深度信息去掉了,只保留了二维坐标。

        使用函数glColor3f(Glfloatr,Glfloat g,Glfloatb)通过传入RGB坐标值来制定绘制颜色。

        然后通过调整传入参数,把五颗星星的大小和位置调整好。

 

 

        窗口大小:(正方形窗口有利于计算)

        (400,400)

 

        矩形四点坐标:

         (-0.9,0.6),(0.9, 0.6),(0.9,-0.6),(-0.9, -0.6)

 

        五个五角星参数:(根据标准五星红旗绘制)

 

    drawStar(-0.60, 0.30, -0.78, 0.36);
    drawStar(-0.30, 0.48, -0.24, 0.48);
    drawStar(-0.18, 0.36, -0.24, 0.36);
    drawStar(-0.18, 0.18, -0.18, 0.24);
    drawStar(-0.30, 0.06, -0.24, 0.06);

/*
author:fish1996
date:2016/03/09
*/

#define GLUT_DISABLE_ATEXIT_HACK  
#include<math.h>  
#include<stdio.h>  
#include<gl/glut.h>  
const GLfloat PI = 3.1415926536f;//定义PI  


//(cx,cy)为五角星中心坐标,(mx,my)为其中一顶点坐标  
void drawStar(GLfloat cx, GLfloat cy, GLfloat mx, GLfloat my)
{
    int i, j;

    GLfloat length = sqrt((mx - cx)*(mx - cx) + (my - cy)*(my - cy));//计算外点极坐标半径  
    const GLfloat cos1 = cos(PI*0.4), sin1 = sin(PI*0.4);//计算得到常量 cos72°,sin72°的值  
    GLfloat cos2 = (mx - cx) / length; //计算得到初始点极坐标的cos,sin值  
    GLfloat sin2 = (my - cy) / length;
    const GLfloat cos3 = cos(PI*0.2), sin3 = sin(PI*0.2);//计算得到常量 cos36°,sin36°的值  
    GLfloat length2 = length*cos1/cos3;//计算内点极坐标半径  
    GLfloat point[10][2];//定义存储坐标信息的数组  
    GLfloat tmp_cos, tmp_sin;

    point[0][0] = mx, point[0][1] = my;

    //计算五个外点的坐标点,存入偶数下标  
    for (i = 1; i < 5; i++) {
        //利用极坐标旋转公式计算新坐标  
        tmp_cos = cos1*cos2 - sin1*sin2;
        tmp_sin = sin1*cos2 + cos1*sin2;
        point[2 * i][0] = cx + length*tmp_cos;
        point[2 * i][1] = cy + length*tmp_sin;
        cos2 = tmp_cos;
        sin2 = tmp_sin;
    }

    cos2 = (mx - cx) / length;
    sin2 = (my - cy) / length;

    //计算五个内点的坐标点,存入奇数下标  
    for (i = 0; i < 5; i++) {
        //利用极坐标旋转公式计算新坐标  
        if (i == 0) {
            tmp_cos = cos2*cos3 - sin2*sin3;
            tmp_sin = sin2*cos3 + cos2*sin3;
        }
        else {
            tmp_cos = cos1*cos2 - sin1*sin2;
            tmp_sin = sin1*cos2 + cos1*sin2;
        }
        point[i * 2 + 1][0] = cx + length2*tmp_cos;
        point[i * 2 + 1][1] = cy + length2*tmp_sin;
        cos2 = tmp_cos;
        sin2 = tmp_sin;
    }

    //设置黄色  
    glColor3f(1, 1, 0);

    //绘制五个三角形  
    glBegin(GL_TRIANGLES);
    for (i = 0; i < 5; i++) {
        for (j = 1; j <= 3; j++) {
            glVertex2fv(point[(2 * i + j) % 10]);
        }
    }
    glEnd();

    //绘制五边形  
    glBegin(GL_POLYGON);
    for (i = 0; i < 5; i++) {
        glVertex2fv(point[2 * i + 1]);
    }
    glEnd();
}

void display()
{
    glClear(GL_COLOR_BUFFER_BIT);//清除颜色缓存  
    //设置红色  
    glColor3f(1, 0, 0);

    //绘制红旗  
    glBegin(GL_QUADS);
    glVertex2f(-0.9, 0.6);
    glVertex2f(0.9, 0.6);
    glVertex2f(0.9, -0.6);
    glVertex2f(-0.9, -0.6);
    glEnd();

    //绘制星星  
    drawStar(-0.60, 0.30, -0.78, 0.36);
    drawStar(-0.30, 0.48, -0.24, 0.48);
    drawStar(-0.18, 0.36, -0.24, 0.36);
    drawStar(-0.18, 0.18, -0.18, 0.24);
    drawStar(-0.30, 0.06, -0.24, 0.06);

    glutSwapBuffers();//交换缓冲区  
}

int main(int argc, char *argv[])
{
    glutInit(&argc, argv);//对glut的初始化  
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);//初始化显示模式:RGB颜色模型,双缓冲  
    glutInitWindowPosition(10, 10);//设置窗口位置  
    glutInitWindowSize(400, 400);//设置窗口大小  
    glutCreateWindow("五星红旗");//设置窗口标题  
    glutDisplayFunc(display);//注册绘制回调函数  
    glutMainLoop();// glut事件处理循环  
    return 0;
}




你可能感兴趣的:([OpenGL] 绘制五星红旗)