001/* 002 * To change this template, choose Tools | Templates 003 * and open the template in the editor. 004 */ 005package armyc2.c5isr.graphics2d; 006/** 007 * 008* 009 */ 010public class Rectangle implements Shape { 011 public int x=0; 012 public int y=0; 013 public int width=0; 014 public int height=0; 015 public Rectangle() 016 { 017 x=0; 018 y=0; 019 width=0; 020 height=0; 021 } 022 023 public Rectangle(Rectangle2D rect) 024 { 025 this((int) rect.x, (int) rect.y, (int) rect.width, (int) rect.height); 026 } 027 028 public Rectangle(Rectangle rect) 029 { 030 this(rect.x, rect.y, rect.width, rect.height); 031 } 032 033 public Rectangle(int x1, int y1, int width1, int height1) 034 { 035 x=x1; 036 y=y1; 037 width=width1; 038 height=height1; 039 } 040 public Rectangle getBounds() 041 { 042 return this; 043 } 044 public PathIterator getPathIterator(AffineTransform at) 045 { 046 return null; 047 } 048 public boolean intersects(Rectangle2D rect) 049 { 050 if(x+width<rect.x) 051 return false; 052 if(x>rect.x+rect.width) 053 return false; 054 if(y+height<rect.y) 055 return false; 056 if(y>rect.y+rect.height) 057 return false; 058 059 return true; 060 } 061 062 public boolean intersects(Rectangle rect) 063 { 064 return this.intersects(rect.x, rect.y, rect.width, rect.height); 065 } 066 067 public boolean intersects(double x1, double y1, double width1, double height1) 068 { 069 if(x+width<x1) 070 return false; 071 if(x>x1+width1) 072 return false; 073 if(y+height<y1) 074 return false; 075 if(y>y1+height1) 076 return false; 077 078 return true; 079 } 080 public boolean contains (int x1, int y1) 081 { 082 if(x<=x1 && x1<=x+width && 083 y<=y1 && y1<=y+height) 084 return true; 085 else return false; 086 } 087 public boolean contains (int x1, int y1, int width1, int height1) 088 { 089 if(this.contains(x1, y1) && this.contains(x1+width1, y1+height1)) 090 return true; 091 else return false; 092 } 093 public boolean contains (Point2D pt) 094 { 095 if(x<=pt.getX() && pt.getX()<=x+width && 096 y<=pt.getY() && pt.getY()<=y+height) 097 return true; 098 else return false; 099 } 100 public Rectangle2D getBounds2D() 101 { 102 return new Rectangle2D.Double(x,y,width,height); 103 } 104 public int getX() 105 { 106 return x; 107 } 108 public int getY() 109 { 110 return y; 111 } 112 public int getMinX() 113 { 114 return x; 115 } 116 public int getMinY() 117 { 118 return y; 119 } 120 public int getMaxX() 121 { 122 return x+width; 123 } 124 public int getMaxY() 125 { 126 return y+height; 127 } 128 public int getHeight() 129 { 130 return height; 131 } 132 public int getWidth() 133 { 134 return width; 135 } 136 137 public void grow(int h, int v) 138 { 139 long x0 = this.x; 140 long y0 = this.y; 141 long x1 = this.width; 142 long y1 = this.height; 143 x1 += x0; 144 y1 += y0; 145 146 x0 -= h; 147 y0 -= v; 148 x1 += h; 149 y1 += v; 150 151 if (x1 < x0) { 152 // Non-existant in X direction 153 // Final width must remain negative so subtract x0 before 154 // it is clipped so that we avoid the risk that the clipping 155 // of x0 will reverse the ordering of x0 and x1. 156 x1 -= x0; 157 if (x1 < Integer.MIN_VALUE) x1 = Integer.MIN_VALUE; 158 if (x0 < Integer.MIN_VALUE) x0 = Integer.MIN_VALUE; 159 else if (x0 > Integer.MAX_VALUE) x0 = Integer.MAX_VALUE; 160 } else { // (x1 >= x0) 161 // Clip x0 before we subtract it from x1 in case the clipping 162 // affects the representable area of the rectangle. 163 if (x0 < Integer.MIN_VALUE) x0 = Integer.MIN_VALUE; 164 else if (x0 > Integer.MAX_VALUE) x0 = Integer.MAX_VALUE; 165 x1 -= x0; 166 // The only way x1 can be negative now is if we clipped 167 // x0 against MIN and x1 is less than MIN - in which case 168 // we want to leave the width negative since the result 169 // did not intersect the representable area. 170 if (x1 < Integer.MIN_VALUE) x1 = Integer.MIN_VALUE; 171 else if (x1 > Integer.MAX_VALUE) x1 = Integer.MAX_VALUE; 172 } 173 174 if (y1 < y0) { 175 // Non-existant in Y direction 176 y1 -= y0; 177 if (y1 < Integer.MIN_VALUE) y1 = Integer.MIN_VALUE; 178 if (y0 < Integer.MIN_VALUE) y0 = Integer.MIN_VALUE; 179 else if (y0 > Integer.MAX_VALUE) y0 = Integer.MAX_VALUE; 180 } else { // (y1 >= y0) 181 if (y0 < Integer.MIN_VALUE) y0 = Integer.MIN_VALUE; 182 else if (y0 > Integer.MAX_VALUE) y0 = Integer.MAX_VALUE; 183 y1 -= y0; 184 if (y1 < Integer.MIN_VALUE) y1 = Integer.MIN_VALUE; 185 else if (y1 > Integer.MAX_VALUE) y1 = Integer.MAX_VALUE; 186 } 187 188 this.x = (int) x0; 189 this.y = (int) y0; 190 this.width = (int) x1; 191 this.height = (int) y1; 192 } 193 194 public void setRect(Rectangle rect) 195 { 196 x=rect.x; 197 y=rect.y; 198 width=rect.width; 199 height=rect.height; 200 } 201 202 public void setRect(int x, int y, int width, int height) { 203 this.x = x; 204 this.y = y; 205 this.width = width; 206 this.height = height; 207 } 208 209 public void setLocation(int x, int y) { 210 this.x = x; 211 this.y = y; 212 } 213 214 public void add(Point2D pt) { 215 int newx = (int) pt.getX(); 216 int newy = (int) pt.getY(); 217 if ((width | height) < 0) { 218 this.x = newx; 219 this.y = newy; 220 this.width = this.height = 0; 221 return; 222 } 223 int x1 = this.x; 224 int y1 = this.y; 225 long x2 = this.width; 226 long y2 = this.height; 227 x2 += x1; 228 y2 += y1; 229 if (x1 > newx) x1 = newx; 230 if (y1 > newy) y1 = newy; 231 if (x2 < newx) x2 = newx; 232 if (y2 < newy) y2 = newy; 233 x2 -= x1; 234 y2 -= y1; 235 if (x2 > Integer.MAX_VALUE) x2 = Integer.MAX_VALUE; 236 if (y2 > Integer.MAX_VALUE) y2 = Integer.MAX_VALUE; 237 this.x = x1; 238 this.y = y1; 239 this.width = (int) x2; 240 this.height = (int) y2; 241 } 242 243 public Rectangle union(Rectangle r) { 244 long tx2 = this.width; 245 long ty2 = this.height; 246 if ((tx2 | ty2) < 0) { 247 // This rectangle has negative dimensions... 248 // If r has non-negative dimensions then it is the answer. 249 // If r is non-existant (has a negative dimension), then both 250 // are non-existant and we can return any non-existant rectangle 251 // as an answer. Thus, returning r meets that criterion. 252 // Either way, r is our answer. 253 return new Rectangle(r); 254 } 255 long rx2 = r.width; 256 long ry2 = r.height; 257 if ((rx2 | ry2) < 0) { 258 return new Rectangle(this); 259 } 260 int tx1 = this.x; 261 int ty1 = this.y; 262 tx2 += tx1; 263 ty2 += ty1; 264 int rx1 = r.x; 265 int ry1 = r.y; 266 rx2 += rx1; 267 ry2 += ry1; 268 if (tx1 > rx1) tx1 = rx1; 269 if (ty1 > ry1) ty1 = ry1; 270 if (tx2 < rx2) tx2 = rx2; 271 if (ty2 < ry2) ty2 = ry2; 272 tx2 -= tx1; 273 ty2 -= ty1; 274 // tx2,ty2 will never underflow since both original rectangles 275 // were already proven to be non-empty 276 // they might overflow, though... 277 if (tx2 > Integer.MAX_VALUE) tx2 = Integer.MAX_VALUE; 278 if (ty2 > Integer.MAX_VALUE) ty2 = Integer.MAX_VALUE; 279 return new Rectangle(tx1, ty1, (int) tx2, (int) ty2); 280 } 281}