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