因此,我使用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;
}
我得到的输出有非常细的白线,不应该在那里:
我的猜测是,由于generate()
中的计算被一两个像素关闭,这些线条只是显示的白色背景。但是我不确定如何摆脱这些。任何帮助将不胜感激!
答案 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);
}
请注意,黑色背景通过正方形显示。请尝试发布这种最小的例子而不是将来的整个草图。
无论如何,有三种方法可以解决这个问题:
选项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);
}