首先来看kock曲线是如何生成的:
(1)过程:
主要分为三大步骤:第一步,给定一个初始图形(这里是线段);第二步,将这条线段中间的1/3从中点向外折起(夹角为60度);第三步,按照第二步的方法不断的把各段线段中间的1/3处向外折起。
(2)新生成图形的坐标:
假设原直线的首尾点是P0(x0,y0)和P1(x1,y1),那么新生成的图形的五个端点就是:(注意第三个端点的正负号表示中间两条新直线位于原直线的哪一侧)
(3)之后就是结婚、离婚、结婚、再离婚,永无宁日。
正是上面加粗的那句话:注意第三个端点的正负号表示中间两条新直线位于原直线的哪一侧导致第一次取正号画出了这样的图像:
原本图像应该是:
这两个图像在代码上的区别只有一个正负号,就是第三个端点的正负号分别取正和负的结果,这的很神奇很有魅力,这大概就是分形学成为图形学重要分支的原因吧。
最后给出实现的代码:
代码中void compute()函数中注释的代码就是画上面两个图的区别之处:
//取正画皇冠上的钻石
tmp.x=(V[j][iteration_num-1][i].x+V[j][iteration_num-1][i+1].x)/2+(V[j][iteration_num-1][i].y-V[j][iteration_num-1][i+1].y)*sqrt(3.0)/6;
tmp.y=(V[j][iteration_num-1][i].y+V[j][iteration_num-1][i+1].y)/2+(V[j][iteration_num-1][i+1].x-V[j][iteration_num-1][i].x)*sqrt(3.0)/6;
//取负画雪花
//tmp.x=(V[j][iteration_num-1][i].x+V[j][iteration_num-1][i+1].x)/2-(V[j][iteration_num-1][i].y-V[j][iteration_num-1][i+1].y)*sqrt(3.0)/6;
//tmp.y=(V[j][iteration_num-1][i].y+V[j][iteration_num-1][i+1].y)/2-(V[j][iteration_num-1][i+1].x-V[j][iteration_num-1][i].x)*sqrt(3.0)/6;
完整代码:
#include <GL/freeglut.h>
#include <math.h>
#include <vector>
#define max_iteration_num 6//最多迭代六次
using namespace std;
struct Vertex{
GLfloat x,y;
};
vector<Vertex> V[3][max_iteration_num+1];//分别记录3条边各自6次迭代的数据(0、1、2、3、4、5、6)
int iteration_num=0;//记录迭代次数
GLfloat width=800.0,height=800.0;
//用户初始化函数
void myinit(void)