實驗要求及實現目標:
實驗1:(1)觀察實驗要求可以發現,最外層正方形的相鄰兩點的橫縱座標分別相加再除以2就得到內層正方形的座標。
(2)通過for循環,利用上層正方形的四個座標來求下層正方形的座標,並利用for循環,每循環一次就改變輸出圖形的顏色。爲了避免無限循環,當最內層的正方邊 長小於預先設定的值時,就退出循環。
實驗2:(1)實驗所要求的圖形由菱形組成,但是紅色菱形與綠色菱形的邊長相等,夾角可能不同,但二者夾角和爲90度。
(2)通過預先設定的邊長和角度,利用三角函數求出菱形的各點的座標。通過for循環,改變角度並循環輸出每一個菱形。
My solution:
循環菱形:
#include<GL/glut.h>
#include<cmath>
#include<cstdio>
#include<iostream>
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<GL/glut.h>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
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;
}