【问题标题】:How can I optimize this Sierpinski carpet i made using recursion?如何优化我使用递归制作的这个谢尔宾斯基地毯?
【发布时间】:2018-05-27 15:21:07
【问题描述】:

我按照 Shiffmans 关于递归的教程结束了这个:

如您所见,它并不完美,我认为代码可以优化。我如何摆脱不应该存在的粗线?如果您知道如何优化此代码,请告诉我!

这是使用处理 3.3.6 制作的,代码如下:

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

void draw() {
  background(255);
  fill(0);
  noStroke();

  rectMode(CENTER);
  Serpinski(width/2, height/2, width/3);
}

void Serpinski(int x, int y, int d) {
  rect(x, y, d, d);
  if (d > 1) {
    Serpinski(int(x+ d), y, d*1/3);
    Serpinski(int(x- d), y, d*1/3);
    Serpinski(x, int(y+ d), d*1/3);
    Serpinski(x, int(y- d), d*1/3);
    Serpinski(int(x+ d), int(y+ d), d*1/3);
    Serpinski(int(x- d), int(y- d), d*1/3);
    Serpinski(int(x+ d), int(y- d), d*1/3);
    Serpinski(int(x- d), int(y+ d), d*1/3);
  }
}

【问题讨论】:

  • 您指的是出现在最顶部 3x3 网格边界处的“粗”白线吗?我的猜测是它们只是由于舍入错误:800 / 3 = 266,666667(int 截断为 266),266 / 3 = 88,6666667(int 截断为 88)。我猜Sierpinski函数的参数应该是float。 (这不是答案,因为我无法真正测试它,但如果您确认它有效,我会将其写为答案(也许也尝试一下......))
  • 不要画白线,试着剪下黑色矩形。

标签: recursion processing fractals


【解决方案1】:

如 cmets 中所述,更改 Sierpinski 方法以处理 float 值而不是 int 会有所帮助。

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

void draw() {
  background(255);
  fill(0);
  noStroke();
  rectMode(CENTER);
  Serpinski(width/2, height/2, width/3);
}

void Serpinski(float x, float y, float d) {
  rect(x, y, d, d);
  if (d > 1) {
    Serpinski( x+ d,  y,    d/3);
    Serpinski( x- d,  y,    d/3);
    Serpinski( x,     y+ d, d/3);
    Serpinski( x,     y- d, d/3);
    Serpinski( x+ d,  y+ d, d/3);
    Serpinski( x- d,  y- d, d/3);
    Serpinski( x+ d,  y- d, d/3);
    Serpinski( x- d,  y+ d, d/3);
  }
}

但是,由于the way the pixel information is handled,当您深入到较小的矩形时,您会发现图形表示仍然不“精确”。实现这一目标的一种方法是将草图的大小更改为 3 的幂:

size(729, 729);

至于优化,您可以在 setup() 中调用 Sierpinski 方法,这样它只会计算一次,而不是每次调用 draw()

【讨论】:

    【解决方案2】:

    像这样?

    void setup() {
      size(729, 729);
      fill(0);
      background(255);
      centerRectangle(0, 0, width);
      rectangles(width/3, height/3, width/3);
    }
    
    void centerRectangle(int x, int y, int s) {
      float delta = s/3;
      noStroke();
      rect(x+delta, y+delta, delta, delta);
    }
    
    void rectangles(int x, int y, int s) {
      if (s < 1) return;
      int xc = x-s;
      int yc = y-s;
      for (int row = 0; row < 3; row++) {
        for (int col = 0; col < 3; col++) {
          if (!(row == 1 && col == 1)) {
            int xx = xc+row*s;
            int yy = yc+col*s;
            centerRectangle(xx, yy, s);
            rectangles(xx+s/3, yy+s/3, s/3);
          }
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-30
      • 2012-01-30
      相关资源
      最近更新 更多