1 /* 2 a program to paint, centered on the canvas, a circle of randomly colored, black-framed squares, with spaces. 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 HirstSquares { 17 private void paintTheImage() { 18 // get the input info 19 int radius = getNumber("circle radius"); 20 int side = getNumber("square side length"); 21 // establish painter 22 SPainter painter = new SPainter("HirstSquares", radius*2+50, radius*2+50); 23 painter.setBrushWidth(3); 24 SCircle circle = new SCircle(radius); 25 SSquare square = new SSquare(side); 26 // paint the squares 27 paintCircleOfSquares(painter, circle, square); 28 } 29 30 private void paintCircleOfSquares(SPainter painter, SCircle circle, SSquare square) { 31 // position the painter to begin drawing the rows 32 painter.mfd(circle.radius()); 33 painter.tr(); 34 // paint the circle of squares 35 double moved = 0; 36 while (moved < circle.diameter()) { 37 double chord = chordLength(circle.radius()-moved, circle); 38 int squares = squaresOnLineCount(chord, square.side()); 39 paintRow(painter, square, squares); 40 nextRow(painter, square.side()); 41 moved = moved + square.side(); 42 } 43 // make the method invariant with respect to painter position 44 painter.tl(); 45 painter.mfd(circle.radius()); 46 } 47 48 // move to the next row 49 private void nextRow (SPainter painter, double rowHeight) { 50 painter.tr(); 51 painter.mfd(rowHeight); 52 painter.tl(); 53 } 54 55 // assumes the painter is at the center of the row to paint, facing right. 56 private void paintRow (SPainter painter, SSquare square, int squaresToPaint) { 57 // move backward one half of the length we're painting to get ready to paint the row 58 double centerOffset = ((squaresToPaint*square.side())/2)- square.side()/2; 59 painter.mbk(centerOffset); 60 // paint the row of squares 61 int painted = 0; 62 while (painted < squaresToPaint) { 63 paintOneSquare(painter, square); 64 painter.mfd(square.side()); 65 painted = painted +1; 66 } 67 // make the method invariant with respect to painter position 68 painter.mbk(centerOffset + square.side()); 69 } 70 71 private void paintOneSquare(SPainter painter, SSquare square) { 72 square.shrink(10); 73 painter.setColor(randomColor()); 74 painter.paint(square); 75 painter.setColor(Color.black); 76 painter.draw(square); 77 square.expand(10); 78 } 79 80 private static int squaresOnLineCount(double lineLength, double sideLength) { 81 int squares = ((int)Math.ceil( ( lineLength - sideLength ) / sideLength ) + 1); 82 return squares; 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 HirstSquares() { 106 paintTheImage(); 107 } 108 109 public static void main(String[] args) { 110 SwingUtilities.invokeLater(new Runnable() { 111 public void run() { 112 new HirstSquares(); 113 } 114 }); 115 } 116 }