1 /* 2 *A program to paint, centered on the canvas, a circle of randomlt 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 HirstSquares { 17 18 private void paintTheImage () { 19 //GEt the input info 20 int radius = getNumber("circle radius"); 21 int side = getNumber("square side length"); 22 23 //Establish the painter 24 SPainter painter = new SPainter("Hirst Square", 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 paintHirstSquares(painter, circle, square); 31 } 32 private void paintHirstSquares(SPainter painter, SCircle circle, SSquare square) { 33 //Position the painter to begin drawing the rows 34 painter.mfd(circle.radius()); 35 painter.tr(); 36 // Paint the circle of squares 37 double moved = 0; 38 while (moved < circle.diameter()) { 39 double chord = chordLength(circle.radius() - moved, circle); 40 int squares = squareOnLineCount(chord, square.side()); 41 paintRow(painter, square, squares); 42 nextRow(painter, square.side()); 43 moved = moved + square.side(); 44 } 45 46 //Make the method invariant with respect to painter position 47 painter.tl(); 48 painter.mfd(circle.radius()); 49 } 50 //Move to the next row 51 private void nextRow(SPainter painter, double rowHeight) { 52 painter.tr(); 53 painter.mfd(rowHeight); 54 painter.tl(); 55 } 56 57 //Assumes the painter is at the center of the row to paint, facing right. 58 private void paintRow(SPainter painter, SSquare square, int squaresToPaint){ 59 //Move backward 1/2 of the length we're painting to get ready to paint the row. 60 double centerOffset = ((squaresToPaint * square.side())/2) - square.side()/2; 61 painter.mbk(centerOffset); 62 63 //Paint the row of squares. 64 int painted = 0; 65 while (painted < squaresToPaint) { 66 paintOneSquare(painter, square); 67 painter.mfd(square.side()); 68 painted = painted + 1; 69 } 70 71 //Make the method invariant with respect to painter position. 72 painter.mbk(centerOffset + square.side()); 73 } 74 75 private void paintOneSquare(SPainter painter, SSquare square) { 76 square.s2(); 77 painter.setColor(randomColor()); 78 painter.paint(square); 79 painter.setColor(Color.BLACK); 80 painter.draw(square); 81 square.x2(); 82 83 84 85 } 86 87 private static int squareOnLineCount(double lineLength, double sideLength) { 88 int squares = ((int)Math.ceil((lineLength - sideLength) / sideLength) + 1); 89 return squares; 90 } 91 92 private double chordLength(double yOffset, SCircle circle){ 93 double xLength = Math.sqrt(Math.pow(circle.radius(), 2) - Math.pow(yOffset, 2)); 94 double chordLength = xLength * 2; 95 return chordLength; 96 } 97 98 private static int getNumber(String prompt) { 99 String nss = JOptionPane.showInputDialog(null,prompt + "?"); 100 Scanner scanner = new Scanner(nss); 101 return scanner.nextInt(); 102 } 103 104 private static Color randomColor() { 105 Random rgen = new Random(); 106 int r = rgen.nextInt(256); 107 int g = rgen.nextInt(256); 108 int b = rgen.nextInt(256); 109 return new Color(r,g,b); 110 } 111 112 public HirstSquares() { 113 paintTheImage(); 114 } 115 116 public static void main(String[] args) { 117 SwingUtilities.invokeLater(new Runnable() { 118 @Override 119 public void run() { 120 new HirstSquares(); 121 } 122 }); 123 } 124 } 125 126