HirstDots.java
1    /* 
2     * A program to paint an abstract gradient in the vertical and horizontal direction. 
3     */
4    
5    package npw;
6    
7    import painter.SPainter;
8    import shapes.SCircle;
9    
10   import javax.swing.*;
11   import java.awt.*;
12   import java.util.Scanner;
13   
14   public class HirstDots {
15   
16       public static void main(String[] args) {SwingUtilities.invokeLater(HirstDots::new);
17       }
18   
19       public HirstDots() {paintTheImage();}
20   
21       private void paintTheImage() {
22           // Grab the input information
23           int width = getNumber("width");
24           int height = getNumber("height");
25           int horizontalSpace = getNumber("horizontal space between dots");
26           int verticalSpace = getNumber("vertical space between dots");
27           // Establish the painter
28           SPainter painter = new SPainter("Hirst Dots" ,  width , height);
29           SCircle dot = new SCircle(5);
30   
31   
32           // Move the painter to the upper left corner and get ready to paint the gradient
33           painter.mfd(height/2.0);
34           painter.tl();
35           painter.mfd(width/2.0);
36           painter.tl();
37   
38           // Paint it!
39           paintGradient(painter, dot, height, width, horizontalSpace, verticalSpace);
40       }
41   
42       private static int getNumber(String prompt) {
43           String nss = JOptionPane.showInputDialog(null, prompt+"?");
44           Scanner scanner = new Scanner(nss);
45           return scanner.nextInt();
46       }
47   
48       private void paintGradient(SPainter painter, SCircle dot, int height, int width, int horizontalSpace, int verticalSpace){
49           // Calculate the number of columns. We want to fill the screen, but don't want any columns half on the canvas.
50           // A column takes up the horizontal space of a dot's diameter plus the space between it and a neighbor.
51           double colWidth = dot.diameter() + horizontalSpace;
52           double rowWidth = dot.diameter() + verticalSpace;
53           // We don't want a column all the way on the edge on the right side, so subtract 1.
54           int nrOfCols = (int) Math.floor(( width / colWidth )) -1;
55           int nrOfRows = (int) Math.floor(( width / rowWidth )) -1;
56   
57           int cols = 0;
58           while (cols < nrOfCols) {
59               nextCol(painter, dot, horizontalSpace);
60               paintColumn(painter, dot, height, horizontalSpace);
61               cols = cols + 1;
62           }
63           int rows = 0;
64           while ((rows > nrOfRows)) {
65               nextRow(painter, dot, verticalSpace);
66               paintRow(painter, dot, height, verticalSpace);
67               rows = rows + 1;
68           }
69       }
70   
71       private static Color randomColor() {
72           int rv = (int) (Math.random()*256);
73           int gv = (int) (Math.random()*256);
74           int bv = (int) (Math.random()*256);
75           return new Color( rv,gv,bv );
76       }
77   
78       private void paintOneDot(SPainter painter, SCircle dot) {
79           painter.setColor(randomColor());
80           painter.paint(dot);
81       }
82   
83       // Dots are spaced more tightly together near the bottom of the canvas.
84       private void paintColumn(SPainter painter, SCircle dot, int height, int horizontalSpace) {
85           int totalDistanceTraveled = 0;
86   
87           // Paint a column with decreasing distance between dots.
88           while (totalDistanceTraveled < height - (dot.radius() *3)) {
89               int travel = horizontalSpace -1;
90               totalDistanceTraveled = totalDistanceTraveled + travel;
91               painter.mfd(travel);
92               paintOneDot(painter, dot);
93           }
94   
95           // Make the method invariant with respect to painter position.
96           painter.mbk(totalDistanceTraveled);
97       }
98   
99       private void paintRow(SPainter painter, SCircle dot, int height, int verticalSpace) {
100          int totalDistanceTraveled = 0;
101          while (totalDistanceTraveled < height - (dot.radius() *3)) {
102              int travel = verticalSpace -1;
103              totalDistanceTraveled = totalDistanceTraveled + travel;
104              painter.mfd(travel);
105              paintOneDot(painter, dot);
106          }
107      }
108      // Moves the painter to the next column.
109      private void nextCol(SPainter painter, SCircle dot, int horizontalSpace) {
110          painter.tl();
111          painter.mfd(dot.diameter() + horizontalSpace);
112          painter.tr();
113      }
114      private void nextRow(SPainter painter, SCircle dot, int verticalSpace) {
115          painter.tl();
116          painter.mfd(dot.diameter() + verticalSpace);
117          painter.tr();
118      }
119  }
120  
121  
122