很高兴能接触到分形这么美的图形,一直想发一篇这样的博客,实属自己老是忘记,虽然分形的文档已经写了,但是自己的博客却一直没有发。
刚看到分形时,我正在做科赫曲线,也就是雪花曲线。觉得这个图形很好玩,因此打算去做做。后来经龙哥展示了斌牛做的一个图形,顿时,自己都感到震惊。一条直线,不断的弯曲,弯曲。。。最终形成一个图形美丽的图形,神奇。
一、雪花曲线。
1.基本图形
2.图形的变化规则
3.预测产生的图形
雪花图形大家都知道,类似雪花,开始是由一个正三角形,经过不断的变化,产生出美丽的雪花
开始看给我们的就是一个三角形,经过边变换而成。其实我们仔细的看,正三角形还可以细分为每条边,因此我们开始就对一条边进行分析。
我们可以看成: 一条直线-------->去掉中间的三分之一,画一个60度角,两条相等的边------------->每条直线,去掉中间的三分之一,画一个60度角,两条相等的边------------>重复的做下去
我们也可以看成: 一条直线--------->变成四条直线,中间有一个60度的角--------------->每条直线,变成四条直线,中间有一个60度的角----------->重复做下去
我们还可以看成: 一条有方向的直线--------->向上旋转60度,向下旋转(180-60)度,向上再转60度--------->每条直线,向上旋转60度,向下旋转(180-60)度,向上再转60度-------->不断重复
对于前面两种的做法,我们可以根据1与2,算出3,4,5的坐标,然后再连接两点之间的坐标得出图形,但是这样往在第一次变形比较容易,一旦线的斜率发生变化,我们就开始很难处理。
第二种做法,我们出去考虑斜率不存在的麻烦,只需考虑倾斜角,通过第一个点+直线的长度+角度的变化,一次得出个个点的坐标。
只考虑倾斜角
*
* @param deepth//表示递归的次数,及分形的层次
*/
public void Kochv(Graphics g, double aX, double aY, double bX, double bY,int deepth ){
double c=10,
cX = 0, cY = 0,//第一个三等分点
dX = 0, dY = 0,//中间的 60度的角顶点
eX = 0, eY = 0,//第二个三等分点
l = 0, alpha = 0; //长度与倾斜角的初始化
if(deepth<=1){
g.drawLine((int) aX, 300-(int) aY, (int) bX, 300-(int) bY);
}else{
//第一个三等分点
cX = aX + (bX - aX) / 3;
cY = aY + (bY - aY) / 3;
//第二个三等分点
eX = bX - (bX - aX) / 3;
eY = bY - (bY - aY) / 3;
l = Math.sqrt((eX - cX) * (eX - cX) + (eY - cY) * (eY - cY)); //长度
alpha = Math.atan((eY - cY) / (eX - cX));//倾斜角
//对于倾斜角为负值和不存在的考虑
if( (alpha >= 0) && ((eX - cX) < 0) || (alpha <= 0) && ((eX - cX) < 0)){
alpha = alpha + PI;
}
//顶点的
dY = cY + Math.sin(alpha + PI / 3) * l;
dX = cX + Math.cos(alpha + PI / 3) * l;
//递归的调用,并且层次减1
Kochv(g,aX, aY, cX, cY,deepth-1);
Kochv(g,eX, eY, bX, bY,deepth-1);
Kochv(g,cX, cY, dX, dY,deepth-1);
Kochv(g,dX, dY, eX, eY,deepth-1);
}
}
对不deepth层次的控制,倾斜角的考虑。
运行结果如下:
根据一条直线规律,我们就可以同时做三条直线,也就是一个正三角型开始,只需再添加2条直线即可
实现:
int depth, Graphics g){
if (depth<=1){
g.drawLine ((int )x1,(int )y1,(int )x2,(int )y2);}
else {
//计算额外的点
//第一个三等分点
double x4=x1*2/3 + x2*1/3;
double y4=y1*2/3 + y2*1/3;
//第二个三等分点
double x5=x1*1/3 + x2*2/3;
double y5=y1*1/3 + y2*2/3;
//角顶点
double x6=(x4+x5)/2+(y4-y5)*Math.sqrt (3)/2;
double y6=(y4+y5)/2+(x5-x4)*Math.sqrt (3)/2;
//调用雪花递归
snowflake(x1,y1,x4,y4,depth-1,g);
snowflake(x4,y4,x6,y6,depth-1,g);
snowflake(x6,y6,x5,y5,depth-1,g);
snowflake(x5,y5,x2,y2,depth-1,g);
}
}
由上面的雪花曲线我们可以知道整个流程:
这里的处理单元就相当于旋转60的问题
3.预测产生的图形
当基本的图形(直线)不断微小化时,演化成点,曲线的的菱角将不在尖锐,图形的面积不断的增加,直到极限值,形成雪花图案。