十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
这篇文章主要介绍“怎么用opengl绘制五星红旗”,在日常操作中,相信很多人在怎么用opengl绘制五星红旗问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么用opengl绘制五星红旗”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
专注于为中小企业提供网站制作、网站设计服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业怀来免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了上1000家企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。
主要仪器设备
VisualStudio C++2015
Windows 10环境opengl库
操作步骤
1.五星红旗的各项参数
1) 旗面为红色,长方形,长与高之比为3:2。2) 五星的位置参数:·为便于确定五星之位置,先将旗面对分为四个相等的长方形,将左上方之长方形上下划为十等分,左右划为十五等分。如下图所示:
·大五角星的中心点,在该长方形上五下五、左五右十之处。其画法为:以此点为圆心,以三等分为半径作一圆。在此圆周上,定出五个等距离的点,其一点须位于圆之正上方。然后将此五点中各相隔的两点相联,使各成一直线。此五直线所构成之外轮廓线,即为所需之大五角星。五角星之一个角尖正向上方。
·四颗小五角星的中心点,第一点在该长方形上二下八、左十右五之处,第二点在上四下六、左十二右三之处,第三点在上七下三、左十二右三之处,第四点在上九下一、左十右五之处。其画法为:以以上四点为圆心,各以一等分为半径,分别作四个圆。在每个圆上各定出五个等距离的点,其中均须各有一点位于大五角星中心点与以上四个圆心的各联结线上。然后用构成大五角星的同样方法,构成小五角星。此四颗小五角星均各有一个角尖正对大五角星的中心点。
2.绘制大五角星
因为glut无法根据顶点绘制凹多边形,我只能将图形拆解,分步绘制。我采用的方式是将五角星分解为10个三角形,共用五角星中心点作为顶点,这样就可以使用GL_TRIANGLE_FAN(连接成扇形的三角形系列)几何图元类型进行填充。对于每一个五角星,我们必须知道的参数只有两个,中心点和一个外顶点。
注意到,在连续绘制三角形的过程中,重点是根据A点求得B点坐标或者反之,那么根据正弦定理,我们可以求得b边的长度,根据BC边的与x轴的夹角以及36°角,我们可以得到A点的坐标。进而可以得到每一个三角形另外两点的坐标,一个五角星就绘制完成了。
3.绘制小五角星
小五角星的一个顶点必然在小五角星与大五角星的连线上,确定了这个顶点,就可以按照绘制大五角星的方法来绘制它了。根据大小五角星中心连线,我们又已知小五角星外接圆半径,就可以轻易求出顶角的坐标了。
4.窗口尺寸变化时图形不变形
如果不加入这一部分考虑,在对窗口进行缩放时会发生五星红旗拉伸、变形的情况。于是增加函数glutReshapeFunc以及glOrtho函数。glutReshapFunc用以指定窗口大小调整是的重绘制函数。glOrtho是创建一个正交平行的视景体。changeSize函数是在窗口大小发生变化时要执行的操作。
代码如下:
#include "gl/glut.h"#includeconst GLfloat PI = 3.1415926f;//定义圆周率void DrawStar(GLfloat px, GLfloat py, GLfloat vx, GLfloat vy,int flag)//位置以及五角星一个外顶点坐标{ glBegin(GL_TRIANGLE_FAN);//绘制一系列三角形 GLfloat vtx[12], vty[12];//1个中心点,10个顶点,顶点的第一个和最后一个相同,其中奇数下标是外顶点,偶数下标是内顶点 vtx[0] = px;//已知的中心点 vty[0] = py; vtx[1] = vx;//已知的第一个外顶点 vty[1] = vy; GLfloat length2 = sqrt((px - vx)*(px - vx) + (py - vy)*(py - vy));//中心点到外顶点的长度 GLfloat length3 = length2*sin(0.1*PI) / sin(126.0 / 180 * PI); //计算剩下的所有顶点 double init = atan((vty[1] - vty[0]) / (vtx[1] - vtx[0]));//顶点与中心点连线与x轴的角度 if (flag) init = init - PI; for (int i = 2; i < 12; i++) { init = init - 0.2*PI; if (i % 2 == 0) {//内顶点 vtx[i] = length3*cos(init) + vtx[0]; vty[i] = length3*sin(init) + vty[0]; } else {//外顶点 vtx[i] = length2*cos(init) + vtx[0]; vty[i] = length2*sin(init) + vty[0]; } } for (int i = 0; i < 12; i++) //设置顶点 glVertex3f(vtx[i], vty[i], 0.5); glEnd();}void display(){ glClear(GL_COLOR_BUFFER_BIT);//完成清除窗口的任务 //绘制红旗 glColor3f(1, 0, 0);//确定绘制物体时使用的颜色:红色 glBegin(GL_QUADS); glVertex3f(-0.75, 0.5, 0.5);//位于z=0.5平面的矩形 0.5是相对值 glVertex3f(0.75, 0.5, 0.5); glVertex3f(0.75, -0.5, 0.5); glVertex3f(-0.75, -0.5, 0.5); glEnd(); //绘制星星 glColor3f(1.0, 1.0, 0.0);//设置颜色为黄色 GLfloat px[5] = { -1.5 / 3,-0.75 / 3,-0.75 / 5,-0.75 / 5,-0.75 / 3 }; GLfloat py[5] = { 0.25,0.4,0.3,0.15,0.05 }; GLfloat vx[5] = { -1.5 / 3 }; GLfloat vy[5] = {0.4};//五星的中心点和其中指定顶点 //计算其余四星的顶点 for (int i = 1; i < 5; i++) { vx[i] = px[i]-0.05*cos(atan((py[0] - py[i]) / (px[0] - px[i]))); vy[i] = py[i]-0.05*sin(atan((py[0] - py[i]) / (px[0] - px[i]))); } //绘制 DrawStar(px[0], py[0], vx[0], vy[0], 0); DrawStar(px[1], py[1], vx[1], vy[1], 1); DrawStar(px[2], py[2], vx[2], vy[2], 1); DrawStar(px[3], py[3], vx[3], vy[3], 1); DrawStar(px[4], py[4], vx[4], vy[4], 1); glutSwapBuffers();//交换缓冲区}void changeSize(GLsizei w, GLsizei h){ if (h == 0) h = 1; glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); int dis = w < h ? w : h; glViewport(0, 0, dis, dis); glOrtho(-1.5, 1.5, -1.5, 1.5, -1.5, 1.5); if (w <= h) glOrtho(-1.0, 1.0, 1.0,1.0* h / w, 1.0, -1.0); else glOrtho(-1.0, 1.0 * w / h, 1.0, 1.0, 1.0, -1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity();}int main (int argc, char *argv[]){ glutInit(&argc,argv);//对glut函数库进行初始化 glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE);//指定glutCreateWindow函数将要创建的窗口显示模式 RGB模式 双缓冲 glutInitWindowPosition(10, 10);//指定窗口位置,窗口的一个角相对整个屏幕的位置 glutInitWindowSize(400,400);//指定窗口大小,只是一种提示,有可能被其他窗口覆盖 glutCreateWindow("Simple GLUT App");//打开设置好的窗口,进入glutMainLoop之前这个窗口不会显示 glOrtho(1.0, 1.0, 1.0, 1.0, 1.0, -1.0); glutReshapeFunc(changeSize); //注册窗口大小改变时回调函数 glClear(GL_COLOR_BUFFER_BIT);//完成清除窗口的任务 glutDisplayFunc(display);//与注册相关的回调函数,指定当窗口内容需要重绘时要调用的函数 glutMainLoop();//进入GLUT事件处理循环,永远不会返回 return 0;}
到此,关于“怎么用opengl绘制五星红旗”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注创新互联网站,小编会继续努力为大家带来更多实用的文章!