3

使用处理和递归,我正在尝试绘制与此类似的形状: http://i.imgur.com/OPf5D.png

但我觉得我在尝试各种可能的方式来绘制形状时失去了理智。这是我得到的最接近的:http://i.imgur.com/vCHJG.png

加上我的代码,任何帮助将不胜感激。谢谢:

void setup(){
  size(600,600);
}

void draw(){
  background(255);
  draws(300, 300, 50, 5);
}

void draws(int x, int y, int x2, int num){
  stroke(0);
  strokeWeight(2);
  line (x, y, (x+x2), y); //right
  line(x, y, x, y-50); //right up
  line (x-x2, y, x-(x2*2), y); // left 
  line(x-x2, y, x-x2, y-50); //left up 
  line (x, y-50, x-x2, y-50); //top 

  if(num>0){
    draws(x-x2, y-x2, x2/2, num-1);
  }
}
4

3 回答 3

0

(也许这应该是一个评论 - 因为它不是一个完整的答案 - 但我似乎无法做到)

那就是说.......

  • 您在每一步都除以 2 而不是 3。
  • 您需要每次绘制 3 秒层次结构“绘制”
  • 你在这里有'y'坐标-但是x坐标是错误的。猜测......层次结构应该是......

`

if(num>0){

    draws(x, y-x2, x2/3, num-1); // Central one    
    draws(x-x2, y, x2/3, num-1); // Left One   
    draws(x, y, x2/3/2,  num-1); // right one
}

`

稍微困难的是,您的坐标从右边线的左侧开始......可能更容易从最左边或最右边开始。

于 2012-11-26T04:22:02.743 回答
0

我知道了!谢谢您的帮助。

这是它的肉,其他一切都很好:

线(x,y,x,y-x2);//正确的

线(x-x2,y,x-x2,y-x2);//剩下

如果(数量> 0){

draws(x-(x2/3), y-x2, x2/3, num-1); // Central one  

draws(x+(x2/1.5), y, x2/3, num-1); // right one  

draws(x-(x2*1.33), y, x2/3, num-1); // left one

}

if (num==0) { //如果没有更多实例,画水平线

line (x, y, (x+x2), y); //right

line (x-x2, y, x-(x2*2), y); // left 

line (x, y-x2, x-x2, y-x2); //top 

}

于 2012-11-27T00:29:15.783 回答
0

逻辑类似于生成科赫分形。它是这样的:

  1. 画一条水平直线。
  2. 将线分成 3 段。
  3. 将中间段向上移动一个段的大小。
  4. 对每个段重复。

所以,我们的函数基本上应该尝试画这条线:

           _________
          |         |
          |         |
          |         |
 _________|         |_________

对每条水平线依次重复该过程。

我能想到的一种简单方法是从直线开始。然后在每次迭代中擦除行的中间并进行上移(您可以在黑线的顶部画一条白线)。

因此,伪代码将是这样的:

// Pseudocode:

fractal (x_start,x_end, y) {
    // first simply draw a straight line:
    line(x_start,y,x_end,y);

    // divide the line into 3 and push the middle up
    length = x_end-x_start;
    segment_length = length/3;
    x2 = x_start+segment_length;
    x3 = x_start+segment_length*2;
    y2 = y-segment_length;
    erase_line(x2,y,x3,y);
    line(x2,y,x2,y2);  // up
    line(x2,y2,x3,y2); // accross
    line(x3,y2,x3,y);  // down

    // now repeat for each segment
    fractal(x_start,y,x2,y);
    fractal(x2,y2,x3,y2);
    fractal(x3,y,x_end,y);
}

这就是基本的工作功能。请注意,它不会停止递归,因此上述函数将无限执行(或直到内存不足)。所以首先要做的是添加递归限制:

// Pseudocode:

fractal (x_start,x_end, y, limit) {
    //
    // same content as above except the last 3 lines
    //

    limit --;
    if (limit) {
        fractal(x_start,y,x2,y,limit);
        fractal(x2,y2,x3,y2,limit);
        fractal(x3,y,x_end,y,limit);
    }
}

这应该是一个很好的起点。

您还可以进行其他优化。例如,您实际上不需要在开始时绘制直线,因为每次迭代基本上都会再次绘制它。您只需要在递归的极限处绘制水平线。这意味着您不需要擦除未绘制的线条。但我将把它的实现留给读者作为练习。

于 2012-11-26T04:26:26.690 回答