简单分形与递归

          学如逆水行舟,不进则退;心似平原走马,易放难收。大概我不是一个好的“骑手”,所以我的心总是在乱七八糟的飞---学事无成。又懒惰好久没写心得了,也将近两个月没认真学java了。不管怎样,总要写点什么了,最近复习了以前写的分形,又想起了当时的一点明悟,早就想着和大家一块分享一下,但由于鄙人的懒惰,一直拖到今天。
        好吧,我想说的是简单分形中的递归。
        说递归,初学者可能都知道递归这个词的含义,递归嘛,就是反复调用自己的方法。但在初写分形的时候,却不是很懂,不管你是不是,反正我是了(在java中的迟钝,让我一度伤心自己在这方面智商拙计)。你知道要用递归,可却不知道如何下手,或许简单的你知道如何去写,但麻烦点的又让你困惑,有木有,比我还菜的菜鸟?让本大菜鸟从三分康托,谢宾斯基,科赫曲线三个例子帮你理解分形中的递归吧。
先拿三分康托集来说吧,三分康托说白就是线段无限三分取两端,(我来学学插图):

      这个用递归,相信大家都很容易能够做出来,额,我做的是竖着的,竖着的啊,方法和思路都很简单,先写出一个画下条线的方法,然后母线调用就行了,简单代码如下:

 public void actionPerformed(ActionEvent e) {
   System.out.println(e.getActionCommand());   
   drawNextLine(g, 100,  100,  100,  700,count);

    } 
    private void drawNextLine(Graphics g, int x1, int y1, int x2, int y2,int count) {
    int blank =50; 
    if(count==0) 
     return;
     g.drawLine(x1, y1, x2,y2);
     drawNextLine(g,x1+blank, y1, x2+blank,(y2-y1)/3+y1,count-1);
     drawNextLine(g,x1+blank,(y2-y1)/3*2+y1, x2+blank, y2,count-1);
 } 

这个你能看出什么?初学者笨拙点的像我这样的可能还不太明白,以为只画出了两列线,但是你看,在画下条线中,又调用了drawNextLine的方法,这样母线调用画出第一子线,第一子线又调用方法画出第二级子线,如此下去,便可以画出三分康托集了,但是一定要注意递归跳出的条件哦,不然一个死递归只会画出一半,一半的一半,直到永远......

学会了三分康托集你可能好像明白了什么,好像有点感觉,那么再来做谢宾斯基三角形吧,喏,就是他了:

 突然有点复杂,是不是有点措手不及呢?没关系,可以照葫芦画瓢嘛,模仿三分康托集的方法试试吧,这是我的代码:

public void actionPerformed(ActionEvent e) {
   System.out.println(e.getActionCommand());
   draw2(g, 350, 100, 150, 450, 550, 450, 10);
 }
     public void draw2(Graphics g, int x1, int y1, int x2, int y2, int x3,
   int y3, int count) {
  if (count == 0)
   return;
      g.drawLine(x1, y1, x2, y2);
  g.drawLine(x1, y1, x3, y3);
  g.drawLine(x2, y2, x3, y3);
  //递归定义变量时要为局部变量
  int x4, y4, x5, y5, x6, y6;
  x4 = (x1 + x2) / 2;
  y4 = (y1 + y2) / 2;
  x5 = (x2 + x3) / 2;
  y5 = (y2 + y3) / 2;
  x6 = (x1 + x3) / 2;
  y6 = (y1 + y3) / 2;
  // 调用自身方法
  draw2(g,x1,y1,x4,y4,x6,y6,count-1);
  draw2(g,x6,y6,x5,y5,x3,y3,count-1);
  draw2(g,x4,y4,x2,y2,x5,y5,count-1);
 }

代码还是敲一敲比较好,或许刚开始你没有思路,但在模仿之下,你会越敲越有灵感,不知不觉中就做了出来,怎么样,看了代码是不是有种恍然大悟的感觉,但是你真的悟了吗?那么再来看看科赫雪花吧:

 看了这个是不是感觉还可以,但是真正做的时候,你可以吗?反正我那个时候是被拦住了,肿么做,想了几种方法都不能实现,反而是越想越复杂,又是添加斜率,又是判断角度的,最后反倒是做不出来了,好吧,求助,网上看了几个代码,也是不太简单,最后还是我的基友水货帮我解了惑,这是他的一篇文章,http://1095939258.iteye.com/blog/1873141

,额,好吧,这是我抄的代码:

public void actionPerformed(ActionEvent e) {
  System.out.println(e.getActionCommand());
   draw(g,50, 500,350, 500,depth);
   draw(g,350, 500,200, 240,depth);
   draw(g,200, 240,50, 500,depth);
 }
      private void draw(Graphics g, double x1, double y1, double x2, double y2, int depth) {
  if(depth<=1){
   g.drawLine((int)x1, (int)y1, (int)x2, (int)y2);
  }else{
   double x3=(2*x1+x2)/3,y3=(2*y1+y2)/3;
   double x4=(x1+2*x2)/3, y4=(y1+2*y2)/3;
   double x5=(x3+x4)/2+(y3-y4)/2*Math.sqrt(3);
      double y5=(y3+y4)/2+(x4-x3)/2*Math.sqrt(3);
     draw(g,x1,y1,x3,y3,depth-1); 
            draw(g,x3,y3,x5,y5,depth-1); 
            draw(g,x5,y5,x4,y4,depth-1); 
            draw(g,x4,y4,x2,y2,depth-1);
  }
  }  

到这里,我突然有种豁然开朗的感觉,原来这就是递归啊,真的是递归啊,就是不断调用自己的方法,科赫雪花需要考虑这么多吗?没必要啊,那什么斜率角度反倒脱离了递归的简洁,科赫雪花的用递归并不麻烦,麻烦其实只是画的方法,只要方法有,递归就是那一套了,所以,我在这里说了这么多废话,意思只有一个:用递归画分形,你要牢记递归就是反复调用自己的方法,不要想那么多,真的不要想那么多,多做几个练习,你会明白的,好吧,可能你早就懂了,突然感觉自己好笨噻..........

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值