import java.awt.*; import java.awt.event.*; import java.lang.*; import java.lang.Math; public class Projectile1 extends java.applet.Applet implements Runnable { Canvas oscillators; Label launchAngleLabel, vZeroLabel, aGravLabel, launchAngleS, vZeroS; TextField aGrav; Button Start, Reset; Thread runner; Scrollbar launchAnglescroll, vZeroscroll; int launchAngle, vZero, ballDiameter, index, ballRadius; int[] xpos = new int[102]; double[] x = new double[102]; int[] ypos = new int[102]; double[] y = new double[102]; double g, vInt, vIntX, vIntY, vY, dropTime, maxHeight, range, maxTime, launchA, currentX, currentY; double pi = 3.141592653589793238468; Image offscreenImg; Graphics offscreenG; boolean startFlag; boolean pauseFlag; void buildConstraints(GridBagConstraints gbc, int gx, int gy, int gw, int gh, int wx, int wy) { gbc.gridx = gx; gbc.gridy = gy; gbc.gridwidth = gw; gbc.gridheight = gh; gbc.weightx = wx; gbc.weighty = wy; } public void init() { GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints constraints = new GridBagConstraints(); setLayout(gridbag); // Initial velocity text buildConstraints(constraints, 0, 0, 1, 1, 20, 5); constraints.fill = GridBagConstraints.NONE; constraints.anchor = GridBagConstraints.EAST; Label vZeroLabel = new Label("Initial velocity (m/s):", Label.CENTER); gridbag.setConstraints (vZeroLabel, constraints); add(vZeroLabel); // Initial velocity scrollbar label buildConstraints(constraints, 2, 0, 1, 1, 20, 0); constraints.fill = GridBagConstraints.HORIZONTAL; vZeroS = new Label("25", Label.LEFT); vZero = 25; gridbag.setConstraints (vZeroS, constraints); add(vZeroS); // Initial velocity scrollbar buildConstraints(constraints, 1, 0, 1, 1, 20, 0); constraints.fill = GridBagConstraints.HORIZONTAL; constraints.anchor = GridBagConstraints.WEST; vZeroscroll = new Scrollbar(Scrollbar.HORIZONTAL, 25, 5, 0, 100); gridbag.setConstraints (vZeroscroll, constraints); add(vZeroscroll); // launch angle text buildConstraints(constraints, 0, 1, 1, 1, 20, 5); constraints.fill = GridBagConstraints.NONE; constraints.anchor = GridBagConstraints.EAST; Label launchAngleLabel = new Label("Launch angle (degrees):", Label.CENTER); gridbag.setConstraints (launchAngleLabel, constraints); add(launchAngleLabel); // launch angle scrollbar label buildConstraints(constraints, 2, 1, 1, 1, 20, 0); constraints.fill = GridBagConstraints.HORIZONTAL; launchAngleS = new Label("45", Label.LEFT); launchAngle = 45; gridbag.setConstraints (launchAngleS, constraints); add(launchAngleS); // launch angle scrollbar buildConstraints(constraints, 1, 1, 1, 1, 20, 0); constraints.fill = GridBagConstraints.HORIZONTAL; constraints.anchor = GridBagConstraints.WEST; launchAnglescroll = new Scrollbar(Scrollbar.HORIZONTAL, 45, 5, 0, 90); gridbag.setConstraints (launchAnglescroll, constraints); add(launchAnglescroll); // g label buildConstraints(constraints, 0, 2, 1, 1, 20, 5); constraints.fill = GridBagConstraints.NONE; constraints.anchor = GridBagConstraints.EAST; Label labelk = new Label("Acceleration due to gravity (between 0.1 and 100 m/s^2):", Label.RIGHT); gridbag.setConstraints (labelk, constraints); add(labelk); // k textbox buildConstraints(constraints, 1, 2, 1, 1, 0, 0); constraints.fill = GridBagConstraints.NONE; constraints.anchor = GridBagConstraints.CENTER; aGrav = new TextField("9.8", 6); g = 9.8; gridbag.setConstraints (aGrav, constraints); add(aGrav); // Start button buildConstraints(constraints, 0, 3 , 1, 1, 0, 10); constraints.fill = GridBagConstraints.NONE; constraints.anchor = GridBagConstraints.EAST; Start = new Button(" Start "); gridbag.setConstraints (Start, constraints); add(Start); // Reset button buildConstraints(constraints, 1, 3 , 1, 1, 0, 10); constraints.fill = GridBagConstraints.HORIZONTAL; constraints.anchor = GridBagConstraints.WEST; Reset = new Button("Reset"); gridbag.setConstraints (Reset, constraints); add(Reset); // canvas buildConstraints(constraints, 0, 4, 3, 1, 0, 80); constraints.fill = GridBagConstraints.HORIZONTAL; oscillators = new Canvas(); gridbag.setConstraints (oscillators, constraints); add(oscillators); offscreenImg = createImage(this.size().width, this.size().height); offscreenG = offscreenImg.getGraphics(); } public void start() { if (runner == null); { runner = new Thread(this); runner.start(); } } public void stop() { if (runner != null) { runner.stop(); runner = null; } } public void run() { double deltat, junk, xScale, yScale, scale, xOrigin, yOrigin, kAngle; Double temp; deltat=0.1; ballDiameter = 16; ballRadius = 7; kAngle = pi/180.0; yOrigin = 380.0; xOrigin = 20.0; startFlag = false; pauseFlag = false; while (true) { index = 0; currentX = 0.0; currentY = 0.0; dropTime = 0.0; vInt = vZero; launchA = kAngle*launchAngle; x[0] = xOrigin-ballDiameter; xpos[0] = (int)(x[0]); y[0] = yOrigin-ballDiameter; ypos[0] = (int)(y[0]); temp = Double.valueOf(aGrav.getText()); g = temp.doubleValue(); if (g < 0.1) g = 0.1; if (g > 100.0) g = 100.0; g = -g; vIntX = vInt*Math.cos(launchA); vIntY = vInt*Math.sin(launchA); vY = vIntY; maxHeight = -0.5*vInt*vInt/g; maxTime = -vInt/g; range = vInt*maxTime; xScale = 10.0; if (range > 0.0) xScale = 280.0/range; yScale = 10.0; if (maxHeight > 0.0) yScale = 160.0/maxHeight; scale = xScale; if (yScale < xScale) scale = yScale; if (maxTime > 10.0) deltat = (1.0+(int)(maxTime/10))/10.0; maxHeight = -0.5*vIntY*vIntY/g; maxTime = -2.0*vIntY/g; range = vIntX*maxTime; while (pauseFlag) { while (startFlag) { index = index +1; dropTime = dropTime + deltat; currentX = vIntX*dropTime; x[index] = x[0]+scale*currentX; currentY = dropTime*(vIntY+0.5*g*dropTime); y[index] = y[0]-scale*currentY; vY = vIntY+g*dropTime; if (y[index]>y[0]) { currentX = range; x[index] = x[0]+scale*range; currentY = 0.0; y[index] = y[0]; vY = -vIntY; dropTime = maxTime; startFlag = false; pauseFlag = true; } xpos[index] = (int)(x[index]); ypos[index] = (int)(y[index]); repaint(); try { Thread.sleep(300); } catch (InterruptedException e) { } } } repaint(); try { Thread.sleep(1); } catch (InterruptedException e) { } } } public void update(Graphics g) { paint(g); } public void paint(Graphics g) { int i; // Draw background offscreenG.setColor(Color.lightGray); offscreenG.fillRect(0,0,500,200); offscreenG.setColor(Color.white); offscreenG.fillRect(0,200,500,400); // Draw mass offscreenG.setColor(Color.black); offscreenG.drawLine(10, 380, 299, 380); offscreenG.setColor(Color.blue); for (i=0; i