import java.awt.*;
import java.applet.*;
import java.lang.*;
public class Boyle extends Applet
{
Graphics bG; // Graphics buffer
Image bI; // Image buffer
Graphics sG; // Display
Color background = new Color(128, 128, 255); // Background color
Color inside = new Color(255, 255, 255); // Tank color
Color time = new Color(0, 0, 255); // Time gauge color
Color ball = new Color(255, 0, 255); // Ball color
Color wall = new Color(0, 0, 0); // Wall color
Font font = new Font("Courier", Font.PLAIN, 12);
int center = 100; // Tank center
int radius = 80; // Tank radius
int nballs = 20; // Number of balls
int nsteps = 1000; // number of steps
int speed; // Ball speed
int running = 0; // 1 for running
int bounces; // Count bounces;
int i, j, k, ix, iy;
double bx[] = new double[100]; // ball x coord
double by[] = new double[100]; // ball y coord
double vx[] = new double[100]; // ball vel x coord
double vy[] = new double[100]; // ball vel y coord
double s, x, y;
public void init()
{
bI = createImage(this.size().width, this.size().height);
bG = bI.getGraphics(); // Set up graphics buffer
drawbackground();
}
public void paint(Graphics g)
{
g.drawImage(bI, 0, 0, this);
sG = getGraphics(); // Get display
}
public void update(Graphics g)
{
g.drawImage(bI, 0, 0, this);
}
public void drawbackground()
{
bG.setColor(background);
bG.fillRect(0, 0, 421, 201);
bG.setColor(wall);
bG.fillOval(center-radius-5, center-radius-5,
2*radius+11, 2*radius+11);
bG.setColor(inside);
bG.fillOval(center-radius-1, center-radius-1,
2*radius+3, 2*radius+3);
bG.fillRect(210, 20, 91, 21);
bG.fillRect(210, 50, 91, 21);
bG.fillRect(210, 80, 91, 21);
bG.fillRect(320, 20, 91, 21);
bG.fillRect(320, 50, 91, 21);
bG.fillRect(320, 80, 91, 21);
bG.fillRect(210, 110, 201, 20);
bG.fillRect(210, 140, 201, 20);
bG.fillRect(210, 170, 201, 20);
bG.setFont(font);
bG.setColor(wall);
bG.drawString("Rad 1 Sp 1", 216, 35);
bG.drawString("Rad 2 Sp 1", 216, 65);
bG.drawString("Rad 4 Sp 1", 216, 95);
bG.drawString("Rad 1 Sp 2", 326, 35);
bG.drawString("Rad 2 Sp 2", 326, 65);
bG.drawString("Rad 4 Sp 2", 326, 95);
}
public boolean mouseDown(Event evt, int x, int y)
{
if (running == 1)
{ return true; }
if ( (210 < x) && (x < 301))
{ speed = 1; }
if ( (321 < x) && (x < 411))
{ speed = 2; }
if ( (20 < y) && (y < 41))
{ radius = 20; }
if ( (50 < y) && (y < 71))
{ radius = 40; }
if ( (80 < y) && (y < 101))
{ radius = 80; }
simulate();
return true;
}
public void simulate()
{
double sine, cosine, mag, tx, ty;
double ax, ay, cx, cy, mx, my; // For bisection method
j = 0;
running = 1;
bounces = 0;
drawbackground();
bG.setColor(time);
bG.fillRect(210, 140, 201, 20);
sG.drawImage(bI, 0, 0, this);
bG.setColor(ball);
for (i = 0; i < nballs; i = i + 1)
{ x = 10;
y = 10;
while (x*x + y*y > 0.99)
{ x = 2.0 * java.lang.Math.random() - 1.0;
y = 2.0 * java.lang.Math.random() - 1.0;
}
bx[i] = radius * x;
by[i] = radius * y;
ix = (int) java.lang.Math.round(bx[i]);
iy = (int) java.lang.Math.round(by[i]);
bG.fillOval(center + ix - 1, center + iy - 1, 3, 3);
x = 0.0;
y = 0.0;
while (x*x + y*y < 0.1)
{ x = 2.0 * java.lang.Math.random() - 1.0;
y = 2.0 * java.lang.Math.random() - 1.0;
}
s = java.lang.Math.sqrt(x * x + y * y);
vx[i] = speed * x / s;
vy[i] = speed * y / s;
}
sG.drawImage(bI, 0, 0, this);
for (k = 0; k < nsteps; k = k + 1)
{
drawbackground();
bG.setColor(time);
bG.fillRect(210, 140, 201, 20);
bG.setColor(inside);
ix = (int) java.lang.Math.round(201.0 * k / nsteps);
bG.fillRect(210, 140, ix, 20);
bG.setColor(wall);
bG.drawString("Bounces: " + bounces, 216, 185);
bG.setColor(ball);
bG.fillRect(210, 110, j, 20);
for (i = 0; i < nballs; i = i + 1)
{
ax = bx[i];
ay = by[i];
cx = bx[i] + vx[i];
cy = by[i] + vy[i];
bx[i] = cx;
by[i] = cy;
if (cx * cx + cy * cy > radius * radius)
{
mx = (ax + cx)/2;
my = (ay + cy)/2;
for (j = 0; j < 10; j = j + 1)
{ if (mx * mx + my * my < radius * radius)
{ ax = mx;
ay = my;
}
else
{ cx = mx;
cy = my;
}
mx = (ax + cx)/2;
my = (ay + cy)/2;
}
mag = java.lang.Math.sqrt(mx * mx + my * my);
sine = my/mag;
cosine = mx/mag;
tx = cosine * bx[i] + sine * by[i];
ty = -sine * bx[i] + cosine * by[i];
tx = 2 * radius - tx;
bx[i] = cosine * tx - sine * ty;
by[i] = sine * tx + cosine * ty;
tx = cosine * vx[i] + sine * vy[i];
ty = -sine * vx[i] + cosine * vy[i];
tx = -tx;
vx[i] = cosine * tx - sine * ty;
vy[i] = sine * tx + cosine * ty;
bounces = bounces + 1;
bG.setColor(inside);
bG.fillRect(210, 170, 201, 20);
bG.setColor(wall);
bG.drawString("Bounces: " + bounces, 216, 185);
bG.setColor(ball);
tx = 100 * java.lang.Math.abs(tx);
j = (int) java.lang.Math.round(tx);
bG.fillRect(210, 110, j, 20);
}
ix = (int) java.lang.Math.round(bx[i]);
iy = (int) java.lang.Math.round(by[i]);
bG.fillOval(center + ix - 1, center + iy - 1, 3, 3);
}
sG.drawImage(bI, 0, 0, this);
}
running = 0;
}
}
Copyright c 1995 by Frank Wattenberg Department of Mathematics, Montana State University, Bozeman, MT 59717.