//
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;
}
}