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