import java.applet.AudioClip; import java.awt.*; public class hw6 extends BufferedApplet { AudioClip sound; double epsilon= 0.001; int ns=0; long time; int counterTranslate = 0; int maxTranslate = 3; int flipEyes = 0; int len=100; Matrix3D S[]=new Matrix3D[len]; Matrix3D pushz = new Matrix3D(); public void rotateX(double theta){ S[ns].rotateX(theta); } public void rotateY(double theta){ S[ns].rotateY(theta); } public void rotateZ(double theta){ S[ns].rotateZ(theta); } public void translate(double a, double b, double c){ S[ns].translate(a,b,c); } public void scale(double a, double b, double c){ S[ns].scale(a,b,c); } void push(){ if ((ns+1)>len){ Matrix3D S1[]=new Matrix3D[len + 1]; for (int i=0; i0) --ns; else System.out.println("Cannot pop very first matrix\n"); } void transform2(Shape shape){ shape.transfo=new Matrix3D(); shape.transfo.copy(S[ns]); } double eval(double[][] keyData, double t){ int i=0; while (t>=keyData[i+1][0]){ i++; } return (keyData[i][1] + (keyData[i+1][1] - keyData[i][1])*(t-keyData[i][0])/(keyData[i+1][0] - keyData[i][0])); } double hermite[][]={ {2, -2, 1, 1}, {-3, 3, -2, -1}, {0, 0, 1, 0}, {1, 0, 0, 0} }; double bezier[][]={ {-1, 3, -3, 1}, {3, -6, 3, 0}, {-3, 3, 0, 0}, {1, 0, 0, 0} }; double eval2(double [][] keyData, double t){ int i=0; while (t>=keyData[i+1][0]){ i++; } double tmp = (t-keyData[i][0])/(keyData[i+1][0] - keyData[i][0]); double tvect[] = {tmp*tmp*tmp, tmp*tmp, tmp, 1}; double coeff[] = new double[4]; for (int j=0; j<4; j++) coeff[j]=hermite[j][0]*keyData[i][1] + hermite[j][1]*keyData[i+1][1] + hermite[j][2]*keyData[i][2] + hermite[j][3]*keyData[i+1][2]; return tvect[0]*coeff[0]+tvect[1]*coeff[1]+tvect[2]*coeff[2]+tvect[3]*coeff[3]; } double eval3(double [][] keyData, double t){ int i=0; while (t>=keyData[i+1][0]){ i++; } double tmp = (t-keyData[i][0])/(keyData[i+1][0] - keyData[i][0]); double tvect[] = {tmp*tmp*tmp, tmp*tmp, tmp, 1}; double coeff[] = new double[4]; for (int j=0; j<4; j++) coeff[j]=bezier[j][0]*keyData[i][1] + bezier[j][1]*keyData[i][2] + bezier[j][2]*keyData[i][3] + bezier[j][3]*keyData[i+1][1]; return tvect[0]*coeff[0]+tvect[1]*coeff[1]+tvect[2]*coeff[2]+tvect[3]*coeff[3]; } int w, h, count = 0; int colr, colg,colb,currcol = 255; double t = 0; long time0; double elapsed; double headData[][] = { {0.0, 0.0}, {3.0, Math.PI/4}, {6.0, 0.0}, {16.0, 0.0} }; double headData2[][] = { {0.0, 0.0, 0.0}, {9.0, Math.PI/3, 0.0}, {11.0, 0.0, 0.0}, {14.0, -Math.PI/3, 0.0}, {16.0, 0.0, 0.0}, }; double bodyDataX[][] = { {0.0, -1.0}, {4.0, 1.0}, {5.0, 1.0}, {9.0, -1.0}, {10.0, -1.0}, }; double bodyDataY[][] = { {0.0, -1.0}, {4.0, -1.0}, {5.0, -0.5}, {9.0, -0.5}, {10.0, 0.0}, {14.0, 0.0}, {15.0, -0.5}, {19.0, -0.5}, {20.0, -1.0}, }; double bodyDataX2[][] = { {0.0, 0.0, 1.0, 1.0}, {5.0, 0.0, -1.0, -1.0}, {10.0, 0.0, 1.0, 1.0}, }; double bodyDataY2[][] = { {0.0, -1.0, -0.6, -0.3}, {10.0, 0.0, -0.3, -0.6}, {20.0, -1.0, -0.6, -0.3}, }; double footData[][] = { {0.0, 0.0}, {1.0, Math.PI/6}, {3.0, -Math.PI/6}, {4.0, 0.0}}; double onCubeMove[][] = { {0.0, 0.0}, {2.0, 0.25}, {6.0, -0.25}, {8.0, 0.0}}; double onCubeMove2[][] = { {0.0, 0.0, 0.5}, {2.0, 0.25, 0.0}, {4.0, 0.0, -0.5}, {6.0, -0.25,0.0}, {8.0, 0.0, 0.5}}; double onCubeMoveZ[][] = { {0.0,-3.0}, {2.0,-1.0}, {10.0,-1.0}, {12.0,3.0}, {14.0,-1.0}, {18.0,-1.0}, {24.0,-3.0}, }; double onCubeRotation[][] = { {0.0, 0.0}, {1.75, 0.0}, {2.0, Math.PI/2}, {2.25, Math.PI}, {5.75, Math.PI}, {6.0, 3*Math.PI/2}, {6.25, 2*Math.PI}, {8.0, 2*Math.PI}}; double onCubeRotation2[][] = { {0.0, 0.0, 0.0}, {2.0, Math.PI/2, 2.0}, {4.0, Math.PI, 0.0}, {6.0, 3*Math.PI/2, 2.0}, {8.0, 2*Math.PI, 0.0}}; Shape body = new Shape(); Shape head = new Shape(); Shape beak = new Shape(); Shape leftEye = new Shape(); Shape rightEye = new Shape(); Shape leftEyeBlack = new Shape(); Shape rightEyeBlack = new Shape(); Shape leftFoot = new Shape(); Shape rightFoot = new Shape(); Shape base = new Shape(); Shape duck[]= new Shape[10]; Matrix3D baseTransfo[] = new Matrix3D[10]; Matrix3D shapeTransfo[] = new Matrix3D[10]; Matrix3D placeTransfo[] = new Matrix3D[10]; Matrix3D persp = new Matrix3D(); public void init() { super.init(); } public void render(Graphics g) { if (w == 0) { initialize(); w = bounds().width; h = bounds().height; g.setColor(Color.black); g.fillRect(0,0,w,h); time0 = System.currentTimeMillis(); } g.setColor(Color.black); g.fillRect(0,0,w,h); time = System.currentTimeMillis(); elapsed = (double)(time - time0) / 1000.0; animate(); count ++; g.setColor(Color.blue); trace(base,g); if (flipEyes==0){ g.setColor(Color.red); trace(leftFoot,g); trace(rightFoot,g); g.setColor(Color.red); trace(beak,g); g.setColor(Color.white); trace(leftEye,g); trace(rightEye,g); g.setColor(Color.black); trace(leftEyeBlack,g); trace(rightEyeBlack,g); g.setColor(Color.yellow); trace(body,g); trace(head,g); } else{ g.setColor(Color.yellow); trace(body,g); trace(head,g); g.setColor(Color.red); trace(leftFoot,g); trace(rightFoot,g); g.setColor(Color.red); trace(beak,g); g.setColor(Color.white); trace(leftEye,g); trace(rightEye,g); g.setColor(Color.black); trace(leftEyeBlack,g); trace(rightEyeBlack,g); } } void animate() { Matrix3D tmp=new Matrix3D(); double t1 = Math.sin(elapsed/2); S[ns].identity(); S[ns].translate(0,0.3,0); S[ns].translate(eval3(bodyDataX2,(count/20.0)%10),eval3(bodyDataY2,(count/20.0)%20),0); //S[ns].translate(eval(bodyDataX,(count/20.0)%10),eval(bodyDataY,(count/20.0)%20),0); transform2(base); base.transfo.multiplyRight(baseTransfo[9]); push();//base S[ns].translate(eval2(onCubeMove2,(count/20.0)%8),0,0); //S[ns].translate(eval(onCubeMove,(count/20.0)%8),0,0); S[ns].translate(0,0,eval(onCubeMoveZ,(count/20.0)%24)); if ((count/20.0)%24>18) flipEyes=0; else flipEyes=1; S[ns].rotateYRight(-1*eval2(onCubeRotation2,(count/20.0)%8)); //S[ns].rotateYRight(-1*eval(onCubeRotation,(count/20.0)%8)); for (int i=0; i<9; i++){ transform2(duck[i]); duck[i].transfo.multiplyRight(baseTransfo[i]); } push();//left foot tmp.copy(baseTransfo[7]); tmp.rotateZ(eval(footData,(count/3.0)%4)); S[ns].multiplyRight(tmp); transform2(leftFoot); pop();//left foot push();//right foot tmp.copy(baseTransfo[8]); tmp.rotateZ(-1.0*eval(footData,(count/3.0)%4)); S[ns].multiplyRight(tmp); transform2(rightFoot); pop();//right foot push();//head double tmpAngle = eval(headData,((double)count/10.0)%16); S[ns].scaleRight(0.1,0.1,0.1); S[ns].translateRight(1.2*Math.sin(Math.PI/6+tmpAngle),1.2*Math.cos(Math.PI/6+tmpAngle),0); S[ns].rotateYRight(eval2(headData2,((double)count/10.0)%16)); for (int l=1; l<7; l++){ push();//head item S[ns].multiplyRight(shapeTransfo[l]); transform2(duck[l]); pop();//head item } pop();//head pop();//base /////////////////////////////////////////////////////////////////////////////////////// } int px(double t) { return (int)(w/2 + (int)(t*w/4)); } int py(double t) { return (int) (h/2 - (int)(t*w/4)); } void traceBak(Shape s, Graphics g ){ transform(s); for (int i=0; i