//PiToothpicks.java import java.awt.*; import java.awt.event.*; import javax.swing.*; public class PiToothpicks extends JApplet implements ActionListener { private JLabel linesLabel, toothpickLabel; private JTextField linesField, toothpickField; private JButton againButton; public void init() { Container container = getContentPane(); container.setLayout( new FlowLayout() ); linesLabel = new JLabel( "Number of grid lines" ); linesField = new JTextField( "10", 4 ); container.add( linesLabel ); container.add( linesField ); linesField.addActionListener( this ); toothpickLabel = new JLabel( "Number of toothpicks to drop randomly" ); toothpickField = new JTextField( "100", 4 ); container.add( toothpickLabel ); container.add( toothpickField ); toothpickField.addActionListener( this ); againButton = new JButton( "Again!" ); container.add( againButton ); againButton.addActionListener( this ); } public void actionPerformed( ActionEvent event ) { repaint(); } public void paint( Graphics g ) { super.paint( g ); int x1, y1, x2, y2; double angle; int xcenter, ycenter; int toothpicks; int gridlines; int length; int[] y; int k; double distanceToLine; int M=0; double projectionLength; gridlines = Integer.parseInt(linesField.getText()); y = new int[gridlines+1]; length = getHeight() / gridlines; g.setColor( Color.CYAN); for (int i=1; i<=gridlines; i++) { y[i] = getHeight()/gridlines*i; g.drawLine(0,y[i],getWidth(),y[i]); } toothpicks = Integer.parseInt(toothpickField.getText()); g.setColor(Color.BLACK); for (int i=1; i<=toothpicks; i++) { x1 = (int)(Math.random() * getWidth()); y1 = (int)(Math.random() * getHeight()); angle = Math.random() * 2 * Math.PI; //radians x2 = (int)(Math.cos(angle) * length + x1); y2 = (int)(Math.sin(angle) * length + y1); ycenter = (y1 + y2) / 2; //find closest line k = 0; distanceToLine = ycenter; //find nearest grid line to this line's y center. while (k<=gridlines && Math.abs(ycenter - y[k]) <= distanceToLine) distanceToLine = Math.abs(ycenter - y[k++]); //projectionLength = Math.sin(angle) * length; projectionLength = Math.abs(Math.sin(angle) * 0.5 * length); if (projectionLength > distanceToLine) { M++; g.setColor(Color.RED); } else g.setColor(Color.BLACK); g.drawLine(x1,y1,x2,y2); } showStatus("2 * #toothpicks / #intersections = " + 2.0*toothpicks/M + " M=" + M); } }