import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.border.*; import java.util.*; import java.text.*; public class MultiIncline extends JPanel implements MouseInputListener { String statusStr = ""; boolean designMode = false; // If in design mode, corners can be moved. int radius = 10; // Radius of bead. int numSegments = 2; // Number of segments in incline. double maxX = 400; // x3 double[] segx, segy; // Store x and y values of intermediate points. // Variables tied to the current segment (where the bead is now). int currentSeg = -1; double cosineOfCurrentAngle; double sineOfCurrentAngle; // The usual physical variables. double m = 1; double ax, ay; double vx, vy; double x,y; double g = 9.8; int time; // Animation: int sleepTime = 100; int timeStep = sleepTime; boolean stopped = true; // GUI: String terminateMsg = ""; DecimalFormat df = new DecimalFormat ("##.##"); JTextField segmentsField; int currentBeingDragged = -1; public MultiIncline () { initSegments (); this.addMouseListener (this); this.addMouseMotionListener (this); } void initSegments () { segx = new double [numSegments + 1]; segy = new double [numSegments + 1]; // Initialize the x and y parts. double interval = maxX / numSegments; // Leftmost point (the start). segx[0] = 0; segy[0] = maxX; // Intermediate points along straight line. for (int i=1; i= segx[currentSeg+1]) { // Change to new segment. currentSeg ++; double hyp = distance (segx[currentSeg],segy[currentSeg], segx[currentSeg+1],segy[currentSeg+1]); double yDiff = Math.abs (segy[currentSeg] - segy[currentSeg+1]); double xDiff = Math.abs (segx[currentSeg] - segx[currentSeg+1]); cosineOfCurrentAngle = xDiff / hyp; sineOfCurrentAngle = yDiff / hyp; a = g * sineOfCurrentAngle; // Now conserve energy double v = Math.sqrt (vx*vx + vy*vy); vx = v * cosineOfCurrentAngle; vy = - v * sineOfCurrentAngle; } // Horizontal and vertical accelerations. ax = a * cosineOfCurrentAngle; ay = - a * sineOfCurrentAngle; // Increase velocity accordingly. vx = vx + delT * ax; vy = vy + delT * ay; // Increase distance according to velocity. x = x + delT * vx; y = y + delT * vy; // If we're close enough to the end, stop. if (x >= (maxX - 0.01)) { break; } // Redraw. repaint (); } } public void paintComponent (Graphics g) { super.paintComponent (g); Dimension D = this.getSize (); // Background. g.setColor (Color.white); g.fillRect (0,0, D.width, D.height); // Draw segments. g.setColor (Color.lightGray); for (int i=0; i= 2) && (n != numSegments)) { numSegments = n; initSegments (); } designMode = true; this.repaint (); } catch (Exception e) { } } // These methods are for the mouse-listening interface. public void mouseClicked (MouseEvent e) {} public void mouseEntered (MouseEvent e) {} public void mouseMoved (MouseEvent e) {} public void mouseExited (MouseEvent e) { currentBeingDragged = -1; } public void mousePressed (MouseEvent e) { if (! designMode) { return; } currentBeingDragged = nodeClick (e.getPoint()); } int nodeClick (Point clickPoint) { // See if click is within a circle. Dimension D = this.getSize (); for (int i=1; i segy[currentBeingDragged+1]) ) { segy[currentBeingDragged] = tempY; } this.repaint (); } public void makeFrame () { JFrame frame = new JFrame (); frame.setSize (500, 500); frame.setResizable (true); Container cPane = frame.getContentPane (); cPane.add (this, BorderLayout.CENTER); cPane.add (makeBottomPanel(), BorderLayout.SOUTH); frame.setVisible (true); } JPanel makeBottomPanel () { JPanel panel = new JPanel (); panel.add (new JLabel ("# Segments: ")); segmentsField = new JTextField (4); segmentsField.setText ("2"); panel.add (segmentsField); panel.add (new JLabel (" ")); JButton button = new JButton ("Design"); button.addActionListener ( new ActionListener () { public void actionPerformed (ActionEvent a) { design (); } } ); panel.add (button); panel.add (new JLabel (" ")); button = new JButton ("Go"); button.addActionListener ( new ActionListener () { public void actionPerformed (ActionEvent a) { go (); } } ); panel.add (button); panel.add (new JLabel (" ")); button = new JButton ("Quit"); button.addActionListener ( new ActionListener () { public void actionPerformed (ActionEvent a) { System.exit(0); } } ); panel.add (button); return panel; } public static void main (String[] argv) { MultiIncline m = new MultiIncline (); m.makeFrame (); } }