实验要求及实现目标:
实验1:(1)观察实验要求可以发现,最外层正方形的相邻两点的横纵坐标分别相加再除以2就得到内层正方形的坐标。
(2)通过for循环,利用上层正方形的四个坐标来求下层正方形的坐标,并利用for循环,每循环一次就改变输出图形的颜色。为了避免无限循环,当最内层的正方边 长小于预先设定的值时,就退出循环。
实验2:(1)实验所要求的图形由菱形组成,但是红色菱形与绿色菱形的边长相等,夹角可能不同,但二者夹角和为90度。
(2)通过预先设定的边长和角度,利用三角函数求出菱形的各点的坐标。通过for循环,改变角度并循环输出每一个菱形。
My solution:
循环菱形:
#include
#include
#include
#include
using namespace std;
double reddegree=45;//红色菱形的夹角度数
double sidelength=0.4;//菱形边长
const double 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.85f,-0.85f,0.85f,0.85f);
double redx,redy,greenx,greeny,dglength,drlength;
redx=sin((reddegree*1.0/2)/180*PI)*sidelength;//最上面的菱形与原点相邻右顶点的,x,y坐标
redy=cos((reddegree*1.0/2)/180*PI)*sidelength;
greenx=greeny=(redx+redy);//最右面绿菱形的顶点坐标
dglength=sqrt(2*greenx*greenx);//绿色菱形最长对角线
drlength=2*redy;//红色菱形最长对角线
int count=1;//纪录循环次数
double nowdegree1=-reddegree/2,nowdegree2=0;//从最右边的红色菱形开始旋转
double dx,dy;
dx=sidelength*cos(nowdegree1/180*PI);//中间变量,用来记录菱形中的第二个点坐标
dy=sidelength*sin(nowdegree1/180*PI);
while(count<9)//每循环一次输出一个菱形。每次循环由于角度的增加,而边长始终不变,可以利用三角函数求得每次循环中的菱形各点的坐标
{
if(count%2==1)//选择颜色
glColor3f(1.0f, 0.0f, 0.0f);
else
glColor3f(0.0f, 1.0f, 0.0f);
glBegin (GL_POLYGON);
glVertex2d(0.0,0.0);//四边形第一个点
glVertex2d(dx,dy);//四边形第2个点
if(count%2==1)//判断输出第3个点:绿色菱形顶点,还是红色菱形顶点。因为预先设定的角度不同,红色菱形和绿色菱形可能不一样大
{
float cx,cy;
cx=drlength*cos(nowdegree2/180*PI);
cy=drlength*sin(nowdegree2/180*PI);
glVertex2d(cx,cy);//红色菱形顶点
}
// glVertex2d(drlength*cos(nowdegree2/180*PI),drlength*sin(nowdegree2/180*PI));//红色菱形顶点
else
{
float cx,cy;
cx=dglength*cos(nowdegree2/180*PI);
cy=dglength*sin(nowdegree2/180*PI);
glVertex2d(cx,cy);//绿色菱形顶点
}
// glVertex2d(dglength*cos(nowdegree2/180*PI),dglength*sin(nowdegree2/180*PI));//绿色菱形顶点
if(count%2==1)
nowdegree1+=reddegree;
else
nowdegree1+=(90-reddegree);
dx=sidelength*cos((nowdegree1)/180*PI);//计算第4个点的坐标,同时该点也是下一次循环输出的菱形的第二个点的坐标
dy=sidelength*sin(nowdegree1/180*PI);
glVertex2d(dx,dy);//第四个点
nowdegree2+=45;
count++;
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!");
glutDisplayFunc(&myDisplay);
glutMainLoop();
return 0;
}
#include
#include
#include
#include
#include
using namespace std;
const float initlength=0.6;//最外边正方形长度
const float finalength=0.03;//最里层正方形长度
void myDisplay(void)
{
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
// glBegin(GL_POLYGON);
float a_x,a_y,b_x,b_y,c_x,c_y,d_x,d_y;//四个坐标
float a_x1,a_y1,b_x1,b_y1,c_x1,c_y1,d_x1,d_y1;//辅助转换坐标
int colorchange=0;//控制颜色循环
float exit01,exit02;//循环的出口。因为在旋转过程中,a可能会在坐标轴上,此时与原点的横坐标或纵坐标差值为0,因此需
//同时需要同时比较横坐标、纵坐标的差值当二者都很小时,说明a足够接近原点,跳出循环
a_x=d_x=-initlength;
b_x=c_x=initlength;
a_y=b_y=initlength;
c_y=d_y=-initlength;
exit01=a_x;//设置循环出口,当足够接近原点,就结束循环;
exit02=a_y;
if(exit01<0)
exit01=-exit01;
if(exit02<0)
exit02=-exit02;
while(exit01>finalength||exit02>finalength)//设置循环出口,当最内层边长足够小就结束循环;
{
switch(colorchange)
{
case 0: glColor3f(1.0f,1.0f,1.0f);break;//白色
case 1: glColor3f(1.0f,0.0f,1.0f);break;//粉色=红+蓝
case 2: glColor3f(0.0f,0.0f,1.0f);break;//蓝色
case 3: glColor3f(1.0f,1.0f,0.0f);break;//(黄=红+绿)
case 4: glColor3f(0.0f,1.0f,0.0f);break;//绿色
default: glColor3f(1.0f,0.0f,0.0f);//红色
}
glBegin(GL_POLYGON);
//glBegin(GL_LINE_LOOP);//矩形框
glVertex2f(a_x,a_y);//输出正方形四个点
glVertex2f(b_x,b_y);
glVertex2f(c_x,c_y);
glVertex2f(d_x,d_y);
glEnd();
glFlush();
a_x1=(a_x+b_x)/2; a_y1=(a_y+b_y)/2;//变换坐标
b_x1=(b_x+c_x)/2; b_y1=(b_y+c_y)/2;
c_x1=(c_x+d_x)/2; c_y1=(c_y+d_y)/2;
d_x1=(d_x+a_x)/2; d_y1=(d_y+a_y)/2;
a_x=a_x1; a_y=a_y1;//重新赋值
b_x=b_x1; b_y=b_y1;
c_x=c_x1; c_y=c_y1;
d_x=d_x1; d_y=d_y1;
colorchange++;
colorchange%=6;//控制6种颜色变化
exit01=a_x;//设置循环出口,当足够接近原点,就结束循环;
exit02=a_y;
if(exit01<0)
exit01=-exit01;
if(exit02<0)
exit02=-exit02;
}
}
int main(int argc,char *argv[])
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);
glutInitWindowPosition(100,100);
glutInitWindowSize(400,400);
glutCreateWindow("Hello World!");
glutDisplayFunc(&myDisplay);
glutMainLoop();
return 0;
}