001package algs12; 002 003import java.awt.Color; 004import stdlib.*; 005 006/** 007 * For this assignment, you must do two things: 008 * 009 * 1. Complete the MyRectangle class at the bottom of this file. It is not a 010 * public class, but don't worry about that. I've put two classes in one file so 011 * that you need only hand in a single file. 012 * 013 * In particular, you should get the testEquals method to work without throwing 014 * any exceptions. 015 * 016 * 2. Modify the draw method of MyRecursiveRectangles so that it behaves as 017 * demonstrated here: 018 * 019 * <pre> 020 * http://fpl.cs.depaul.edu/jriely/ds1/extras/RecursiveRectangles.mp4 021 * </pre> 022 * 023 * To do this only requires very minor modifications to the function. 024 * 025 * It is not necessary, but if you want to learn more about the drawing classes, 026 * see here: 027 * 028 * <pre> 029 * http://fpl.cs.depaul.edu/jriely/ds1/code/doc-public/stdlib/StdDraw.html 030 * http://introcs.cs.princeton.edu/java/15inout/ 031 * </pre> 032 */ 033 034public class MyRecursiveRectangles { 035 public static Color randomColor () { 036 int r = StdRandom.uniform (256); 037 int g = StdRandom.uniform (256); 038 int b = StdRandom.uniform (256); 039 return new Color (r, g, b); 040 } 041 public static final int VARIANCE = 60; 042 public static int randomByteAbove (int i) { 043 return StdRandom.uniform (Math.max (0, i - 1), Math.min (i + VARIANCE, 256)); 044 } 045 public static int randomByteBelow (int i) { 046 return StdRandom.uniform (Math.max (0, i - VARIANCE), Math.min (i + 1, 256)); 047 } 048 public static Color randomColorLight (Color c) { 049 int r = randomByteAbove (c.getRed ()); 050 int g = randomByteAbove (c.getGreen ()); 051 int b = randomByteAbove (c.getBlue ()); 052 return new Color (r, g, b); 053 } 054 public static Color randomColorDark (Color c) { 055 int r = randomByteBelow (c.getRed ()); 056 int g = randomByteBelow (c.getGreen ()); 057 int b = randomByteBelow (c.getBlue ()); 058 return new Color (r, g, b); 059 } 060 public static void draw (MyRect rect, int level, Color c) { 061 // TODO: 062 // edit this function so that it recursively draws levels from here down to level 0, 063 // decrementing by 1 each time 064 // Optionally, you can also stop recursing if the area of the rectangle is less than 0.1 065 066 // The following line might help while debugging: 067 //StdOut.format ("rect=%s, height=%f width=%f area=%f xmid=%f ymid=%f\n", rect, rect.height (), rect.width (), rect.area (), rect.xmid (), rect.ymid ()); 068 StdDraw.setPenColor (c); 069 rect.drawEllipse (); 070 StdDraw.show (50); 071 if (level % 2 == 0) { 072 double xmid = StdRandom.uniform (rect.xmin (), rect.xmax ()); 073 StdDraw.setPenColor (StdDraw.BLACK); 074 StdDraw.line (xmid, rect.ymin (), xmid, rect.ymax ()); 075 MyRect left = new MyRect (rect.xmin (), rect.ymin (), xmid, rect.ymax ()); 076 MyRect right = new MyRect (xmid, rect.ymin (), rect.xmax (), rect.ymax ()); 077 StdDraw.setPenColor (randomColorLight (c)); 078 left.drawEllipse (); 079 StdDraw.setPenColor (randomColorDark (c)); 080 right.drawEllipse (); 081 } else { 082 double ymid = StdRandom.uniform (rect.ymin (), rect.ymax ()); 083 StdDraw.setPenColor (StdDraw.BLACK); 084 StdDraw.line (rect.xmin (), ymid, rect.xmax (), ymid); 085 MyRect below = new MyRect (rect.xmin (), rect.ymin (), rect.xmax (), ymid); 086 MyRect above = new MyRect (rect.xmin (), ymid, rect.xmax (), rect.ymax ()); 087 StdDraw.setPenColor (randomColorLight (c)); 088 below.drawEllipse (); 089 StdDraw.setPenColor (randomColorDark (c)); 090 above.drawEllipse (); 091 } 092 } 093 public static void testEquals () { 094 // this method should not throw any exceptions! 095 MyRect r1 = new MyRect (1, 1, 2, 2); 096 if (!r1.equals (r1)) { 097 throw new Error (); 098 } 099 if (!r1.equals (new MyRect (1, 1, 2, 2))) { 100 throw new Error (); 101 } 102 if (r1.equals (null)) { 103 throw new Error (); 104 } 105 if (r1.equals (new Object ())) { 106 throw new Error (); 107 } 108 if (r1.equals (new MyRect (0, 1, 2, 2))) { 109 throw new Error (); 110 } 111 if (r1.equals (new MyRect (1, 0, 2, 2))) { 112 throw new Error (); 113 } 114 if (r1.equals (new MyRect (1, 1, 3, 2))) { 115 throw new Error (); 116 } 117 if (r1.equals (new MyRect (1, 1, 2, 3))) { 118 throw new Error (); 119 } 120 } 121 122 public static final double DIM = 1.0; 123 public static void main (String[] args) { 124 testEquals(); 125 126 StdDraw.setCanvasSize (800, 800); // in pixels 127 StdDraw.setXscale (-DIM, DIM); 128 StdDraw.setYscale (-DIM, DIM); 129 MyRect rect = new MyRect (-DIM, -DIM, DIM, DIM); 130 131 //StdRandom.setSeed (0); // uncomment this if you want the same behavior every time you run the program 132 Color initialColor = randomColor (); //new Color(127,127,127) 133 //long seed = StdRandom.getSeed (); 134 for (int numLevels = 1; numLevels < 8; numLevels += 1) { 135 //StdRandom.setSeed (seed); 136 StdDraw.clear (); 137 draw (rect, numLevels, initialColor); 138 StdDraw.show (1000); 139 } 140 } 141} 142 143// An axis aligned rectangle 144class MyRect { 145 // TODO: add fields 146 147 // construct the axis-aligned rectangle "[xmin, xmax] x [ymin, ymax]" 148 public MyRect (double xmin, double ymin, double xmax, double ymax) { 149 if (xmax < xmin || ymax < ymin) { 150 throw new IllegalArgumentException ("Invalid rectangle"); 151 } 152 // TODO: set the fields 153 } 154 155 // accessor methods for 4 coordinates 156 public double xmin () { 157 return /* TODO */0; 158 } 159 public double ymin () { 160 return /* TODO */0; 161 } 162 public double xmax () { 163 return /* TODO */0; 164 } 165 public double ymax () { 166 return /* TODO */0; 167 } 168 169 // width, height, area of rectangle 170 public double width () { 171 return /* TODO */0; 172 } 173 public double height () { 174 return /* TODO */0; 175 } 176 public double area () { 177 return /* TODO */0; 178 } 179 180 // halfway between xmin and xmax 181 public double xmid () { 182 return /* TODO */0; 183 } 184 // halfway between ymin and ymax 185 public double ymid () { 186 return /* TODO */0; 187 } 188 189 // follow the recipe given in the textbook (pp 102-103) to implement equals 190 public boolean equals (Object y) { 191 return /* TODO */false; 192 } 193 194 public void drawEllipse () { 195 StdDraw.filledEllipse (xmid (), ymid (), width () / 2, height () / 2); 196 } 197 public void drawRectangle () { 198 StdDraw.filledRectangle (xmid (), ymid (), width () / 2, height () / 2); 199 } 200 public String toString () { 201 return "[" + xmin () + ", " + xmax () + "] x [" + ymin () + ", " + ymax () + "]"; 202 } 203}