实验要求(如图片):
思路分析:
1. 观察实验要求实现的图形,发现三个图形都有相同的特点。三个图形大致都可以拆分为:最外层的圆形以及内部若干个相同的小四边形。
2. 这些相同的小四边形可由其中一个四边形旋转实现,可利用for循环通过对角度的改变来循环输出若干个四边形,同时可在for循环内嵌入四边形第一个点分别与第二个点和 第三个点的连线,最终通过for循环实现图形内部所有的连线。
3. 共青团徽与普通花形中都有圆环,本程序中通过圆的参数方程,画圆上的点,虽然各点之间没有连线,但由于画的点足够多因此就无限逼近圆,再通过设置点的大小,就实 现了圆环的效果。My solution:
#include<GL/glut.h>
#include<cmath>
#include<iostream>
using namespace std;
int pointcount=12;//顶点数
float r=0.75;//圆的半径
float sidelength=0.15;//四边形的边长
const float pi=3.1415926;
void myDisplay(void)
{
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f,1.0f,1.0f);
glRectf(-0.8f,-0.8f,0.8f,0.8f);//最外层白色矩形
if(pointcount!=12 && pointcount!=5)
glColor3f(1.0,0.0,1.0);
else if(pointcount==12)
glColor3f(0.0,0.0,1.0);党徽圆为蓝色
else
glColor3f(1.0,0.0,0.0);//共青团圆形为红色
glBegin(GL_POLYGON);//画圆形
for(float i=0;i<360;i=i+0.5)
{
float x1=r*cos((i/180)*pi);
float y1=r*sin((i/180)*pi);
glVertex2f(x1,y1);
}
glEnd();
float x[4],y[4],x2,y2;
x[0]=y[0]=0;
float averagedegree=360.0/pointcount;//每个花瓣的角度
float averde01,averde02;//循环角度变量
averde01=90;
averde02=90-averagedegree/2;//初始化
if(pointcount==5)//求五角星中四边形较短边的长度
{
float dx;
dx=sin(18.0/180*pi)*r;
sidelength=dx/cos(36.0/180*pi);
}
else
sidelength=(r/2)/cos((averagedegree/2)/180*pi);//其它所画图形中的四边形较短边的长度
x[1]=sidelength*cos((averde02/180)*pi);
y[1]=sidelength*sin((averde02/180)*pi);
for(int ii=1;ii<=pointcount;ii++)//画圆形内部的图案,通过for循环一个一个四边形输出拼凑
{
if(pointcount==5)
glColor3f(1.0,1.0,0.0);//五角星为黄色
else
glColor3f(1.0,1.0,1.0);//白色
glBegin(GL_POLYGON);
glVertex2f(0.0,0.0);//第一个点
glVertex2f(x[1],y[1]);//第二个点
x[2]=r*cos((averde01/180)*pi);
y[2]=r*sin((averde01/180)*pi);
glVertex2f(x[2],y[2]);//第三个点
averde01+=averagedegree;
averde02+=averagedegree;
x[3]=sidelength*cos((averde02/180)*pi);
y[3]=sidelength*sin((averde02/180)*pi);
glVertex2f(x[3],y[3]);//第四个点
glEnd();
if(pointcount!=12)//画图案内部的连线,国民党党徽内部无结点连线
{
if(pointcount==5)
glColor3f(0.0,0.0,0.0);//五角星内部结点连线为黑色
else
glColor3f(1.0,0.0,0.0);//其余图形内部结点连线为红色
glBegin(GL_LINE_LOOP);
glVertex2f(x[0],y[0]);
glVertex2f(x[2],y[2]);//画四边形的第一个结点和第三个结点连线
glEnd();
glBegin(GL_LINE_LOOP);
glVertex2f(x[0],y[0]);
glVertex2f(x[1],y[1]);//画四边形的第一个结点和第二个结点的连线
glEnd();
}
x[1]=x[3];//变换坐标:当前四边形的第四个坐标是下一个四边形的第二个坐标
y[1]=y[3];
}
if(pointcount==12||pointcount==5)//画圆圈,国民党徽内部,共青团五角星外部,其它图形不需画圆
{
if(pointcount==12)
{
glColor3f(0.0,0.0,1.0);//党徽圆圈为蓝色
glPointSize(3);//圆圈
}
else
{
glColor3f(1.0,1.0,0.0);//共青团徽圆圈为黄色
glPointSize(6);
}
glBegin(GL_POINTS);
float x3,y3;
for(float j=0;j<360;j=j+0.3)
{
if(pointcount==12)//国民党党徽内部圆圈
{
x3=(sidelength-0.015)*cos((j/180)*pi);
y3=(sidelength-0.015)*sin((j/180)*pi);
}
else//共青团徽最外层圆圈
{
x3=(r+0.015)*cos((j/180)*pi);
y3=(r+0.015)*sin((j/180)*pi);
}
glVertex2f(x3,y3);
}
glEnd();
}
glFlush();
}
int main(int argc,char *argv[])
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);
glutInitWindowPosition(100,100);
glutInitWindowSize(400,400);
glutCreateWindow("Hello World!");
cout<<"请输入顶点个数: 5.为共青团团徽; 12.为国民党徽; 其它顶点数则输出花形!\n";
cin>>pointcount;
glutDisplayFunc(&myDisplay);
glutMainLoop();
return 0;
}