Why is the processing app not working?

I learned how to use Processing and modified one of the examples to create this applet . I have two questions:

  • Why are the spheres flattened? The spheres in the example I cut out were nice and round.
  • Why am I getting the light displayed on the outer edges of the spheres when the point source is in between?

Here is the source for this little program:

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

      

+2


source to share


2 answers


In this case the smooth function doesn't work because you have adjacent polygons. It's a bit tricky to do without a picture, but think about a pixel that is on the edge between two polygons. For example, suppose the background is (0,0,0) and the polygons are (255,255,255). The first polygon draws and deletes this pixel. It covers half of it, so it calculates 0.5 * (0.0.0) + 0.5 * (255,255,255) and stores (126,126,126) as the new value for that pixel. The second polygon draws. It also covers half a pixel, so it calculates 0.5 * (126,126,126) + 0.5 * (255,255,255) and stores (190, 190, 190). This is incorrect because two polygons had to cover the other half and result in the color (255,255,255). But you can't figure it out,if you draw each polygon individually and don't store coverage information between them.

Modern graphics cards support something called multisample anti-aliasing . This stores some information about how much of the pixel is covered by the first polygon. The processing tries to mimic this without hardware support, so it uses a trick that works really well when you don't have any adjacent primitives, but falls apart when you do.



As for the flattening. By default, processing fills the entire window and the size is not square. The easiest way to deal with this is to use the ortho function to make your camera's aspect ratio square. Try adding this to your setup:

ortho (-360360, -180180, -10.10);

+3


source


For nice round edges, try calling the smooth () method in your setup ():



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

      

0


source







All Articles