1 package npw; 2 /* 3 * A program to paint, centered on the canvas, a circle of randomly colored circles 4 * In this program, we will add spaces between each circle 5 */ 6 7 import painter.SPainter; 8 import shapes.SCircle; 9 import shapes.SSquare; 10 import javax.swing.*; 11 import java.awt.*; 12 import java.util.Random; 13 import java.util.Scanner; 14 public class HirstDots { 15 private void paintTheImage(){ 16 // Get the input info 17 int bigRadius = getNumber("Overall circle radius"); 18 int individualRadius = getNumber("Individual circle radius"); 19 20 // Establish a painter 21 SPainter painter = new SPainter("Circle of circles", bigRadius*2+50, bigRadius*2+50); 22 painter.setBrushWidth(3); 23 SCircle totalCircle = new SCircle(bigRadius); 24 SCircle individualCircle = new SCircle(individualRadius); 25 26 // Paint the squares 27 paintHirstDots(painter, totalCircle, individualCircle); 28 } 29 30 private void paintHirstDots(SPainter painter, SCircle bCircle, SCircle iCircle){ 31 // Position the painter to begin drawing rows 32 painter.mfd(bCircle.radius()); 33 painter.tr(); 34 // Paint the circle of squares 35 double moved = 0; 36 while (moved < bCircle.diameter()) { 37 double chord = chordLength(bCircle.radius() - moved, bCircle); 38 int squares = squaresOnLineCount(chord, iCircle.diameter()); 39 paintRow(painter, iCircle, squares); 40 nextRow(painter, iCircle.diameter()); 41 moved = moved + iCircle.diameter(); 42 } 43 // Invariance 44 painter.tl(); 45 painter.mfd(bCircle.radius()); 46 } 47 48 // Move to 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, SCircle iCircle, int squaresToPaint){ 57 // Move backward 1/2 of the length we're painting to get ready to paint the row. 58 double centerOffset = ( (squaresToPaint * iCircle.diameter()) / 2) - iCircle.diameter()/2; 59 painter.mbk(centerOffset); 60 61 // Paint the row of circles. 62 int painted = 0; 63 while (painted < squaresToPaint){ 64 paintOneCircle(painter, iCircle); 65 painter.mfd(iCircle.diameter()); 66 painted = painted + 1; 67 } 68 69 // Make the method invariant w/ respect to painter position. 70 painter.mbk(centerOffset + iCircle.diameter()); 71 } 72 73 private void paintOneCircle(SPainter painter, SCircle iCircle){ 74 iCircle.s2(); 75 painter.setColor(randomColor()); 76 painter.paint(iCircle); 77 //Remove black outline from circles 78 //painter.setColor(Color.BLACK); 79 //painter.draw(iCircle); 80 iCircle.x2(); 81 } 82 83 private static int squaresOnLineCount(double lineLength, double sideLength){ 84 int circles = ( (int)Math.ceil( ( lineLength - sideLength ) / sideLength ) + 1); 85 return circles; 86 } 87 88 private double chordLength(double yOffset, SCircle circle){ 89 double xLength = Math.sqrt(Math.pow(circle.radius(), 2) - Math.pow(yOffset, 2)); 90 double chordLength = xLength * 2; 91 return chordLength; 92 } 93 94 private static int getNumber(String prompt) { 95 String nss = JOptionPane.showInputDialog(null,prompt+"?"); 96 Scanner scanner = new Scanner(nss); 97 return scanner.nextInt(); 98 } 99 100 private static Color randomColor() { 101 Random rgen = new Random(); 102 int r = rgen.nextInt(256); 103 int g = rgen.nextInt(256); 104 int b = rgen.nextInt(256); 105 return new Color(r,g,b); 106 } 107 108 public HirstDots() { 109 paintTheImage(); 110 } 111 112 public static void main(String[] args) { 113 SwingUtilities.invokeLater(new Runnable() { 114 public void run() { 115 new HirstDots(); 116 } 117 }); 118 } 119 } 120