import java.awt.*; import graphics.Animation; import graphics.Sphere; import graphics.Tube; public class hw4 extends ThreeDApplet { double speed = 0.5; Sphere unitSphere; Sphere head; Sphere leftBicep; Sphere rightBicep; Sphere leftArm; Sphere rightArm; Tube unitTube; Tube torso; //rotating head animation Animation headTurn; //rotating arm animations Animation rotatingLeft; Animation rotatingRight; Animation flexing; //flexing muscle animation public void init() { super.init(); unitSphere = new Sphere(); unitSphere.calculate(); unitTube = new Tube(); unitTube.calculate(); headTurn = new Animation(3); headTurn.addKeyFrame(0, -Math.PI/6); headTurn.addKeyFrame(1, Math.PI/6); headTurn.addKeyFrame(2, -Math.PI/6); //keyframe value is rotation of arm rotatingLeft = new Animation(3); rotatingLeft.addKeyFrame(0, -Math.PI/16); rotatingLeft.addKeyFrame(1, Math.PI/8); rotatingLeft.addKeyFrame(2, -Math.PI/16); rotatingRight = new Animation(3); rotatingRight.addKeyFrame(0, Math.PI/8); rotatingRight.addKeyFrame(1, -Math.PI/16); rotatingRight.addKeyFrame(2, Math.PI/8); //keyframe value is scaling of spheres representing biceps flexing = new Animation(3); flexing.addKeyFrame(0, 0.15); flexing.addKeyFrame(1, 0.30); flexing.addKeyFrame(2, 0.15); } void draw(Graphics g) { //background g.setColor(Color.white); g.fillRect(0,0,w,h); g.setColor(Color.black); drawShape(g, head); //drawShape(g, neck); drawShape(g, torso); drawShape(g, leftBicep); drawShape(g, rightBicep); drawShape(g, leftArm); drawShape(g, rightArm); } void animate() { push(); push(); //head head = (Sphere)unitSphere.clone(); //turn head rotateY( headTurn.get(elapsed) ); //shape head scale(0.22, 0.25, 0.22); translate(0, 1.25, 0); transform(head); pop(); push(); //torso torso = (Tube)unitTube.clone(); rotateX(Math.PI/2); scale(0.3, 1.5, 1); translate(0, 1, 0); transform(torso); pop(); push(); //left arm push(); animateLeftForearm(); pop(); push(); flexLeftBicep(); pop(); scale(0.7, 0.7, 0.7); rotateY(Math.PI/3); //move left arm to the left //and closer to shoulder translate(-0.6, 0.5, 0); transform(leftArm); transform(leftBicep); pop(); push(); //right arm push(); animateRightForearm(); pop(); push(); flexRightBicep(); pop(); scale(0.7, 0.7, 0.7); rotateY(-Math.PI/3); //move right arm to the right //and closer to shoulder translate(0.6, 0.5, 0); transform(rightArm); transform(rightBicep); pop(); //scale everything to fit //scale(0.85, 0.85, 0.85); scale(1.25, 1.25, 1.25); transform(head); transform(torso); transform(leftArm); transform(leftBicep); transform(rightArm); transform(rightBicep); pop(); } private void animateLeftForearm() { leftArm = (Sphere)unitSphere.clone(); scale(1, 0.15, 0.15); //stretch sphere to look like arm translate(-1, 0, 0); //change the center of rotation to elbow rotateZ(rotatingLeft.get(elapsed)); translate(-0.75, -0.25, 0); transform(leftArm); } private void animateRightForearm() { rightArm = (Sphere)unitSphere.clone(); scale(1, 0.15, 0.15); //stretch sphere to look like arm translate(1, 0, 0); //change the center of rotation to elbow rotateZ(rotatingRight.get(elapsed+1)); translate(0.75, -0.25, 0); transform(rightArm); } private void flexLeftBicep() { //copy the unit sphere to start fresh leftBicep = (Sphere)unitSphere.clone(); //modulus-based looping is handled by Animation class scale(1, flexing.get(elapsed), 0.15); rotateZ(-Math.PI/8); translate(0, 0.1, 0); //apply stack transformations to leftBicep transform(leftBicep); } private void flexRightBicep() { //copy the unit sphere to start fresh rightBicep = (Sphere)unitSphere.clone(); scale(1, flexing.get(elapsed+1), 0.15); rotateZ(Math.PI/8); translate(0, 0.1, 0); //apply stack transformations to rightBicep transform(rightBicep); } //opposite of projecting/rendering - turns screen coordinates into 3D coordinates //(sort of) private double[] screenTo3D(int x, int y) { double[] point = new double[2]; point[0] = 2.0 * (x - w/2.0) / w; point[1] = -2.0 * (y - h/2.0) / h; //flip y-axis return point; } }