views:

135

answers:

2

I am learning to use Processing, and have modified one of the examples to create this applet. I have two questions:

  1. Why are the spheres oblate? The spheres in the example I cribbed from were nice and round.
  2. Why do I get the light showing on the outside edges of the spheres, when the point source is between them?

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

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

void setup() {
  // ...
  smooth();
  // ...
}
Bart Kiers
Thanks for your answer, but this actually makes things worse. The triangles that make up the spheres' surfaces become visible, and the light shows "through" the spheres.
Paul McGuire
Ah yes, smooth() is AFAIK only used for 2D drawing in Processing. It didn't occur to me you were making a 3D drawing. Unfortunately, I've never done much 3D in Processing.
Bart Kiers
+1  A: 

The smooth function doesn't work well in this case because you've got abutting polygons. It's a little tricky to follow without a picture, but think about a pixel which is on the edge between two polygons. For the example, let's say that the background is (0,0,0) and the polygons are (255,255,255). The first polygon draws and hits that pixel. It covers half of it, so it computes 0.5*(0,0,0) + 0.5*(255,255,255) and saves (126,126,126) as the new value for that pixel. The second polygon draws. It also covers half of the pixel so it computes 0.5*(126,126,126) + 0.5*(255,255,255) and saves (190,190,190). This isn't correct because the two polygons should have each covered a different half and resulted in a color of (255,255,255). But you can't figure that out if you draw each polygon individually and don't save any coverage information in between.

Modern graphics cards support something called multisample antialiasing. This saves some information about what part of the pixel the first polygon covered. Processing is trying to simulate this without the hardware support, so it uses a trick which works pretty well when you don't have abutting primitives, but falls apart when you do.

As for the oblateness. By default, Processing fills the entire window, and your size isn't square. The easiest way to deal with this is to use the ortho function to make the aspect ratio of your camera square. Try adding this to your setup:

ortho(-360,360,-180,180,-10,10);

MPG
Thanks - the aspect ratio fixes the oblateness of the spheres. ortho helps, but now I get some weird backlighting.
Paul McGuire