1 /* 2 * A program to paint, centered on the canvas, a circle of colored, unframed dots 3 * that are separated. 4 * */ 5 6 package npw; 7 8 import painter.SPainter; 9 import shapes.SCircle; 10 11 import javax.swing.*; 12 import java.awt.*; 13 import java.util.Random; 14 import java.util.Scanner; 15 16 17 public class SimpleDots { 18 19 20 private void paintTheImage() { 21 // Get the input information 22 23 int radius = getNumber("circle radius"); 24 int dotRadius = getNumber("dot radius"); 25 26 27 // Establish the painter 28 SPainter painter = new SPainter("Simple Dots", radius * 2 + 50, radius * 2 + 50); 29 painter.setBrushWidth(3); 30 SCircle circle = new SCircle(radius); 31 SCircle dot = new SCircle(dotRadius); 32 33 while (true) { 34 String command = JOptionPane.showInputDialog(null, "Color?"); 35 if (command == null) { 36 command = "exit"; 37 break; 38 } // user clicked on Cancel 39 if (command.equalsIgnoreCase("red")) { 40 painter.setColor(Color.RED); 41 break; 42 } else if (command.equalsIgnoreCase("green")) { 43 painter.setColor(Color.GREEN); 44 break; 45 } else if (command.equalsIgnoreCase("blue")) { 46 painter.setColor(Color.BLUE); 47 break; 48 } else { 49 painter.setColor(Color.BLACK); 50 break; 51 } 52 } 53 54 // Paint the dots 55 paintSimpleDots(painter, circle, dot); 56 } 57 58 private void paintSimpleDots(SPainter painter, SCircle circle, SCircle dot) { 59 // Position the painter to begin drawing the rows 60 painter.mfd(circle.radius()); 61 painter.tr(); 62 // Paint the circle of squares 63 double moved = 0; 64 while (moved < circle.diameter()) { 65 double chord = chordLength(circle.radius() - moved, circle); 66 int dots = dotsOnLineCount(chord, dot.diameter()); 67 paintRow(painter, dot, dots); 68 nextRow(painter, dot.diameter()); 69 moved = moved + dot.diameter(); 70 } 71 // Make the method invariant with respect to painter position 72 painter.tl(); 73 painter.mfd(circle.radius()); 74 } 75 76 // Move to the next row 77 private void nextRow(SPainter painter, double rowHeight) { 78 painter.tr(); 79 painter.mfd(rowHeight); 80 painter.tl(); 81 } 82 83 // Assumes the painter is at the center of the row to paint, facing right. 84 private void paintRow(SPainter painter, SCircle dot, int dotsToPaint) { 85 // Move backward 1/2 of the length we're painting to get ready to paint the row. 86 double centerOffset = ((dotsToPaint * dot.diameter()) / 2) - dot.diameter() / 2; 87 painter.mbk(centerOffset); 88 89 // Paint the row of squares. 90 int painted = 0; 91 while (painted < dotsToPaint) { 92 paintOneDot(painter, dot); 93 painter.mfd(dot.diameter()); 94 painted = painted + 1; 95 } 96 97 // Make the method invariant with respect to painter position. 98 painter.mbk(centerOffset + dot.diameter()); 99 } 100 101 private void paintOneDot(SPainter painter, SCircle dot) { 102 dot.s2(); 103 painter.paint(dot); 104 dot.x2(); 105 } 106 107 108 private static int dotsOnLineCount(double lineLength, double diameterLength) { 109 int dots = ((int) Math.ceil((lineLength - diameterLength) / diameterLength) + 1); 110 return dots; 111 } 112 113 private double chordLength(double yOffset, SCircle circle) { 114 double xLength = Math.sqrt(Math.pow(circle.radius(), 2) - Math.pow(yOffset, 2)); 115 double chordLength = xLength * 2; 116 return chordLength; 117 } 118 119 private static int getNumber(String prompt) { 120 String nss = JOptionPane.showInputDialog(null, prompt + "?"); 121 Scanner scanner = new Scanner(nss); 122 return scanner.nextInt(); 123 } 124 125 126 private static Color randomColor() { 127 Random rgen = new Random(); 128 int r = rgen.nextInt(256); 129 int g = rgen.nextInt(256); 130 int b = rgen.nextInt(256); 131 return new Color(r, g, b); 132 } 133 134 public SimpleDots() { 135 paintTheImage(); 136 } 137 138 public static void main(String[] args) { 139 SwingUtilities.invokeLater(new Runnable() { 140 public void run() { 141 new SimpleDots(); 142 } 143 }); 144 } 145 } 146