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