用递归函数实现康托尔集

源码 2024-9-6 11:32:15 57 0 来自 中国
书名:代码本色:用编程模仿天然体系
作者:Daniel Shiffman
译者:周晗彬
ISBN:978-7-115-36947-5
第8章目次
8.3 用递归函数实现康托尔集

接下来,我们要用递归函数实现康托尔集的可视化。从那边开始?
1、绘制线段的函数


  • 我们知道康托尔集在开始时是一个线段。因此,我们可以先实现一个用于绘制线段的函数。
void cantor(float x, float y, float len) {      line(x,y,x+len,y);}

  • 上面的cantor()函数在坐标(x,y)处开始画一个线段,线段长度是len。
  • (假设线段是水平的)因此,如果我们按以下方式调用cantor()函数:
    cantor(10, 20, width-20);
    就会得到这条线段
2、继承绘制下面两条线段


  • 从康托尔规则中可以看出,我们必要去掉线段中心的1/3,剩下两条线段:一条线段从出发点到1/3处,另一个条线段从2/3处到尽头。

    1.png
  • 我们要分别绘制这两条线段。我们沿y轴方向将这两条线段下移几个像素,让它们体现在原线段的下方。
void cantor(float x, float y, float len) {    line(x,y,x+len,y);    y += 20;    line(x,y,x+len/3,y); 从出发点到1/3处    line(x+len*2/3,y,x+len,y); 从2/3处到尽头} 2.png

  • 只管这是一个很好的开始,但重复地为每个线段调用line()函数并不是我们想要的实现方式。
    线段的数量会很快地增长,接下来我们要调用4次line()函数,再接着是8次,然后是16次……for循环曾经是我们办理此类题目的常用方法,但实验之后你会发现,用循环的方法办理这个题目黑白常复杂的。
  • 在这时间,递归就派上用场了,能接济我们于水火之中。
3、递归实现


  • 回顾一下我们怎样绘制第一个条线段,也就是从出发点到1/3处的线段:
    line(x,y,x+len/3,y);
    我们可以把这里的line()更换成cantor()函数。由于cantor()函数原来就会在(x,y)位置画一条指定长度的线段!因此:
    line(x,y,x+len/3,y); 更换成 -------> cantor(x,y,len/3);
  • 对于下面的line()函数调用,也有:
    line(x+len2/3,y,x+len,y); 更换成 -------> cantor(x+len2/3,y,len/3);
  • 于是,我们就有了以下代码:
void cantor(float x, float y, float len) {    line(x,y,x+len,y);    y += 20;    cantor(x,y,len/3);    cantor(x+len*2/3,y,len/3);}4、退出条件


  • 由于cantor()函数是递归调用的,在调用过程中,同样的规则会作用于下一条线段,再作用于下下条线段……别急着运行代码,我们还少了一个关键元素:退出条件。我们必须包管递归在某个点上能停下来——好比线段的长度小于1个像素。
5、示例

示例代码8-4 康托尔集
3.png void setup() {  size(800, 200);  background(255);    // Call the recursive function  cantor(35, 0, 730);}void draw() {  // No need to loop  noLoop();}void cantor(float x, float y, float len) {    float h = 30;    // recursive exit condition  if (len >= 1) {    // Draw line (as rectangle to make it easier to see)    noStroke();    fill(0);    rect(x, y, len, h/3);    // Go down to next y position    y += h;    // Draw 2 more lines 1/3rd the length (without the middle section)    cantor(x, y, len/3);    cantor(x+len*2/3, y, len/3);  }}
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-10-19 04:30, Processed in 0.165609 second(s), 35 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表