//
// SHOW CLOSE-PACKING OF SPHERES
import java.awt.*;
import render.*;
public class packing extends RenderApplet
{
Geometry spheres, links;
Material pearl, bronze, steel;
double radius = .5, fov = .3;
boolean showLinks = true;
// INITIALIZE EVERYTHING
public void initialize() {
// SET BACKGROUND COLOR, FIELD OF VIEW AND FOCAL LENGTH
setBgColor(.4,.4,.8);
setFOV(fov);
setFL(20);
// DEFINE X,Y,Z AND RED,GREEN,BLUE FOR EACH LIGHT SOURCE
addLight( 1, 1, 1, .5 ,.4 ,.3 );
addLight(-1, 1,-1, .1 ,.07,.35);
addLight( 1, 1,-1, .012,.02,.22);
addLight(.5, 1,-1, .012,.02,.22);
addLight(.0,-1,-1, .22 ,.12,.02);
// CREATE SURFACE MATERIALS
pearl = (new Material()).setColor(.8,.8,.8, 1,1,1,10, .4,.4,.4);
bronze = (new Material()).setColor(.5,.35,.25, 1,1,1,3, .2,.14,.1);
steel = (new Material()).setColor(.5,.5,.5, 1.5,1.5,1.5,20, .1,.1,.25);
pearl.noiseF = 2;
pearl.noiseA = 1;
bronze.noiseF = 3;
bronze.noiseA = .5;
spheres = world.add();
links = world.add();
// MAKE THE CENTRAL (WHITE) SPHERE
Geometry s = spheres.add().setMaterial(pearl).add().ball(16);
// PLACE THE 12 SURROUNDING (RED) SPHERES AS FOLLOWS:
for (int i = 0 ; i < 12 ; i++) {
push();
// TRAVEL AROUND THE EQUATOR IN 12 EQUAL STEPS
rotateY(i * Math.PI / 6);
// ODD NUMBERED SPHERE: REMAIN ON THE EQUATOR
// ODD MULTIPLE OF TWO: TILT UP BY .955 RADIANS
// MULTIPLE OF FOUR: TILT DOWN .955 RADIANS
rotateX(i % 2 != 0 ? 0 : i % 4 != 0 ? -.955 : .955);
// CREATE AND POSITION THE SPHERE OBJECT
translate(0,0,2);
transform(s = spheres.add());
// - CREATE THE (RE-SIZABLE) SPHERICAL BALL
s.add().ball(12).setMaterial(bronze);
// - CREATE A CYLINDER LINKING TO THE CENTER SPHERE
translate(0,0,-1);
scale(.07,.07,1);
transform(links.add().cylinder(16).setMaterial(steel));
pop();
}
// SET THE INITIAL SIZE FOR EACH SPHERE
scaleSpheres(radius);
}
// SCALE ALL SPHERES
void scaleSpheres(double r) {
radius = Math.max(.2, Math.min(1, r));
scale(radius,radius,radius);
for (int i = 0 ; i <= 12 ; i++)
transform(spheres.child[i].child[0]);
}
// RESPOND TO USER KEYBOARD COMMANDS
public boolean keyUp(Event e, int key) {
super.keyUp(e, key);
switch (key) {
case ' ': // SPACE KEY: TOGGLE LINKS
showLinks = ! showLinks;
steel.setTransparency(showLinks ? 0 : 1);
break;
case 1004: // UP ARROW: NARROW VIEW
setFOV(fov = Math.max(.1,fov-.05));
break;
case 1005: // DOWN ARROW: WIDEN VIEW
setFOV(fov = Math.min(.5,fov+.05));
break;
case 1006: // LEFT ARROW: SHRINK SPHERES
scaleSpheres(radius-.1);
break;
case 1007: // RIGHT ARROW: GROW SPHERES
scaleSpheres(radius+.1);
break;
}
damage();
return true;
}
}