import java.awt.*; import java.awt.event.*; import java.lang.*; import java.lang.Math; import java.text.*; public class Circular2 extends java.applet.Applet implements Runnable { Canvas oscillators; Label ballMassLabel, stringTensionLabel, ballMassS, stringTensionS; Button Start; Thread runner; Scrollbar ballMassscroll, stringTensionscroll; int xpos, ypos, ballMass, stringTension, ballDiameter, ballRadius, yLine, ovalX1, ovalX2, ovalY1, ovalY2; double x, y, ballM, ballW, ballV, tension, tX, tY, stringA, radius; double pi = 3.141592653589793238468; Image offscreenImg; Graphics offscreenG; boolean startFlag; 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 mass text buildConstraints(constraints, 0, 0, 1, 1, 20, 5); constraints.fill = GridBagConstraints.NONE; constraints.anchor = GridBagConstraints.EAST; Label ballMassLabel = new Label("Mass of the ball (grams):", Label.CENTER); gridbag.setConstraints (ballMassLabel, constraints); add(ballMassLabel); // ball mass scrollbar label buildConstraints(constraints, 2, 0, 1, 1, 20, 0); constraints.fill = GridBagConstraints.HORIZONTAL; ballMassS = new Label("800", Label.LEFT); ballMass = 800; gridbag.setConstraints (ballMassS, constraints); add(ballMassS); // ball mass scrollbar buildConstraints(constraints, 1, 0, 1, 1, 20, 0); constraints.fill = GridBagConstraints.HORIZONTAL; constraints.anchor = GridBagConstraints.WEST; ballMassscroll = new Scrollbar(Scrollbar.HORIZONTAL, 800, 20, 100, 1000); gridbag.setConstraints (ballMassscroll, constraints); add(ballMassscroll); // string tension text buildConstraints(constraints, 0, 1, 1, 1, 20, 5); constraints.fill = GridBagConstraints.NONE; constraints.anchor = GridBagConstraints.EAST; Label stringTensionLabel = new Label("Tension in the string(N):", Label.CENTER); gridbag.setConstraints (stringTensionLabel, constraints); add(stringTensionLabel); // string tension scrollbar label buildConstraints(constraints, 2, 1, 1, 1, 20, 0); constraints.fill = GridBagConstraints.HORIZONTAL; stringTensionS = new Label("15", Label.LEFT); stringTension = 15; gridbag.setConstraints (stringTensionS, constraints); add(stringTensionS); // string tension scrollbar buildConstraints(constraints, 1, 1, 1, 1, 20, 0); constraints.fill = GridBagConstraints.HORIZONTAL; constraints.anchor = GridBagConstraints.WEST; stringTensionscroll = new Scrollbar(Scrollbar.HORIZONTAL, 15, 1, 10, 20); gridbag.setConstraints (stringTensionscroll, constraints); add(stringTensionscroll); // Start button buildConstraints(constraints, 1, 2 , 1, 1, 0, 10); constraints.fill = GridBagConstraints.HORIZONTAL; constraints.anchor = GridBagConstraints.WEST; Start = new Button("Start"); gridbag.setConstraints (Start, constraints); add(Start); // canvas buildConstraints(constraints, 0, 3, 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() { int i, temp; double xOrigin, yOrigin, xScale, yScale, kAngle, t, deltat, yL, stringL; ballDiameter = 16; ballRadius = 8; yOrigin = 250.0; xOrigin = 150.0; kAngle = pi/180.0; deltat = 0.02; startFlag = false; while (true) { t = 0.0; ballM = ballMass/1000.0; ballW = ballM*9.8; tension = stringTension; stringL = 0.5; ballV = Math.sqrt(tension/(ballM*stringL)); tY = ballW; tX = Math.sqrt(tension*tension - tY*tY); stringA = (Math.atan(tX/tY)); radius = 100.0*stringL*Math.sin(stringA); xScale = 2.0*radius; yL = 200.0*stringL*Math.cos(stringA); yLine = (int)(yL); yScale = 0.3*xScale; stringA = stringA / kAngle; x = xOrigin-xScale; xpos = (int)(x); y = yOrigin+yLine; ypos = (int)(y); ovalX1 = xpos; ovalX2 = (int)(xOrigin+xScale); ovalY1 = (int)(y-yScale); ovalY2 = (int)(y+yScale); while (startFlag) { while (startFlag) { t = t+deltat; x = xOrigin-xScale*Math.cos(ballV*t); y = yOrigin+yLine+yScale*Math.sin(ballV*t); xpos = (int)(x); ypos = (int)(y); repaint(); try { Thread.sleep(100); } 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 NumberFormat nf = NumberFormat.getInstance(); nf.setMaximumFractionDigits(4); offscreenG.setColor(Color.black); offscreenG.drawOval(ovalX1,ovalY1,ovalX2-ovalX1,ovalY2-ovalY1); offscreenG.drawString("Radius of path = " + nf.format(radius) + " cm", 310, 360); offscreenG.setColor(Color.blue); offscreenG.drawLine(150, 250,xpos, ypos); offscreenG.drawString("Tension in the string", 310, 240); offscreenG.drawString("X component : Tx = " + nf.format(tX) + " N", 320, 260); offscreenG.drawString("Y component : Ty = " + nf.format(tY) + " N", 320, 280); offscreenG.drawString("magnitude : T = " + nf.format(tension) + " N", 320, 300); offscreenG.drawString("Angle of string = " + nf.format(stringA) + " degrees", 310, 320); offscreenG.setColor(Color.red); offscreenG.drawString("Weight of the ball = " + nf.format(ballW) + " N", 310, 220); offscreenG.drawString("Ball speed = " + nf.format(radius*ballV/100.0) + " m/s", 310, 340); if (ypos>250+yLine) { offscreenG.setColor(Color.blue); offscreenG.drawLine(150, 250+yLine,150, 250); offscreenG.setColor(Color.red); offscreenG.fillOval(xpos-ballRadius,ypos-ballRadius,ballDiameter,ballDiameter); } else { offscreenG.setColor(Color.red); offscreenG.fillOval(xpos-ballRadius,ypos-ballRadius,ballDiameter,ballDiameter); offscreenG.setColor(Color.blue); offscreenG.drawLine(150, 250+yLine,150, 250); } g.drawImage(offscreenImg,0,0,this); } public void destroy() { offscreenG.dispose(); } public boolean action (Event evt, Object arg) { if (evt.target instanceof Button) { if ((Button)evt.target == Start) { if (Start.getLabel().equals("Start")) { startFlag = true; Start.setLabel("Reset"); } else { startFlag = false; Start.setLabel("Start"); } } } else return super.action(evt, arg); return true; } public boolean handleEvent(Event evt) { if (evt.target instanceof Scrollbar) { if ((Scrollbar)evt.target == ballMassscroll) { ballMass = ((Scrollbar)evt.target).getValue(); ballMassS.setText(String.valueOf(ballMass)); } else if ((Scrollbar)evt.target == stringTensionscroll) { stringTension = ((Scrollbar)evt.target).getValue(); stringTensionS.setText(String.valueOf(stringTension)); } repaint(); } else return super.handleEvent(evt); return true; } }