加工中的谢尔宾斯基地毯
Sierpinski carpet in processing
所以我在处理过程中使用 Square
数据类型制作了 Sierpinski 地毯分形,该数据类型绘制一个正方形并具有一个函数 generate()
可以从自身生成 9 个相等的正方形并且 returns一个 (9-1)=8 正方形的 ArrayList
移除中间的正方形(它不会添加到返回的 ArrayList
中)以生成 Sierpinski 地毯.
这里是class广场-
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()
中的计算偏离一两个像素而出现的白色背景。但是我不确定如何摆脱这些。如有任何帮助,我们将不胜感激!
这里有一个更小的例子来说明你的问题:
size(1000, 100);
noStroke();
background(0);
float squareWidth = 9.9;
for(float squareX = 0; squareX < width; squareX += squareWidth){
rect(squareX, 0, squareWidth, height);
}
请注意,黑色背景透过方块显示出来。请尝试 post 这种最小的例子,而不是你以后的整个草图。
无论如何,可以通过三种方法解决此问题:
选项 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);
}
所以我在处理过程中使用 Square
数据类型制作了 Sierpinski 地毯分形,该数据类型绘制一个正方形并具有一个函数 generate()
可以从自身生成 9 个相等的正方形并且 returns一个 (9-1)=8 正方形的 ArrayList
移除中间的正方形(它不会添加到返回的 ArrayList
中)以生成 Sierpinski 地毯.
这里是class广场-
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()
中的计算偏离一两个像素而出现的白色背景。但是我不确定如何摆脱这些。如有任何帮助,我们将不胜感激!
这里有一个更小的例子来说明你的问题:
size(1000, 100);
noStroke();
background(0);
float squareWidth = 9.9;
for(float squareX = 0; squareX < width; squareX += squareWidth){
rect(squareX, 0, squareWidth, height);
}
请注意,黑色背景透过方块显示出来。请尝试 post 这种最小的例子,而不是你以后的整个草图。
无论如何,可以通过三种方法解决此问题:
选项 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);
}