import java.awt.*; import java.awt.event.*; import java.lang.*; import java.lang.Math; public class Freefall1 extends java.applet.Applet implements Runnable { Canvas oscillators; Label ballHeightLabel, vZeroLabel, aGravLabel, ballHeightS, vZeroS; TextField aGrav; Button Start, Reset; Thread runner; Scrollbar ballHeightscroll, vZeroscroll; int ballHeight, vZero, ballDiameter, ballRadius, index; int[] xpos = new int[102]; double[] x = new double[102]; double g, currentV, dropTime, ballH, intcurrentV, intballH; 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); // ball height text buildConstraints(constraints, 0, 0, 1, 1, 20, 5); constraints.fill = GridBagConstraints.NONE; constraints.anchor = GridBagConstraints.EAST; Label ballHeightLabel = new Label("Initial height of ball (m):", Label.CENTER); gridbag.setConstraints (ballHeightLabel, constraints); add(ballHeightLabel); // ball Height scrollbar label buildConstraints(constraints, 2, 0, 1, 1, 20, 0); constraints.fill = GridBagConstraints.HORIZONTAL; ballHeightS = new Label("4", Label.LEFT); ballHeight = 4; gridbag.setConstraints (ballHeightS, constraints); add(ballHeightS); // ball height scrollbar buildConstraints(constraints, 1, 0, 1, 1, 20, 0); constraints.fill = GridBagConstraints.HORIZONTAL; constraints.anchor = GridBagConstraints.WEST; ballHeightscroll = new Scrollbar(Scrollbar.HORIZONTAL, 4, 1, 0, 10); gridbag.setConstraints (ballHeightscroll, constraints); add(ballHeightscroll); // Initial velocity text buildConstraints(constraints, 0, 1, 1, 1, 20, 5); constraints.fill = GridBagConstraints.NONE; constraints.anchor = GridBagConstraints.EAST; Label vZeroLabel = new Label("Initial velocity, positive down (m/s):", Label.CENTER); gridbag.setConstraints (vZeroLabel, constraints); add(vZeroLabel); // Initial velocity scrollbar label buildConstraints(constraints, 2, 1, 1, 1, 20, 0); constraints.fill = GridBagConstraints.HORIZONTAL; vZeroS = new Label("0", Label.LEFT); vZero = 0; gridbag.setConstraints (vZeroS, constraints); add(vZeroS); // Initial velocity scrollbar buildConstraints(constraints, 1, 1, 1, 1, 20, 0); constraints.fill = GridBagConstraints.HORIZONTAL; constraints.anchor = GridBagConstraints.WEST; vZeroscroll = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, -10, 10); gridbag.setConstraints (vZeroscroll, constraints); add(vZeroscroll); // 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, scale, xOrigin, maxHeight, maxTime; Double temp; deltat=0.1; ballDiameter = 16; ballRadius = 7; scale = 16.0; xOrigin = 380.0; startFlag = false; pauseFlag = false; while (true) { index = 0; dropTime = 0.0; intcurrentV = vZero; intballH = ballHeight; currentV = vZero; ballH = ballHeight; temp = Double.valueOf(aGrav.getText()); g = temp.doubleValue(); if (g < 0.1) g = 0.1; if (g > 100.0) g = 100.0; maxHeight = ballH; if (currentV<0.0) maxHeight = maxHeight + 0.5*currentV*currentV/g; maxTime = 2.0*Math.sqrt(2.0*maxHeight/g); scale = 10.0; if (maxHeight > 0.0) scale = 160.0/maxHeight; if (maxTime > 10.0) deltat = (1.0+(int)(maxTime/10))/10.0; x[0] = xOrigin-scale*intballH-ballDiameter; xpos[0] = (int)(x[0]); while (pauseFlag) { while (startFlag) { index = index + 1; dropTime = dropTime + deltat; ballH = intballH-dropTime*(intcurrentV+0.5*g*dropTime); x[index] = xOrigin-scale*ballH-ballDiameter; currentV = intcurrentV+g*dropTime; if (x[index]>(xOrigin-ballDiameter)) { x[index] = xOrigin-ballDiameter; currentV = Math.sqrt(intcurrentV*intcurrentV+2.0*g*intballH); dropTime = (currentV-intcurrentV)/g; ballH = 0.0; startFlag = false; pauseFlag = true; } xpos[index] = (int)(x[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(50, 380, 150, 380); offscreenG.setColor(Color.blue); for (i=0; i