HirstDots.java
1    package npw;
2    
3    import painter.SPainter;
4    import shapes.SCircle;
5    
6    import javax.swing.*;
7    import java.awt.*;
8    import java.util.Random;
9    import java.util.Scanner;
10   
11   public class HirstDots {
12   
13       private void paintTheImage () {
14           //Get the input info
15           int radius = getNumber("circle radius");
16           int diameter = getNumber("dot radius");
17   
18           //Establish the painter
19           SPainter painter = new SPainter("Hirst Dots", radius * 2 + 50, radius * 2 + 50);
20           painter.setBrushWidth(3);
21           SCircle circle = new SCircle(radius);
22           SCircle dot = new SCircle(diameter/2);
23   
24           //Paint the dots
25           paintCircleOfDots(painter, circle, dot);
26       }
27       private void paintCircleOfDots(SPainter painter, SCircle circle, SCircle dot) {
28           //Position the painter to begin drawing the rows
29           painter.mfd(circle.radius());
30           painter.tr();
31           // Paint the circle of dots
32           double moved = 0;
33           while (moved < circle.diameter()) {
34               double chord = chordLength(circle.radius() - moved, circle);
35               int dots = dotOnLineCount(chord, dot.diameter()/2);
36               paintRow(painter, dot, dots);
37               nextRow(painter, (dot.diameter()/2));
38               moved = moved + (dot.diameter()/2);
39           }
40   
41           //Make the method invariant with respect to painter position
42           painter.tl();
43           painter.mfd(circle.radius());
44       }
45       //Move to the next row
46       private void nextRow(SPainter painter, double rowHeight) {
47           painter.tr();
48           painter.mfd(rowHeight);
49           painter.tl();
50       }
51   
52       //Assumes the painter is at the center of the row to paint, facing right.
53       private void paintRow(SPainter painter, SCircle dot, int dotsToPaint){
54           //Move backward 1/2 of the length we're painting to get ready to paint the row.
55           double centerOffset = ((dotsToPaint * dot.diameter()/4) - dot.diameter()/4);
56           painter.mbk(centerOffset);
57   
58           //Paint the row of dots.
59           int painted = 0;
60           while (painted < dotsToPaint) {
61               paintOneDot(painter, dot);
62               painter.mfd(dot.diameter()/2);
63               painted = painted + 1;
64           }
65   
66           //Make the method invariant with respect to painter position.
67           painter.mbk(centerOffset + (dot.diameter()/2));
68       }
69   
70       private void paintOneDot(SPainter painter, SCircle dot) {
71           dot.s3();
72           painter.setColor(randomColor());
73           painter.paint(dot);
74           dot.x3();
75       }
76   
77       private static int dotOnLineCount(double lineLength, double diameterLength) {
78           int dots = ((int)Math.ceil((lineLength - diameterLength) / diameterLength) + 1);
79           return dots;
80       }
81   
82       private double chordLength(double yOffset, SCircle circle){
83           double xLength = Math.sqrt(Math.pow(circle.radius(), 2) - Math.pow(yOffset, 2));
84           double chordLength = xLength * 2;
85           return chordLength;
86       }
87   
88       private static int getNumber(String prompt) {
89           String nss = JOptionPane.showInputDialog(null,prompt + "?");
90           Scanner scanner = new Scanner(nss);
91           return scanner.nextInt();
92       }
93   
94       private static Color randomColor() {
95           Random rgen = new Random();
96           int r = rgen.nextInt(256);
97           int g = rgen.nextInt(256);
98           int b = rgen.nextInt(256);
99           return new Color(r,g,b);
100      }
101  
102      public HirstDots() {
103          paintTheImage();
104      }
105  
106      public static void main(String[] args) {
107          SwingUtilities.invokeLater(new Runnable() {
108              @Override
109              public void run() {
110                  new HirstDots();
111              }
112          });
113      }
114  }
115