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 class CircleOfSquares { 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("CircleOfSquares", 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 painter.setColor(randomColor()); 73 painter.paint(square); 74 painter.setColor(Color.black); 75 painter.draw(square); 76 } 77 78 private static int squaresOnLineCount(double lineLength, double sideLength) { 79 int squares = ((int)Math.ceil( ( lineLength - sideLength ) / sideLength ) + 1); 80 return squares; 81 } 82 83 private double chordLength(double yOffset, SCircle circle) { 84 double xLength = Math.sqrt(Math.pow(circle.radius(), 2) - Math.pow(yOffset, 2)); 85 double chordLength = xLength*2; 86 return chordLength; 87 } 88 89 private static int getNumber(String prompt) { 90 String nss = JOptionPane.showInputDialog(null,prompt+"?"); 91 Scanner scanner = new Scanner(nss); 92 return scanner.nextInt(); 93 } 94 95 private static Color randomColor() { 96 Random rgen = new Random(); 97 int r = rgen.nextInt(256); 98 int g = rgen.nextInt(256); 99 int b = rgen.nextInt(256); 100 return new Color(r,g,b); 101 } 102 103 public CircleOfSquares() { 104 paintTheImage(); 105 } 106 107 public static void main(String[] args) { 108 SwingUtilities.invokeLater(new Runnable() { 109 public void run() { 110 new CircleOfSquares(); 111 } 112 }); 113 } 114 }