//
import java.awt.*; public class sideView extends BufferedApplet { double time0; Graphics g; Color diskColor[] = new Color[256]; // INITIALIZE EVERYTHING public void init() { super.init(); time0 = System.currentTimeMillis() / 1000.; for (int i = 0 ; i < 256 ; i++) diskColor[i] = new Color(0,0,(int)(165+90*Math.cos(.032*i))); } double X = 0, TX = -1, TY = 0, C0 = -10, rate = 1; Color bgColor = new Color(160,160,255); Color feltColor = new Color(0,150,0); Color metalColor = new Color(220,220,220); boolean grabbed = false; // RENDER EVERYTHING public void render(Graphics g) { this.g = g; // COMPUTE STIRRING MOVEMENT double theta = rate*Math.PI * (System.currentTimeMillis()/1000. - time0); double C = .19 * Math.cos(theta); if (C0 == -10) C0 = C; // CLEAR THE BACKGROUND g.setColor(bgColor); g.fillRect(0, 0, width(), height()); // DRAW THE MOVING GRATE g.setColor(Color.black); fillRect(-1.5, -.08, 3,.09); g.setColor(metalColor); for (int i = 0 ; i < 20 ; i++) fillRect(-1.5+C+.15*i, .2, .075,.04); // WHEN MAGNET REACHES DISK, TELL IT TO GRAB THE DISK if (! mouseIsDown && ! grabbed && Math.abs(TX-X) <= .02) { grabbed = true; TX = 0; } // SHOULD MAGNET MOVE WITH THE GRATE? boolean move = C < C0 == TX < X && Math.abs(TX-X) > .02; // IF SO, THEN IT LIFTS UP TO CONTACT THE GRATE double Y = move ? .02 : 0; // DRAW THE ELECTROMAGNET g.setColor(Color.red); fillRect(-.4+X,Y+.01, .8,.16); g.setColor(Color.black); for (double t = .01 ; t <= .17 ; t += .032) fillRect(-.4+X,Y+t, .8,.01); g.setColor(metalColor); fillRect(-.2+X,Y+.015, .4,.155); // DRAW THE TABLE TOP g.setColor(feltColor); fillRect(-1.5,.24,3,.04); // DRAW THE DISK ATOP THE TABLE... double GX = grabbed ? X : TX; for (int i = 0 ; i <= 18 ; i++) { g.setColor(diskColor[i * 255 / 18]); fillRect(-.35 + .035 * i + GX, .28+TY, .071, .4); } // ...AND ITS METAL BASE g.setColor(metalColor); fillRect(-.35+GX,.27+TY, .7,.06); // DRAW THE DIRECTIONAL ARROWS INSIDE THE DISK if (mouseIsDown || Math.abs(TX-X) <= .02) { g.setColor(Color.white); int x = X2x(GX), y = Y2y(.5+TY), s = R2r(.23); for (int t = -s ; t <= s ; t += 2*s) { g.drawLine(x-t,y, x-2*t/5,y); g.drawLine(x-t,y, x-4*t/5,y-t/5); g.drawLine(x-t,y, x-4*t/5,y+t/5); } } X += move ? C - C0 : 0; C0 = C; animating = true; } // RECTANGLE FILL CALLED IN CONTINUOUS WORLD COORDS void fillRect(double x, double y, double w, double h) { g.fillRect(X2x(x),Y2y(y+h),R2r(w),R2r(h)); } // CONVERT BETWEEN CONTINUOUS WORLD COORDS AND PIXEL COORDS int X2x(double X) { return (int)( width ()/2 + width()/4 * X); } int Y2y(double Y) { return (int)(2*height()/3 - width()/4 * Y); } int R2r(double R) { return (int)( width()/4 * R); } double x2X(int x) { return (double)(x - width ()/2) / ( width()/4); } double y2Y(int y) { return (double)(y - 2*height()/3) / (-width()/4); } double r2R(int r) { return (double) r / ( width()/4); } // ALLOW USER TO GRAB AND MOVE THE DISK boolean mouseIsDown = false; int mx, my; public boolean mouseDown(Event e, int x, int y) { mouseIsDown = true; if (x >= X2x(X-.2) && x <= X2x(X+.2)) { TX = X; TY = 0; grabbed = false; } mx = x; return true; } public boolean mouseDrag(Event e, int x, int y) { if (! grabbed) { TX += r2R(x - mx); TY = Math.max(0, TY - r2R(y - my)); mx = x; my = y; } return true; } public boolean mouseUp(Event e, int x, int y) { mouseIsDown = false; TY = 0; return true; } // ALLOW USER TO CONTROL THINGS WITH THE KEYBOARD public boolean keyUp(Event e, int key) { switch (key) { case ' ': rate = rate == 1 ? 6 : 1; // SPACE KEY TOGGLES STIRRING RATE break; case 1006: TX = -1; // LEFT ARROW PUTS DISK ON THE LEFT grabbed = false; break; case 1007: TX = 1; // RIGHT ARROW PUTS DISK ON THE RIGHT grabbed = false; break; } return true; } }