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 private void paintTheImage(){ 12 //Get the input information 13 int radius = getNumber("Larger Circle radius"); 14 int SecondRadius = getNumber("Smaller Circle radius"); 15 16 //establish the painter 17 SPainter painter = new SPainter ("Hirst Dots", radius*2+50, radius*2+50); 18 painter.setBrushWidth(3); 19 SCircle circle = new SCircle (radius); 20 SCircle SmallerCircle = new SCircle (SecondRadius); 21 22 //paint the squares 23 paintCircleOfSquares(painter, circle, SmallerCircle); 24 25 } 26 private void paintCircleOfSquares(SPainter painter, SCircle circle, SCircle SmallerCircle) { 27 //Position the painter to begin drawing the rows 28 painter.mfd(circle.radius()); 29 painter.tr(); 30 // Paint the circle of squares 31 double moved = 0; 32 while (moved < circle.diameter()) { 33 double chord = chordLength(circle.radius() - moved, circle); 34 int squares = circlesOnLineCount(chord, SmallerCircle.diameter()); 35 paintRow(painter,SmallerCircle,squares); 36 nextRow(painter, SmallerCircle.diameter()); 37 moved = moved + SmallerCircle.diameter(); 38 } 39 //make the method invariant with respect to painter position 40 painter.tl(); 41 painter.mfd(circle.radius()); 42 } 43 // Move to the next row 44 private void nextRow(SPainter painter, double rowHeight){ 45 painter.tr(); 46 painter.mfd(rowHeight); 47 painter.tl(); 48 } 49 50 // Assumes the painter is at the center of the row to paint, facing right. 51 private void paintRow(SPainter painter, SCircle SmallerCircle, int circlesToPaint){ 52 // Move backward 1/2 of the length we're painting to get ready to paint the row. 53 double centerOffset = ( (circlesToPaint * SmallerCircle.diameter()) / 2) - SmallerCircle.diameter()/2; 54 painter.mbk(centerOffset); 55 56 // Paint the row of circles. 57 int painted = 0; 58 while (painted < circlesToPaint){ 59 paintOneCircle(painter, SmallerCircle); 60 painter.mfd(SmallerCircle.diameter()); 61 painted = painted + 1; 62 } 63 64 // Make the method invariant with respect to painter position. 65 painter.mbk(centerOffset + SmallerCircle.diameter()); 66 } 67 68 private void paintOneCircle(SPainter painter, SCircle SmallerCircle){ 69 SmallerCircle.s2(); 70 painter.setColor(randomColor()); 71 painter.paint(SmallerCircle); 72 painter.setColor(Color.BLACK); 73 SmallerCircle.x2(); 74 } 75 76 private static int circlesOnLineCount(double lineLength, double sideLength){ 77 int squares = ( (int)Math.ceil( ( lineLength - sideLength ) / sideLength ) + 1); 78 return squares; 79 } 80 81 private double chordLength(double yOffset, SCircle circle){ 82 double xLength = Math.sqrt(Math.pow(circle.radius(), 2) - Math.pow(yOffset, 2)); 83 double chordLength = xLength * 2; 84 return chordLength; 85 } 86 87 private static int getNumber(String prompt) { 88 String nss = JOptionPane.showInputDialog(null,prompt+"?"); 89 Scanner scanner = new Scanner(nss); 90 return scanner.nextInt(); 91 } 92 93 private static Color randomColor() { 94 Random rgen = new Random(); 95 int r = rgen.nextInt(256); 96 int g = rgen.nextInt(256); 97 int b = rgen.nextInt(256); 98 return new Color(r,g,b); 99 } 100 101 public HirstDots() { 102 paintTheImage(); 103 } 104 105 public static void main(String[] args) { 106 SwingUtilities.invokeLater(new Runnable() { 107 public void run() { 108 new HirstDots(); 109 } 110 }); 111 } 112 }