题
我正在学习使用 加工, ,并修改了示例之一以创建 这个小程序. 。我有两个问题:
- 为什么球体是扁圆形的?我抄袭的例子中的球体又漂亮又圆。
- 当点光源位于球体之间时,为什么光线会显示在球体的外边缘?
这是这个小程序的源代码:
int radius = 40;
int spheredist = 320;
int maxlevel = 7;
float ecc = 0.28;
int x1, x2, y1, y2;
void setup() {
size(640, 360, P3D);
fill(204);
//smooth(); // makes spheres ugly
translate(width/2, height/2, 0);
x1 = -spheredist/2+radius;
x2 = spheredist/2-radius;
y1 =
y2 = 0;
}
void drawLightning(int x1_,int y1_,int x2_,int y2_,int lvl){
if (lvl < maxlevel){
int midx = (x1_ + x2_)/2;
int midy = (y1_ + y2_)/2;
float d = dist(x1_, y1_, x2_, y2_);
d *= ecc;
midx += random(-d, d);
midy += random(-d, d);
drawLightning(x1_, y1_, midx, midy, lvl+1);
drawLightning(midx, midy, x2_, y2_, lvl+1);
} else {
strokeWeight(10);
stroke(60,100,255,100);
line(x1_,y1_,x2_,y2_);
strokeWeight(1);
stroke(255);
line(x1_,y1_,x2_,y2_);
}
}
void draw() {
background(0);
noStroke();
int brt = 200;
pointLight(brt/2, brt/2, brt/2, spheredist/2, -spheredist, spheredist);
ambientLight(brt/8,brt/8,brt/8);
if ((mouseX > width/4 && mouseX < width*3/4) &&
(mouseY > height/2-radius && mouseY < height/2+radius)) {
pushMatrix();
translate(width/2, height/2, 0);
pointLight(100, 100, 255, 0, 0, 0);
popMatrix();
}
pushMatrix();
translate(width/2 - spheredist/2, height/2, 0);
sphere(radius);
translate(spheredist, 0, 0);
sphere(radius);
popMatrix();
if ((mouseX > width/4 && mouseX < width*3/4) &&
(mouseY > height/2-radius && mouseY < height/2+radius)) {
pushMatrix();
translate(width/2, height/2, 0);
drawLightning(x1,y1,x2,y2,0);
popMatrix();
}
}
解决方案
在这种情况下,平滑函数不能很好地工作,因为您有邻接的多边形。在没有图片的情况下跟踪有点困难,但考虑一下位于两个多边形之间边缘的像素。例如,假设背景为 (0,0,0),多边形为 (255,255,255)。第一个多边形绘制并命中该像素。它覆盖了其中的一半,因此它计算 0.5*(0,0,0) + 0.5*(255,255,255) 并将 (126,126,126) 保存为该像素的新值。绘制第二个多边形。它还覆盖了一半像素,因此计算 0.5*(126,126,126) + 0.5*(255,255,255) 并保存 (190,190,190)。这是不正确的,因为两个多边形应该分别覆盖不同的一半并导致颜色为 (255,255,255)。但是,如果您单独绘制每个多边形并且不在其间保存任何覆盖范围信息,您将无法弄清楚这一点。
现代显卡支持称为 多重样本抗锯齿. 。这保存了一些有关第一个多边形覆盖像素部分的信息。处理试图在没有硬件支持的情况下模拟这一点,因此它使用了一种技巧,当您没有邻接基元时,该技巧效果很好,但当您有邻接基元时,该技巧就会崩溃。
至于扁度。默认情况下,处理会填充整个窗口,并且您的尺寸不是方形的。处理这个问题最简单的方法是使用正交函数使相机的长宽比成为正方形。尝试将其添加到您的设置中:
正交(-360,360,-180,180,-10,10);
其他提示
关于漂亮的圆边,尝试在 setup() 中调用 smooth() 方法:
void setup() {
// ...
smooth();
// ...
}
不隶属于 StackOverflow