如何优化我使用递归制作的这张 Sierpinski 地毯?

How can I optimize this Sierpinski carpet i made using recursion?

我按照关于递归的 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);
  }
}

如评论中所述,更改 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,当你深入到更小的矩形时,你会发现图形表示仍然不是"exact"。实现这一目标的一种方法是将草图的大小更改为 3 的幂:

size(729, 729);

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

像这样?

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);
      }
    }
  }
}