Sierpinski地毯在加工

时间:2017-05-12 10:47:56

标签: processing fractals

因此,我使用Square数据类型处理Sierpinski地毯分形,该数据类型绘制正方形并具有函数generate(),其自身生成9个相等的正方形并返回ArrayList为了生成Sierpinski地毯,(9-1)= 8 正方形移除中间的(不会添加到返回的ArrayList)。

这是班级广场 -

class Square {

  PVector pos;
  float r;

  Square(float x, float y, float r) {
    pos = new PVector(x, y);
    this.r = r;
  }
  void display() {
    noStroke();
    fill(120,80,220);
    rect(pos.x, pos.y, r, r);
  }
  ArrayList<Square> generate() {

    ArrayList<Square> rects = new ArrayList<Square>();

    float newR = r/3;

    for (int i=0; i<3; i++) {
      for (int j=0; j<3; j++) {
        if (!(i==1 && j==1)) {
          Square sq = new Square(pos.x+i*newR, pos.y+j*newR, newR);
          rects.add(sq);
        }
      }
    }

    return rects;
  }
}

这是在鼠标点击时向前移动生成的主要草图 -

ArrayList<Square> current;

void setup() {
  size(600, 600);
  current = new ArrayList<Square>();

  current.add(new Square(0, 0, width));
}

void draw() {
  background(255);
  for (Square sq : current) {
    sq.display();
  }
}

void mousePressed() {
  ArrayList<Square> next = new ArrayList<Square>();

  for(Square sq: current) {
    ArrayList<Square> rects = sq.generate();
    next.addAll(rects);
  }
  current = next;
}

问题:

我得到的输出有非常细的白线,不应该在那里:

第一代 - enter image description here

第二代 - enter image description here

第三代 - enter image description here

我的猜测是,由于generate()中的计算被一两个像素关闭,这些线条只是显示的白色背景。但是我不确定如何摆脱这些。任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

这是一个展示您问题的小例子:

size(1000, 100);
noStroke();
background(0);

float squareWidth = 9.9;
for(float squareX = 0; squareX < width; squareX += squareWidth){
 rect(squareX, 0, squareWidth, height); 
}

squares with artifact

请注意,黑色背景通过正方形显示。请尝试发布这种最小的例子而不是将来的整个草图。

无论如何,有三种方法可以解决这个问题:

选项1:调用noSmooth()函数。

默认情况下,Processing使用消除锯齿功能使图形看起来更平滑。通常这是一件好事,但它也可以为形状的边缘添加一些模糊性。如果禁用消除锯齿功能,您的形状将更加清晰,您将看不到这些工件。

选项2:使用与填充颜色相同的笔触。

正如您已经发现的那样,这会围绕形状绘制轮廓。

选项3:使用int值代替float值。

您将坐标和大小存储在float值中,这些值可以包含小数位。问题是,屏幕(显示器上的实际像素)没有小数位(没有半像素),因此它们由int值表示。因此,当您将float值转换为int时,会删除小数部分,这会导致形状出现小间隙。

如果您只是切换到使用int值,则问题就会消失:

size(1000, 100);
noStroke();
background(0);

int squareWidth = 10;
for(int squareX = 0; squareX < width; squareX += squareWidth){
 rect(squareX, 0, squareWidth, height); 
}