配置openGL
dll里的东西放在windows/system32下,include放在编译器的include/gl文件夹里,如果没有gl文件夹可以新建一个,lib放在编译器的lib文件夹里。
这时候在程序开头加上#include<gl/glut.h>就可以。
头文件已成功引入,但出现了链接错误,在include之前加上这样一句宏定义
#define GLUT_DISABLE_ATEXIT_HACK。
计算五角星的顶点坐标
传入参数:中心坐标( x0, y0 ), 某一顶点坐标(x1,y1)
以传入顶点坐标(x1,y1)为基准逆时针旋转计算出各个顶点的坐标
在计算顶点时,使用了极坐标,如下所示:
|
由图可知两条直线的夹角为 ,在已知原坐标和旋转角度时,我们可以求出B的坐标:
我们先求出五角星外部五个顶点的坐标,以(x0,y0)为原点,先求出起始坐标的cos,sin,极坐标半径,再以起始坐标为基准,用以上公式依次旋转75度,得到各点的坐标。存入一个point二维数组。
再计算五角星内部五个顶点的坐标,首先我们要算出它的极坐标半径:
如图,我们已知O,A坐标,我们需要求OO’的长度r,也就是内点的极坐标半径。
可以求出∠AON = 36°,∠O’AN = 36°,利用OA坐标求出OA长度为R,则:
求出极坐标半径后,同理,以(x0,y0)为原点,第一次旋转36°,之后旋转72°,依次求出各内点坐标。
使用函数:
绘制多边形。
由于该函数只能绘制凸多边形,所以我们将五角星划分成多个多边形:
也就是一个五边形和五个三角形。
绘制多个三角形时,使用函数:
虽然还有更少几何形体的分割方式,但是这样在绘制三角形时方便通过循环来控制。
绘制红旗并调用星星函数摆放星星
给出的样例代码已经使用以下函数绘制出红旗:
稍作改动,把原来的深度信息去掉了,只保留了二维坐标。
使用函数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);
/* 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; }