/*----------------------------------------------------------------------*/ /* Rotator -- This object draws a solid tumbling and bouncing. All of the faces will eventually be visable--it should take that long. - the user can also rotate the solid by dragging */ /*----------------------------------------------------------------------*/ /* Jim Morey - morey@math.ubc.ca - Jan 28,1996 */ /*----------------------------------------------------------------------*/ import java.io.*; import java.applet.*; import java.awt.*; import java.net.*; import java.lang.*; import HBlock; import O4matrix; /*----------------------------------------------------------------------*/ public class Rotator extends Canvas implements Runnable { private final static double CON1 = Math.sqrt(2)/2, CON2=Math.sqrt(7)/4,CON3= Math.PI/3; public Color background; public boolean spin; public int xdir,ydir,odir; int W,H,delay,oldx,oldy; double angle,angle0,bounce; boolean keep_going; Thread kicker; HBlock solid; O4matrix tmp,tmp2,tmp3,tmp4,M0; Image im; Graphics offscreen; /* - - - - - - - - - - - - - - - - - - - - - - */ Rotator(Applet applet,HBlock solid_,int width,int height) { solid = solid_; W = width; H = height; M0 = new O4matrix(); tmp = new O4matrix(); tmp2 = new O4matrix(); tmp3 = new O4matrix(); tmp4 = new O4matrix(); angle0 = 0; delay = 100; resize(W,H); im = applet.createImage(W,H); background = Color.lightGray; setBackground(background); offscreen = im.getGraphics(); spin = true; xdir=0; ydir=1; odir=2; } /* - - - - - - - - - - - - - - - - - - - - - - */ public void paint(Graphics g) { update(g); } public void update(Graphics g) { offscreen.setColor(background); offscreen.fillRect(0, 0, W, H); solid.Draw(offscreen,(int)(W/2),(int)(H/2),bounce); g.drawImage(im, 0, 0, null); } /* - - - - - - - - - - - - - - - - - - - - - - */ public void run(){ keep_going = true; angle=0; while(keep_going && spin){ /* .. modify bounce and solid.orient .. */ angle += 0.1; tmp3.Rotation(1,2,angle); tmp2.Rotation(1,0,angle*CON1); tmp.Rotation(0,3,angle*CON3); tmp4.Rotation(1,3,angle*CON2); solid.orient = tmp4.Times(tmp.Times(tmp3.Times(tmp2.Times(tmp.Times(M0))))); bounce = 2*((angle+angle0)/4 - Math.floor((angle+angle0)/4)) - 1; bounce = 1-bounce*bounce*2; repaint(); try {Thread.sleep(delay);} catch (InterruptedException e){} } } /* - - - - - - - - - - - - - - - - - - - - - - */ public boolean mouseUp(java.awt.Event evt, int x, int y) { if (spin) start(); return true; } /* - - - - - - - - - - - - - - - - - - - - - - */ public boolean mouseDown(java.awt.Event evt, int x, int y) { stop(); try {Thread.sleep(delay*2);} catch (InterruptedException e){} M0 = solid.orient; angle0 += angle; angle = 0; oldx = x; oldy = y; return true; } /* - - - - - - - - - - - - - - - - - - - - - - */ public boolean mouseDrag(java.awt.Event evt, int x, int y) { tmp2.Rotation(xdir,odir,(x - oldx) * Math.PI/ solid.W); tmp.Rotation(ydir,odir,(oldy - y) * Math.PI/ solid.H); M0 = tmp.Times(tmp2.Times(M0)); solid.orient = M0; oldx = x; oldy = y; repaint(); return true; } /* - - - - - - - - - - - - - - - - - - - - - - */ public void stop() { kicker = null; keep_going = false; } /* - - - - - - - - - - - - - - - - - - - - - - */ public void start() { if (kicker == null){ kicker = new Thread(this); kicker.start(); } } }