【问题标题】:Why is my Processing app not behaving?为什么我的处理应用程序没有运行?
【发布时间】:2009-10-06 06:17:06
【问题描述】:

我正在学习使用Processing,并修改了其中一个示例以创建this applet。我有两个问题:

  1. 为什么这些球体是扁圆形的?我抄袭的示例中的球体又漂亮又圆。
  2. 当点光源位于球体之间时,为什么我会在球体的外侧边缘显示光?

这是这个小程序的源代码:

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

【问题讨论】:

  • 我看不出任何人在没有看到您的代码的情况下是如何分辨的。
  • @Bart:对不起,我还在习惯处理。小程序页面生成一个源代码链接,我认为它会显示源代码,并且我认为这是发布草图的惯例。我将编辑问题以将其包含在此处。
  • @Paul McGuire:谢谢。我不知道那里有指向源的链接。不幸的是,我没有尝试运行小程序,因为无法在我的 64 位 Linux 机器上使用 Java 的 IcedTea 插件运行处理小程序。稍后我会看一下代码。
  • 当我运行代码时,您描述的问题都没有发生。我看到光线从球体内部反射回来,球体是球形的!

标签: 3d processing


【解决方案1】:

在这种情况下,平滑函数不能很好地工作,因为您有相邻的多边形。在没有图片的情况下跟随有点棘手,但想想两个多边形之间的边缘上的像素。例如,假设背景是 (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)。但是,如果您单独绘制每个多边形并且在其间不保存任何覆盖信息,您将无法弄清楚。

现代显卡支持multisample antialiasing。这保存了一些关于第一个多边形覆盖的像素部分的信息。 Processing 试图在没有硬件支持的情况下模拟这一点,所以它使用了一个技巧,当你没有邻接的基元时效果很好,但当你有时就会崩溃。

至于扁率。默认情况下,Processing 会填满整个窗口,并且您的尺寸不是正方形的。解决这个问题的最简单方法是使用正交函数来使相机的纵横比为正方形。尝试将此添加到您的设置中:

正交(-360,360,-180,180,-10,10);

【讨论】:

  • 谢谢 - 纵横比修复了球体的扁率。 Ortho 有帮助,但现在我得到了一些奇怪的背光。
【解决方案2】:

关于漂亮的圆形边缘,请尝试在 setup() 中调用方法 smooth():

void setup() {
  // ...
  smooth();
  // ...
}

【讨论】:

  • 感谢您的回答,但这实际上使事情变得更糟。构成球体表面的三角形变得可见,光线“穿过”球体显示。
  • 啊,是的,smooth() 是 AFAIK 仅用于处理中的 2D 绘图。我没想到你正在制作 3D 绘图。不幸的是,我从未在 Processing 中做过很多 3D。
猜你喜欢
  • 2021-03-23
  • 2020-10-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多