(18) Experimentation in three dimensions - bouncing sphere

So, now we have seen a lot of 2D examples. How about 3D? How can a third dimension be added to a scene in Processing. Well, I have very little experience myself in this area, but by looking at the reference page for processing and testing some functions, I came up with this example where a ball, a sphere, is bouncing inside a box (drawn as a wireframe). I also added two spotlights to light up the scene. Please enter/copy the code, and try what happens if you remove some of the light sources. You can also change the speed of the ball and the rotation.


The code:

// ball location
float x=0, y=0, z=0;
// ball speeds
float xs=3, ys=2.1, zs=1;
// rotation of scene (viewpoint)
float rotz=0, rotx=0, roty=0;

void setup() {
  size(800, 800, P3D);
}

void draw() {
  background(0);

  // Make 0,0,0 center of scene, rotate all axises
  translate(width/2, height/2, 0);
  rotateX(rotx);
  rotateY(roty);
  rotateZ(rotz);
  lights();
  directionalLight(128, 128, 128, 0, -1, -1);
  // Yellow spotlight outside cube pointing to center
  spotLight(255, 255, 0, 200, 200, 200, -1, -1, -1, PI/2, 2);
  // Red spotlight outside cube pointing to center
  spotLight(255, 0, 0, -200, -200, 200, 1, 1, -1, PI/2, 2);

  // Small yellow sphere where light is 
  pushMatrix();
  noStroke();
  fill(255, 255, 0);
  translate(200, 200, 200);
  sphere(5);
  popMatrix();

  // Small red sphere where light is 
  pushMatrix();
  noStroke();
  fill(255, 0, 0);
  translate(-200, -200, 200);
  sphere(5);
  popMatrix();

  // Wire frame box in which the ball bounces
  pushMatrix();
  stroke(255);
  noFill();
  translate(0, 0, 0);
  box(300);
  popMatrix();

  // Bouncing ball
  pushMatrix();
  rotateX(-PI/8);
  translate(x, y, z);
  rectMode(CENTER);
  noStroke();
  fill(128);
  sphere(20);
  popMatrix();

  // Update ball position, bounce if reach box edge (box is -150 to 150, ball is 20)
  x=x+xs;
  if (x>130 || x<-130) {
    x=x-xs;
    xs=-xs;
  }

  y=y+ys;
  if (y>130 || y<-130) {
    y=y-ys;
    ys=-ys;
  }

  z=z+zs;
  if (z>130 || z<-130) {
    z=z-zs;
    zs=-zs;
  }

  // Rotate scene
  rotx+=0.001;
  roty+=0.0009;
  rotz+=0.0011;
}

After some more adjustments, I came up with this slightly fancier version



Code:

// ball location
float x=0, y=0, z=0;
// ball speeds
float xs=0, ys=0, zs=1;
// rotation of scene (viewpoint)
float rotz=0, rotx=0, roty=0;

float gravity = 0.2; 

void setup() {
  fullScreen(P3D);
  frameRate(60);
  x=0;
  y=-height/8;
  z=0;
}

void draw() {
  background(0);

  // Make 0,0,0 center of scene, rotate all axises
  translate(width/2, height/2, 0);
  rotateX(rotx);
  rotateY(roty);
  rotateZ(rotz);
  lights();
  directionalLight(50, 50, 50, 0, 1, 0);
  // Yellow spotlight outside cube pointing to center
  spotLight(255, 255, 0, width/6, -height/6, -width/6, -1, 1, 1, PI/4, 1);
  // Red spotlight outside cube pointing to center
  spotLight(255, 0, 0, -width/6, -height/6, width/6, 1, 1, -1, PI/4, 1);

  // Small yellow sphere where light is 
  pushMatrix();
  noStroke();
  fill(255, 255, 0);
  translate(width/6, -height/6, -width/6);
  sphere(5);
  popMatrix();

  // Small red sphere where light is 
  pushMatrix();
  noStroke();
  fill(255, 0, 0);
  translate(-width/6, -height/6, width/6);
  sphere(5);
  popMatrix();

  // Wire frame box in which the ball bounces
  pushMatrix();
  stroke(128);
  strokeWeight(5);
  noFill();
  translate(0, 0, 0);
  box(width/4, height/4, width/4);
  fill(10,233,133,50);
  rotateX(PI/2);
  translate(0, 0, -height/8);
  rect(-width/8.0, -width/8.0, width/4.0, width/4.0);
  popMatrix();

  // Bouncing ball
  pushMatrix();
  translate(x, y, z);
  noStroke();
  fill(128);
  sphere(20);
  popMatrix();

  // Update ball position, bounce if reach box edge (ball radius is 20)
  x=x+xs;
  if (x>(width/8) || x<-(width/8)) {
    x=x-xs;
    xs=-xs;
  }

  y=y+ys;
  if (y>(-20+height/8) || y<(-20-height/8)) {
    y=y-ys;
    ys=-ys;
  }

  z=z+zs;
  if (z>(width/8) || z<-(width/8)) {
    z=z-zs;
    zs=-zs;
  }

  // Add speed dependant on how much the plan is leaning 
  ys = ys + gravity*(1-0.1*abs(cos(roty*0.2)));
  xs = xs + gravity*0.1*sin(roty*0.2);
  
  // Rotate scene
  roty+=0.009;
  // Tilt plane 
  rotz=0.1*sin(roty*0.2);
}





1 comment: