2.2koch树
算法步骤类似于koch雪花,只是初始化不同:
c=8;
x3=x2+(c/sin(50.0)),y3=y2+(y1-y2)/5;
a3=x2,b3=y2+(y1-y2)/2,a4=x2,b4=y2+(y1-y2)/3;
x4=x1*2/3+x2*1/3;
y4=y1*2/3+y2*1/3;
x5=x1*1/3+x2*2/3;
y5=y1*1/3+y2*2/3;
x6=(x4+x5)/2+(y4-y5)*sqrt(5.0)/2;
y6=(y4+y5)/2+(x5-x4)*sqrt(5.0)/2;
x7=(x2+x5)/2+(y2-y5)*sqrt(3.0)/2;
y7=(y2+y5)/2+(x5-x2)*sqrt(3.0)/2;
x8=(x5+x4)/2+(y5-y4)*sqrt(7.0)/2;
y8=(y5+y4)/2+(x4-x5)*sqrt(7.0)/2;
x9=(x5+x2)/2+(y5-y2)*sqrt(3.0)/2;
y9=(y5+y2)/2+(x2-x5)*sqrt(3.0)/2;
if(depth<=1){
//初始化画线
}
else{.//递归
koch(x1,y1,x4,y4,depth-1);
koch(x4,y4,x3,y3,depth-1);
koch(x3,y3,x5,y5,depth-1);
koch(x5,y5,x2,y2,depth-1);
}
3、功能设计
(1)鼠标:
点击屏幕,进行递归绘制koch曲线绘制雪花图形和分形树;
(2)键盘交互按键‘1‘和’2‘切换两个图形界面;
(3)键盘交互按键‘A‘、’a‘和’S‘、’s’切换koch雪花的两种渐变颜色。
4、功能实现
3.1核心代码
(1)koch雪花曲线绘制
voidkoch(doublex1,doubley1,doublex2,doubley2,intdepth)
{
doublex4=x1*2/3+x2*1/3;
doubley4=y1*2/3+y2*1/3;
doublex5=x1*1/3+x2*2/3;
doubley5=y1*1/3+y2*2/3;
doublex3=(x4+x5)/2+(y4-y5)*sqrt(3.0)/2;
doubley3=(y4+y5)/2+(x5-x4)*sqrt(3.0)/2;
if(depth<=1){
glColor3f(0.5*color1,x3/500,y3/300);
glBegin(GL_LINE_STRIP);
glVertex2d(x1,y1);
glVertex2d(x4,y4);
glVertex2d(x3,y3);
glVertex2d(x5,y5);
glVertex2d(x2,y2);
glEnd();
}
else{
koch(x1,y1,x4,y4,depth-1);
koch(x4,y4,x3,y3,depth-1);
koch(x3,y3,x5,y5,depth-1);
koch(x5,y5,x2,y2,depth-1);
}
}
voiddrawKoch(void)
{
glColor3f(1.0,0.3,0.8);//设置红色绘图颜色
selectFont(48,GB2312_CHARSET,"楷体");//设置字体楷体48号字
glRasterPos2f(270,400);//在世界坐标250,250处定位首字位置
drawCNString("Koch雪花");//写字“Hello,大家好”
glTranslatef(cx,cy,0);//平移回去
glRotatef(theta1,0,0,1);//绕原点旋转ALPHA角度
glTranslatef(-cx,-cy,0);//平移回原点
koch(150,250,400,sqrt(3.0)*250+250,k);
koch(400,sqrt(3.0)*250+250,650,250,k);//
koch(650,250,150,250,k);
}
(2)koch树曲线绘制
voidtree(doublex1,doubley1,doublex2,doubley2,intdepth)
{
doublec=8;
doublex3=x2+(c/sin(50.0)),y3=y2+(y1-y2)/5;
doublea3=x2,b3=y2+(y1-y2)/2,a4=x2,b4=y2+(y1-y2)/3;
doublex4=x1*2/3+x2*1/3;
doubley4=y1*2/3+y2*1/3;
doublex5=x1*1/3+x2*2/3;
doubley5=y1*1/3+y2*2/3;
doublex6=(x4+x5)/2+(y4-y5)*sqrt(5.0)/2;
doubley6=(y4+y5)/2+(x5-x4)*sqrt(5.0)/2;
doublex7=(x2+x5)/2+(y2-y5)*sqrt(3.0)/2;
doubley7=(y2+y5)/2+(x5-x2)*sqrt(3.0)/2;
doublex8=(x5+x4)/2+(y5-y4)*sqrt(7.0)/2;
doubley8=(y5+y4)/2+(x4-x5)*sqrt(7.0)/2;
doublex9=(x5+x2)/2+(y5-y2)*sqrt(3.0)/2;
doubley9=(y5+y2)/2+(x2-x5)*sqrt(3.0)/2;
if(depth<=1){
glColor3f(0,0.5,0);
glBegin(GL_LINE_STRIP);
glVertex2d(x1,y1);
glVertex2d(x2,y2);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex2d(x5,y5);
glVertex2d(x7,y7);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex2d(x4,y4);
glVertex2d(x6,y6);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex2d(x5,y5);
glVertex2d(x9,y9);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex2d(x4,y4);
glVertex2d(x8,y8);
glEnd();
}else{
glColor3f(0,0.5,0);
glBegin(GL_LINE_STRIP);
glVertex2d(x5,y5);
glVertex2d(x7,y7);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex2d(x1,y1);
glVertex2d(x2,y2);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex2d(x4,y4);
glVertex2d(x6,y6);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex2d(x4,y4);
glVertex2d(x8,y8);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex2d(x5,y5);
glVertex2d(x9,y9);
glEnd();
glBegin(GL_LINE_STRIP);
tree(x5,y5,x2,y2,depth-1);
tree(x4,y4,x6,y6,depth-1);
tree(x5,y5,x7,y7,depth-1);
tree(x4,y4,x8,y8,depth-1);
tree(x5,y5,x9,y9,depth-1);
}}
voiddrawTree(void)
{
sky();
movesun();
tree(400,100,400,600,m);
}
(3)操作说明
voidmenu(void)
{
glColor3f(1,0.7,0);//设置红色绘图颜色
selectFont(48,GB2312_CHARSET,"楷体");//设置字体楷体48号字
glRasterPos2f(270,400);//在世界坐标250,250处定位首字位置
drawCNString("Koch雪花");//写字“Hello,大家好”
glColor3f(1,0.7,0.9);
selectFont(20,GB2312_CHARSET,"楷体");//设置字体楷体48号字/*楷体*/
glRasterPos2f(z1,z2+10);//定位首字位置
drawCNString("操作规则:
");//写字“Hello,大家好”
selectFont(20,GB2312_CHARSET,"楷体");//设置字体楷体48号字/*楷体*/
glRasterPos2f(z1,z2-10);//定位首字位置
drawCNString("1)按键1进入koch树");
glRasterPos2f(z1,z2-30);//定位首字位置
drawCNString("*按键2回到koch雪花");
glRasterPos2f(z1,z2-50);//定位首字位置
drawCNString("*鼠标点击进行分形");
glRasterPos2f(z1,z2-70);//定位首字位置
drawCNString("*按键A或a变换第一种渐进色颜色");
glRasterPos2f(z1,z2-90);//定位首字位置
drawCNString("2)按键S或s变换第二种渐进色颜色");
}
(4)键盘交互
voidmykeyboard(unsignedcharkey,intx,inty)//键盘交互
{
switch(key)
{
case'A':
color1=2;
break;
case'a':
//矩形对角坐标变量修改使得矩形左移
color1=2;
break;
case'D':
color1=0.3;
break;
case'd':
//矩形对角坐标变量修改使得矩形右移
color1=0.3;
break;
case'1':
flag=2;;
break;
case'2':
flag=1;;
break;
}
//参数修改后调用重画函数,屏幕图形将发生改变
glutPostRedisplay();
}
(4)鼠标交互
voidmyMouse(intbutton,intstate,intx,inty)
{
if(button==GLUT_LEFT_BUTTON&&state==GLUT_DOWN)
{
if(flag==1)
{
k+=1;
}
if(flag==2)
{
m+=1;
}
}
}
(5)显示函数
voiddisplay(void)
{
glClearColor(0.0f,0.0f,0.0f,0.0f);//设置清屏颜色
glClear(GL_COLOR_BUFFER_BIT);//刷新颜色缓冲区;
glMatrixMode(GL_MODELVIEW);//设置矩阵模式为模型变换模式,表示在世界坐标系下
glLoadIdentity();//将当前矩阵设置为单位矩阵
if(flag==1)
{
glClearColor(0.0f,0.0f,0.0f,0.0f);//设置清屏颜色
drawKoch();//koch雪花
}
if(flag==2){
glClearColor(1.0f,1.0f,1.0f,1.0f);//设置清屏颜色
drawTree();//koch树
}
glFlush();//用于刷新命令队列和缓冲区,使所有尚未被执行的OpenGL命令得到执行;
}
3.2效果截图:
(1)点击屏幕,递归显示koch曲线—雪花
递归一次:
k=1递归二次:
k=2
递归三次:
k=3递归N次:
k=N
(2)按键‘A’或‘a’换第一种渐变色
按键‘S’或‘s’换第二种渐变色;
(3)按键1,切换到koch树的界面,点击屏幕开始递归分析
递归一次:
k=1递归二次:
k=2
递归三次:
k=3递归N次:
k=N
(4)按键2,切换到koch雪花的界面
参考文献:
[1]分形算法与程序设计—java实现孙博文著科学出版社,2004
[2]混沌的计算实验与分析于万波著科学出版社,2008
[3]Koch雪花曲线的制作及其重要结论《长春师范大学学报》,2003,第1期:
6-8
[4]基于分形理论的图形设计研究与应用帅昌浩著《西安科技大学》,2008