1 package npw; 2 3 import painter.SPainter; 4 import shapes.SCircle; 5 import javax.swing.*; 6 import java.awt.*; 7 import java.util.Random; 8 import java.util.Scanner; 9 10 public class HirstDots { 11 12 private void paintTheImage(){ 13 // Get the input information 14 int radius = getNumber("circle radius"); 15 int dotradius = getNumber("square side length"); 16 17 // Establish the painter 18 SPainter painter = new SPainter("Circle of Squares", radius*2+50, radius*2+50); 19 painter.setBrushWidth(3); 20 SCircle circle = new SCircle(radius); 21 SCircle dot = new SCircle(dotradius); 22 23 // Paint the squares 24 paintHirstSquares(painter, circle, dot); 25 } 26 27 private void paintHirstSquares(SPainter painter, SCircle circle, SCircle dot){ 28 // Paint the circle of squares 29 double howFarToMove = 0; 30 31 while (howFarToMove < circle.radius()) { 32 double chord = chordLength(howFarToMove, circle); 33 int dots = circleOnLineCount(chord, dot.diameter()); 34 if (howFarToMove == 0) { 35 paintRow(painter, dot, dots); 36 } 37 else { 38 // Stay invariant with respect to painter position 39 painter.mfd(howFarToMove); 40 paintRow(painter, dot, dots); 41 painter.mbk(howFarToMove * 2); 42 paintRow(painter, dot, dots); 43 painter.mfd(howFarToMove); 44 } 45 howFarToMove = howFarToMove + dot.diameter(); 46 } 47 } 48 49 // Assumes the painter is at the center of the row to paint, facing right. 50 private void paintRow(SPainter painter, SCircle dot, int squaresToPaint){ 51 // Turn right to start painting the row. 52 painter.tr(); 53 // Move backward 1/2 of the length we're painting to get ready to paint the row. 54 double centerOffset = ( (squaresToPaint * dot.diameter()) / 2) - dot.diameter()/2; 55 painter.mbk(centerOffset); 56 57 // Paint the row of squares. 58 int painted = 0; 59 while (painted < squaresToPaint){ 60 paintOneSquare(painter, dot); 61 painter.mfd(dot.diameter()); 62 painted = painted + 1; 63 } 64 65 // Make the method invariant with respect to painter position. 66 painter.mbk(centerOffset + dot.diameter()); 67 // Turn left to stay invariant with respect to direction. 68 painter.tl(); 69 } 70 71 private void paintOneSquare(SPainter painter,SCircle dot){ 72 dot.s2(); 73 painter.setColor(randomColor()); 74 painter.paint(dot); 75 painter.setColor(Color.BLACK); 76 painter.draw(dot); 77 dot.x2(); 78 } 79 80 private static int circleOnLineCount(double lineLength, double sideLength){ 81 int dots = ( (int)Math.ceil( ( lineLength - sideLength ) / sideLength ) + 1); 82 return dots; 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 HirstDots() { 106 paintTheImage(); 107 } 108 109 public static void main(String[] args) { 110 SwingUtilities.invokeLater(new Runnable() { 111 public void run() { 112 new HirstDots(); 113 } 114 }); 115 } 116 }