import java.awt.*;
import java.applet.*;
import java.lang.*;
public class SpringMass extends Applet
{
Graphics sG;
Graphics bG;
Image bI;
Graphics cG;
Image cI;
Color back = new Color(247, 243, 234);
Color pback = new Color(192, 255, 192);
Color plines = new Color(0, 255, 0);
Color tback = new Color(255, 192, 128);
Color tlines = new Color(192, 96, 0);
Color positiveback = new Color(255, 128, 128);
Color negativeback = new Color(192, 192, 255);
Color positive = new Color(255, 0, 0);
Color negative = new Color(64, 64, 255);
Color black = new Color(0, 0, 0);
Color grey = new Color(128, 128, 128);
Color magenta = new Color(255, 0, 0);
int bottom = 60;
int width = 481;
int height = 261;
double ytop = 1.0;
double ttop = 18.8495;
int n = 100;
double h = ttop/(n * 200);
double newx, oldx, qx;
double startx = 1.0;
double newv, oldv, qv;
double startv = 0.0;
double friction = 0.0;
int ifriction = bottom + 100;
public void init()
{
bI = createImage(this.size().width, this.size().height);
bG = bI.getGraphics();
cI = createImage(this.size().width, this.size().height);
cG = cI.getGraphics();
drawback();
cG.drawImage(bI, 0, 0, this);
drawcart(startx, startv);
}
public void paint(Graphics g)
{
g.drawImage(cI, 0, 0, this);
sG = getGraphics();
}
public void update(Graphics g)
{
g.drawImage(cI, 0, 0, this);
}
public int yscale(double y)
{
int z;
z = (int) (bottom + java.lang.Math.round(100.0 * (1.0 - y)/ytop));
return z;
}
public int tscale(double t)
{
int z;
z = (int) java.lang.Math.round(200.0 * t / ttop);
return z;
}
public int xscale(double x)
{
int z;
z = (int) (320 + java.lang.Math.round(100.0 * x/ytop));
return z;
}
public void drawcart(double x, double v)
{
double dx;
cG.setColor(tlines);
cG.fillRect(xscale(x) - 20, 10, 41, 27);
cG.setColor(black);
cG.fillOval(xscale(x) - 15, 32, 9, 9);
cG.fillOval(xscale(x) + 7, 32, 9, 9);
cG.fillOval(xscale(x) - 2, yscale(v) - 2, 5, 5);
cG.drawLine(xscale(x), 15, xscale(x), 36);
cG.drawLine(xscale(x) - 4, 32, xscale(x) + 4, 32);
cG.drawLine(xscale(x) - 3, 33, xscale(x) + 3, 33);
cG.drawLine(xscale(x) - 2, 34, xscale(x) + 2, 34);
cG.drawLine(xscale(x) - 1, 35, xscale(x) + 1, 35);
dx = (((xscale(x) - 20) * ytop - 320 * ytop)/100 + 3.09)/62;
cG.drawLine(xscale(-3.09), 25, xscale(-3.09 + dx), 15);
cG.drawLine(xscale(x) - 20, 25, xscale(x - dx) - 20, 15);
for (int i = 0; i < 30; i = i + 2)
{
cG.drawLine(xscale(-3.09 * ytop + 2 * i * dx + dx), 15,
xscale(-3.09 * ytop + 2 * i * dx + 3 * dx), 35);
cG.drawLine(xscale(-3.09 * ytop + 2 * i * dx + 3 * dx), 35,
xscale(-3.09 * ytop + 2 * i * dx + 5 * dx), 15);
}
}
public void drawback()
{
bG.setColor(back);
bG.fillRect(0, 0, width, height);
bG.setColor(tback);
bG.fillRect(0, bottom, 201, 201);
bG.setColor(tlines);
for (int i = 0; i < 201; i = i + 20)
{
bG.drawLine(0, yscale(ytop) + i, 200, yscale(ytop) + i);
bG.drawLine(i, yscale(-ytop), i, yscale(ytop));
}
bG.setColor(pback);
bG.fillRect(220, bottom, 201, 201);
bG.setColor(plines);
for (int i = 0; i < 201; i = i + 20)
{
bG.drawLine(220, yscale(ytop) + i, 420, yscale(ytop) + i);
bG.drawLine(220 + i, yscale(-ytop), 220 + i, yscale(ytop));
}
bG.setColor(negativeback);
bG.fillRect(440, bottom, 41, 101);
bG.setColor(positiveback);
bG.fillRect(440, bottom + 100, 41, 101);
bG.setColor(negative);
if (ifriction == bottom + 100)
{ bG.setColor(grey); }
if (ifriction > bottom + 100)
{ bG.setColor(positive); }
bG.fillRect(455, ifriction, 11, height - ifriction);
bG.setColor(black);
bG.drawLine(460, bottom, 460, bottom + 200);
for (int i = 0; i < 201; i = i + 10)
{
bG.drawLine(450, bottom + i, 470, bottom + i);
}
bG.drawLine(440, bottom + 100, 480, bottom + 100);
bG.setColor(grey);
bG.fillRect(0, 0, 11, 41);
bG.fillRect(0, 40, width, 11);
}
public boolean mouseDown(Event evt, int mx, int my)
{
if ((my > bottom - 1) && (mx > 440))
{
friction = (bottom +100 - my)/500.0;
ifriction = my;
drawback();
cG.drawImage(bI, 0, 0, this);
drawback();
sG.drawImage(cI, 0, 0, this);
return true;
}
if (mx > 219)
{
startx = ytop * (mx - 320)/100;
startv = 0;
if (my > bottom)
{
startv = -ytop * (my - bottom - 100)/100;
}
drawback();
cG.drawImage(bI, 0, 0, this);
drawcart(startx, startv);
sG.drawImage(cI, 0, 0, this);
return true;
}
if ((my > bottom) && (mx < 201))
{
simulate();
}
return true;
}
public void simulate()
{
double t = 0;
oldx = startx;
oldv = startv;
drawback();
cG.drawImage(bI, 0, 0, this);
drawcart(startx, startv);
sG.drawImage(cI, 0, 0, this);
for (int i = 0; i < 201; i = i + 1)
{
bG.setColor(black);
qx = oldx;
qv = oldv;
for (int j = 0; j < n; j = j + 1)
{
newx = qx + h * qv;
newv = qv - h * (qx + friction * qv);
qx = newx;
qv = newv;
}
bG.drawLine(xscale(oldx), yscale(oldv),
xscale(newx), yscale(newv));
bG.drawLine(tscale(t), yscale(oldx),
tscale(t + n * h), yscale(newx));
bG.setColor(magenta);
bG.drawLine(tscale(t), yscale(oldv),
tscale(t + n * h), yscale(newv));
oldx = newx;
oldv = newv;
t = t + n * h;
cG.drawImage(bI, 0, 0, this);
drawcart(newx, newv);
sG.drawImage(cI, 0, 0, this);
}
}
}
Copyright c 1997 by
Frank Wattenberg, Department of Mathematics, Montana State University,
Bozeman, MT 59717