001: /*
002: * Copyright (C) 2005, 2006 data2c GmbH (www.data2c.com)
003: *
004: * Author: Wolfgang S. Kechel - wolfgang.kechel@data2c.com
005: *
006: * J2ME version of java.awt.geom.Rectangle.
007: */
008:
009: //#ifndef j2se
010: package org.awt;
011:
012: import org.awt.geom.Rectangle2D;
013:
014: /**
015: * A <code>Rectangle</code> specifies an area in a coordinate space that is
016: * enclosed by the <code>Rectangle</code> object's top-left point
017: * (<i>x</i>, <i>y</i>)
018: * in the coordinate space, its width, and its height.
019: * <p>
020: * A <code>Rectangle</code> object's <code>width</code> and
021: * <code>height</code> are <code>public</code> fields. The constructors
022: * that create a <code>Rectangle</code>, and the methods that can modify
023: * one, do not prevent setting a negative value for width or height.
024: * <p>
025: * A <code>Rectangle</code> whose width or height is negative is considered
026: * empty. If the <code>Rectangle</code> is empty, then the
027: * <code>isEmpty</code> method returns <code>true</code>. No point can be
028: * contained by or inside an empty <code>Rectangle</code>. The
029: * values of <code>width</code> and <code>height</code>, however, are still
030: * valid. An empty <code>Rectangle</code> still has a location in the
031: * coordinate space, and methods that change its size or location remain
032: * valid. The behavior of methods that operate on more than one
033: * <code>Rectangle</code> is undefined if any of the participating
034: * <code>Rectangle</code> objects has a negative
035: * <code>width</code> or <code>height</code>. These methods include
036: * <code>intersects</code>, <code>intersection</code>, and
037: * <code>union</code>.
038: */
039: public class Rectangle extends Rectangle2D /*implements Shape, java.io.Serializable*/{
040:
041: /**
042: * The <i>x</i> coordinate of the <code>Rectangle</code>.
043: *
044: * @serial
045: * @see #setLocation(int, int)
046: * @see #getLocation()
047: */
048: public int x;
049:
050: /**
051: * The <i>y</i> coordinate of the <code>Rectangle</code>.
052: *
053: * @serial
054: * @see #setLocation(int, int)
055: * @see #getLocation()
056: */
057: public int y;
058:
059: /**
060: * The width of the <code>Rectangle</code>.
061: * @serial
062: * @see #setSize(int, int)
063: * @see #getSize()
064: */
065: public int width;
066:
067: /**
068: * The height of the <code>Rectangle</code>.
069: *
070: * @serial
071: * @see #setSize(int, int)
072: * @see #getSize()
073: */
074: public int height;
075:
076: /**
077: * Constructs a new <code>Rectangle</code> whose top-left corner
078: * is at (0, 0) in the coordinate space, and whose width and
079: * height are both zero.
080: */
081: public Rectangle() {
082: this (0, 0, 0, 0);
083: }
084:
085: /**
086: * Constructs a new <code>Rectangle</code>, initialized to match
087: * the values of the specified <code>Rectangle</code>.
088: * @param r the <code>Rectangle</code> from which to copy initial values
089: * to a newly constructed <code>Rectangle</code>
090: */
091: public Rectangle(Rectangle r) {
092: this (r.x, r.y, r.width, r.height);
093: }
094:
095: /**
096: * Constructs a new <code>Rectangle</code> whose top-left corner is
097: * specified as
098: * (<code>x</code>, <code>y</code>) and whose width and height
099: * are specified by the arguments of the same name.
100: * @param x the specified x coordinate
101: * @param y the specified y coordinate
102: * @param width the width of the <code>Rectangle</code>
103: * @param height the height of the <code>Rectangle</code>
104: */
105: public Rectangle(int x, int y, int width, int height) {
106: this .x = x;
107: this .y = y;
108: this .width = width;
109: this .height = height;
110: }
111:
112: /**
113: * Constructs a new <code>Rectangle</code> whose top-left corner
114: * is at (0, 0) in the coordinate space, and whose width and
115: * height are specified by the arguments of the same name.
116: * @param width the width of the <code>Rectangle</code>
117: * @param height the height of the <code>Rectangle</code>
118: */
119: public Rectangle(int width, int height) {
120: this (0, 0, width, height);
121: }
122:
123: /**
124: * Constructs a new <code>Rectangle</code> whose top-left corner is
125: * specified by the {@link Point} argument, and
126: * whose width and height are specified by the
127: * {@link Dimension} argument.
128: * @param p a <code>Point</code> that is the top-left corner of
129: * the <code>Rectangle</code>
130: * @param d a <code>Dimension</code>, representing the
131: * width and height of the <code>Rectangle</code>
132: */
133: public Rectangle(Point p, Dimension d) {
134: this (p.x, p.y, d.width, d.height);
135: }
136:
137: /**
138: * Constructs a new <code>Rectangle</code> whose top-left corner is the
139: * specified <code>Point</code>, and whose width and height are both zero.
140: * @param p a <code>Point</code> that is the top left corner
141: * of the <code>Rectangle</code>
142: */
143: public Rectangle(Point p) {
144: this (p.x, p.y, 0, 0);
145: }
146:
147: /**
148: * Constructs a new <code>Rectangle</code> whose top left corner is
149: * (0, 0) and whose width and height are specified
150: * by the <code>Dimension</code> argument.
151: * @param d a <code>Dimension</code>, specifying width and height
152: */
153: public Rectangle(Dimension d) {
154: this (0, 0, d.width, d.height);
155: }
156:
157: //#ifdef notdef
158: public Object clone() /*throws CloneNotSupportedException*/{
159: return new Rectangle(x, y, width, height);
160: }
161:
162: //#endif
163: /**
164: * Returns the X coordinate of the bounding <code>Rectangle</code> in
165: * <code>double</code> precision.
166: * @return the x coordinate of the bounding <code>Rectangle</code>.
167: */
168: public double getX() {
169: return x;
170: }
171:
172: /**
173: * Returns the Y coordinate of the bounding <code>Rectangle</code> in
174: * <code>double</code> precision.
175: * @return the y coordinate of the bounding <code>Rectangle</code>.
176: */
177: public double getY() {
178: return y;
179: }
180:
181: /**
182: * Returns the width of the bounding <code>Rectangle</code> in
183: * <code>double</code> precision.
184: * @return the width of the bounding <code>Rectangle</code>.
185: */
186: public double getWidth() {
187: return width;
188: }
189:
190: /**
191: * Returns the height of the bounding <code>Rectangle</code> in
192: * <code>double</code> precision.
193: * @return the height of the bounding <code>Rectangle</code>.
194: */
195: public double getHeight() {
196: return height;
197: }
198:
199: /**
200: * Gets the bounding <code>Rectangle</code> of this <code>Rectangle</code>.
201: * <p>
202: * This method is included for completeness, to parallel the
203: * <code>getBounds</code> method of
204: * {@link Component}.
205: * @return a new <code>Rectangle</code>, equal to the
206: * bounding <code>Rectangle</code> for this <code>Rectangle</code>.
207: * @see java.awt.Component#getBounds
208: * @see #setBounds(Rectangle)
209: * @see #setBounds(int, int, int, int)
210: */
211: public Rectangle getBounds() {
212: return new Rectangle(x, y, width, height);
213: }
214:
215: /**
216: * Return the high precision bounding box of this rectangle.
217: */
218: public Rectangle2D getBounds2D() {
219: return new Rectangle(x, y, width, height);
220: }
221:
222: /**
223: * Sets the bounding <code>Rectangle</code> of this <code>Rectangle</code>
224: * to match the specified <code>Rectangle</code>.
225: * <p>
226: * This method is included for completeness, to parallel the
227: * <code>setBounds</code> method of <code>Component</code>.
228: * @param r the specified <code>Rectangle</code>
229: * @see #getBounds
230: * @see java.awt.Component#setBounds(java.awt.Rectangle)
231: */
232: public void setBounds(Rectangle r) {
233: setBounds(r.x, r.y, r.width, r.height);
234: }
235:
236: /**
237: * Sets the bounding <code>Rectangle</code> of this
238: * <code>Rectangle</code> to the specified
239: * <code>x</code>, <code>y</code>, <code>width</code>,
240: * and <code>height</code>.
241: * <p>
242: * This method is included for completeness, to parallel the
243: * <code>setBounds</code> method of <code>Component</code>.
244: * @param x the new x coordinate for the top-left
245: * corner of this <code>Rectangle</code>
246: * @param y the new y coordinate for the top-left
247: * corner of this <code>Rectangle</code>
248: * @param width the new width for this <code>Rectangle</code>
249: * @param height the new height for this <code>Rectangle</code>
250: * @see #getBounds
251: * @see java.awt.Component#setBounds(int, int, int, int)
252: */
253: public void setBounds(int x, int y, int width, int height) {
254: reshape(x, y, width, height);
255: }
256:
257: /**
258: * Sets the bounds of this <code>Rectangle</code> to the specified
259: * <code>x</code>, <code>y</code>, <code>width</code>,
260: * and <code>height</code>.
261: * This method is included for completeness, to parallel the
262: * <code>setBounds</code> method of <code>Component</code>.
263: * @param x the x coordinate of the upper-left corner of
264: * the specified rectangle
265: * @param y the y coordinate of the upper-left corner of
266: * the specified rectangle
267: * @param width the new width for the <code>Dimension</code> object
268: * @param height the new height for the <code>Dimension</code> object
269: */
270: public void setRect(double x, double y, double width, double height) {
271: int x0 = (int) Math.floor(x);
272: int y0 = (int) Math.floor(y);
273: int x1 = (int) Math.ceil(x + width);
274: int y1 = (int) Math.ceil(y + height);
275: setBounds(x0, y0, x1 - x0, y1 - y0);
276: }
277:
278: /**
279: * Sets the bounding <code>Rectangle</code> of this
280: * <code>Rectangle</code> to the specified
281: * <code>x</code>, <code>y</code>, <code>width</code>,
282: * and <code>height</code>.
283: * <p>
284: * @param x the new x coordinate for the top-left
285: * corner of this <code>Rectangle</code>
286: * @param y the new y coordinate for the top-left
287: * corner of this <code>Rectangle</code>
288: * @param width the new width for this <code>Rectangle</code>
289: * @param height the new height for this <code>Rectangle</code>
290: * @deprecated As of JDK version 1.1,
291: * replaced by <code>setBounds(int, int, int, int)</code>.
292: */
293: public void reshape(int x, int y, int width, int height) {
294: this .x = x;
295: this .y = y;
296: this .width = width;
297: this .height = height;
298: }
299:
300: /**
301: * Returns the location of this <code>Rectangle</code>.
302: * <p>
303: * This method is included for completeness, to parallel the
304: * <code>getLocation</code> method of <code>Component</code>.
305: * @return the <code>Point</code> that is the top-left corner of
306: * this <code>Rectangle</code>.
307: * @see java.awt.Component#getLocation
308: * @see #setLocation(Point)
309: * @see #setLocation(int, int)
310: */
311: public Point getLocation() {
312: return new Point(x, y);
313: }
314:
315: /**
316: * Moves this <code>Rectangle</code> to the specified location.
317: * <p>
318: * This method is included for completeness, to parallel the
319: * <code>setLocation</code> method of <code>Component</code>.
320: * @param p the <code>Point</code> specifying the new location
321: * for this <code>Rectangle</code>
322: * @see java.awt.Component#setLocation(java.awt.Point)
323: * @see #getLocation
324: */
325: public void setLocation(Point p) {
326: setLocation(p.x, p.y);
327: }
328:
329: /**
330: * Moves this <code>Rectangle</code> to the specified location.
331: * <p>
332: * This method is included for completeness, to parallel the
333: * <code>setLocation</code> method of <code>Component</code>.
334: * @param x the x coordinate of the new location
335: * @param y the y coordinate of the new location
336: * @see #getLocation
337: * @see java.awt.Component#setLocation(int, int)
338: */
339: public void setLocation(int x, int y) {
340: move(x, y);
341: }
342:
343: /**
344: * Moves this <code>Rectangle</code> to the specified location.
345: * <p>
346: * @param x the x coordinate of the new location
347: * @param y the y coordinate of the new location
348: * @deprecated As of JDK version 1.1,
349: * replaced by <code>setLocation(int, int)</code>.
350: */
351: public void move(int x, int y) {
352: this .x = x;
353: this .y = y;
354: }
355:
356: /**
357: * Translates this <code>Rectangle</code> the indicated distance,
358: * to the right along the x coordinate axis, and
359: * downward along the y coordinate axis.
360: * @param x the distance to move this <code>Rectangle</code>
361: * along the x axis
362: * @param y the distance to move this <code>Rectangle</code>
363: * along the y axis
364: * @see java.awt.Rectangle#setLocation(int, int)
365: * @see java.awt.Rectangle#setLocation(java.awt.Point)
366: */
367: public void translate(int x, int y) {
368: this .x += x;
369: this .y += y;
370: }
371:
372: /**
373: * Gets the size of this <code>Rectangle</code>, represented by
374: * the returned <code>Dimension</code>.
375: * <p>
376: * This method is included for completeness, to parallel the
377: * <code>getSize</code> method of <code>Component</code>.
378: * @return a <code>Dimension</code>, representing the size of
379: * this <code>Rectangle</code>.
380: * @see java.awt.Component#getSize
381: * @see #setSize(Dimension)
382: * @see #setSize(int, int)
383: */
384: public Dimension getSize() {
385: return new Dimension(width, height);
386: }
387:
388: /**
389: * Sets the size of this <code>Rectangle</code> to match the
390: * specified <code>Dimension</code>.
391: * <p>
392: * This method is included for completeness, to parallel the
393: * <code>setSize</code> method of <code>Component</code>.
394: * @param d the new size for the <code>Dimension</code> object
395: * @see java.awt.Component#setSize(java.awt.Dimension)
396: * @see #getSize
397: */
398: public void setSize(Dimension d) {
399: setSize(d.width, d.height);
400: }
401:
402: /**
403: * Sets the size of this <code>Rectangle</code> to the specified
404: * width and height.
405: * <p>
406: * This method is included for completeness, to parallel the
407: * <code>setSize</code> method of <code>Component</code>.
408: * @param width the new width for this <code>Rectangle</code>
409: * @param height the new height for this <code>Rectangle</code>
410: * @see java.awt.Component#setSize(int, int)
411: * @see #getSize
412: */
413: public void setSize(int width, int height) {
414: resize(width, height);
415: }
416:
417: /**
418: * Sets the size of this <code>Rectangle</code> to the specified
419: * width and height.
420: * <p>
421: * @param width the new width for this <code>Rectangle</code>
422: * @param height the new height for this <code>Rectangle</code>
423: * @deprecated As of JDK version 1.1,
424: * replaced by <code>setSize(int, int)</code>.
425: */
426: public void resize(int width, int height) {
427: this .width = width;
428: this .height = height;
429: }
430:
431: /**
432: * Checks whether or not this <code>Rectangle</code> contains the
433: * specified <code>Point</code>.
434: * @param p the <code>Point</code> to test
435: * @return <code>true</code> if the <code>Point</code>
436: * (<i>x</i>, <i>y</i>) is inside this
437: * <code>Rectangle</code>;
438: * <code>false</code> otherwise.
439: */
440: public boolean contains(Point p) {
441: return contains(p.x, p.y);
442: }
443:
444: /**
445: * Checks whether or not this <code>Rectangle</code> contains the
446: * point at the specified location
447: * (<i>x</i>, <i>y</i>).
448: * @param x the specified x coordinate
449: * @param y the specified y coordinate
450: * @return <code>true</code> if the point
451: * (<i>x</i>, <i>y</i>) is inside this
452: * <code>Rectangle</code>;
453: * <code>false</code> otherwise.
454: */
455: public boolean contains(int x, int y) {
456: return inside(x, y);
457: }
458:
459: /**
460: * Checks whether or not this <code>Rectangle</code> entirely contains
461: * the specified <code>Rectangle</code>.
462: * @param r the specified <code>Rectangle</code>
463: * @return <code>true</code> if the <code>Rectangle</code>
464: * is contained entirely inside this <code>Rectangle</code>;
465: * <code>false</code> otherwise.
466: */
467: public boolean contains(Rectangle r) {
468: return contains(r.x, r.y, r.width, r.height);
469: }
470:
471: /**
472: * Checks whether this <code>Rectangle</code> entirely contains
473: * the <code>Rectangle</code>
474: * at the specified location (<i>X</i>, <i>Y</i>) with the
475: * specified dimensions (<i>W</i>, <i>H</i>).
476: * @param X the specified x coordinate
477: * @param Y the specified y coordinate
478: * @param W the width of the <code>Rectangle</code>
479: * @param H the height of the <code>Rectangle</code>
480: * @return <code>true</code> if the <code>Rectangle</code> specified by
481: * (<i>X</i>, <i>Y</i>, <i>W</i>, <i>H</i>)
482: * is entirely enclosed inside this <code>Rectangle</code>;
483: * <code>false</code> otherwise.
484: */
485: public boolean contains(int X, int Y, int W, int H) {
486: int w = this .width;
487: int h = this .height;
488: if ((w | h | W | H) < 0) {
489: // At least one of the dimensions is negative...
490: return false;
491: }
492: // Note: if any dimension is zero, tests below must return false...
493: int x = this .x;
494: int y = this .y;
495: if (X < x || Y < y) {
496: return false;
497: }
498: w += x;
499: W += X;
500: if (W <= X) {
501: // X+W overflowed or W was zero, return false if...
502: // either original w or W was zero or
503: // x+w did not overflow or
504: // the overflowed x+w is smaller than the overflowed X+W
505: if (w >= x || W > w)
506: return false;
507: } else {
508: // X+W did not overflow and W was not zero, return false if...
509: // original w was zero or
510: // x+w did not overflow and x+w is smaller than X+W
511: if (w >= x && W > w)
512: return false;
513: }
514: h += y;
515: H += Y;
516: if (H <= Y) {
517: if (h >= y || H > h)
518: return false;
519: } else {
520: if (h >= y && H > h)
521: return false;
522: }
523: return true;
524: }
525:
526: /**
527: * Checks whether or not this <code>Rectangle</code> contains the
528: * point at the specified location
529: * (<i>X</i>, <i>Y</i>).
530: * @param X the specified x coordinate
531: * @param Y the specified y coordinate
532: * @return <code>true</code> if the point
533: * (<i>X</i>, <i>Y</i>) is inside this
534: * <code>Rectangle</code>;
535: * <code>false</code> otherwise.
536: * @deprecated As of JDK version 1.1,
537: * replaced by <code>contains(int, int)</code>.
538: */
539: public boolean inside(int X, int Y) {
540: int w = this .width;
541: int h = this .height;
542: if ((w | h) < 0) {
543: // At least one of the dimensions is negative...
544: return false;
545: }
546: // Note: if either dimension is zero, tests below must return false...
547: int x = this .x;
548: int y = this .y;
549: if (X < x || Y < y) {
550: return false;
551: }
552: w += x;
553: h += y;
554: // overflow || intersect
555: return ((w < x || w > X) && (h < y || h > Y));
556: }
557:
558: /**
559: * Determines whether or not this <code>Rectangle</code> and the specified
560: * <code>Rectangle</code> intersect. Two rectangles intersect if
561: * their intersection is nonempty.
562: *
563: * @param r the specified <code>Rectangle</code>
564: * @return <code>true</code> if the specified <code>Rectangle</code>
565: * and this <code>Rectangle</code> intersect;
566: * <code>false</code> otherwise.
567: */
568: public boolean intersects(Rectangle r) {
569: int tw = this .width;
570: int th = this .height;
571: int rw = r.width;
572: int rh = r.height;
573: if (rw <= 0 || rh <= 0 || tw <= 0 || th <= 0) {
574: return false;
575: }
576: int tx = this .x;
577: int ty = this .y;
578: int rx = r.x;
579: int ry = r.y;
580: rw += rx;
581: rh += ry;
582: tw += tx;
583: th += ty;
584: // overflow || intersect
585: return ((rw < rx || rw > tx) && (rh < ry || rh > ty)
586: && (tw < tx || tw > rx) && (th < ty || th > ry));
587: }
588:
589: /**
590: * Computes the intersection of this <code>Rectangle</code> with the
591: * specified <code>Rectangle</code>. Returns a new <code>Rectangle</code>
592: * that represents the intersection of the two rectangles.
593: * If the two rectangles do not intersect, the result will be
594: * an empty rectangle.
595: *
596: * @param r the specified <code>Rectangle</code>
597: * @return the largest <code>Rectangle</code> contained in both the
598: * specified <code>Rectangle</code> and in
599: * this <code>Rectangle</code>; or if the rectangles
600: * do not intersect, an empty rectangle.
601: */
602: public Rectangle intersection(Rectangle r) {
603: int tx1 = this .x;
604: int ty1 = this .y;
605: int rx1 = r.x;
606: int ry1 = r.y;
607: long tx2 = tx1;
608: tx2 += this .width;
609: long ty2 = ty1;
610: ty2 += this .height;
611: long rx2 = rx1;
612: rx2 += r.width;
613: long ry2 = ry1;
614: ry2 += r.height;
615: if (tx1 < rx1)
616: tx1 = rx1;
617: if (ty1 < ry1)
618: ty1 = ry1;
619: if (tx2 > rx2)
620: tx2 = rx2;
621: if (ty2 > ry2)
622: ty2 = ry2;
623: tx2 -= tx1;
624: ty2 -= ty1;
625: // tx2,ty2 will never overflow (they will never be
626: // larger than the smallest of the two source w,h)
627: // they might underflow, though...
628: if (tx2 < Integer.MIN_VALUE)
629: tx2 = Integer.MIN_VALUE;
630: if (ty2 < Integer.MIN_VALUE)
631: ty2 = Integer.MIN_VALUE;
632: return new Rectangle(tx1, ty1, (int) tx2, (int) ty2);
633: }
634:
635: /**
636: * Computes the union of this <code>Rectangle</code> with the
637: * specified <code>Rectangle</code>. Returns a new
638: * <code>Rectangle</code> that
639: * represents the union of the two rectangles
640: * @param r the specified <code>Rectangle</code>
641: * @return the smallest <code>Rectangle</code> containing both
642: * the specified <code>Rectangle</code> and this
643: * <code>Rectangle</code>.
644: */
645: public Rectangle union(Rectangle r) {
646: int x1 = Math.min(x, r.x);
647: int x2 = Math.max(x + width, r.x + r.width);
648: int y1 = Math.min(y, r.y);
649: int y2 = Math.max(y + height, r.y + r.height);
650: return new Rectangle(x1, y1, x2 - x1, y2 - y1);
651: }
652:
653: /**
654: * Adds a point, specified by the integer arguments <code>newx</code>
655: * and <code>newy</code>, to this <code>Rectangle</code>. The
656: * resulting <code>Rectangle</code> is
657: * the smallest <code>Rectangle</code> that contains both the
658: * original <code>Rectangle</code> and the specified point.
659: * <p>
660: * After adding a point, a call to <code>contains</code> with the
661: * added point as an argument does not necessarily return
662: * <code>true</code>. The <code>contains</code> method does not
663: * return <code>true</code> for points on the right or bottom
664: * edges of a <code>Rectangle</code>. Therefore, if the added point
665: * falls on the right or bottom edge of the enlarged
666: * <code>Rectangle</code>, <code>contains</code> returns
667: * <code>false</code> for that point.
668: * @param newx the x coordinate of the new point
669: * @param newy the y coordinate of the new point
670: */
671: public void add(int newx, int newy) {
672: int x1 = Math.min(x, newx);
673: int x2 = Math.max(x + width, newx);
674: int y1 = Math.min(y, newy);
675: int y2 = Math.max(y + height, newy);
676: x = x1;
677: y = y1;
678: width = x2 - x1;
679: height = y2 - y1;
680: }
681:
682: /**
683: * Adds the specified <code>Point</code> to this
684: * <code>Rectangle</code>. The resulting <code>Rectangle</code>
685: * is the smallest <code>Rectangle</code> that contains both the
686: * original <code>Rectangle</code> and the specified
687: * <code>Point</code>.
688: * <p>
689: * After adding a <code>Point</code>, a call to <code>contains</code>
690: * with the added <code>Point</code> as an argument does not
691: * necessarily return <code>true</code>. The <code>contains</code>
692: * method does not return <code>true</code> for points on the right
693: * or bottom edges of a <code>Rectangle</code>. Therefore if the added
694: * <code>Point</code> falls on the right or bottom edge of the
695: * enlarged <code>Rectangle</code>, <code>contains</code> returns
696: * <code>false</code> for that <code>Point</code>.
697: * @param pt the new <code>Point</code> to add to this
698: * <code>Rectangle</code>
699: */
700: public void add(Point pt) {
701: add(pt.x, pt.y);
702: }
703:
704: /**
705: * Adds a <code>Rectangle</code> to this <code>Rectangle</code>.
706: * The resulting <code>Rectangle</code> is the union of the two
707: * rectangles.
708: * @param r the specified <code>Rectangle</code>
709: */
710: public void add(Rectangle r) {
711: int x1 = Math.min(x, r.x);
712: int x2 = Math.max(x + width, r.x + r.width);
713: int y1 = Math.min(y, r.y);
714: int y2 = Math.max(y + height, r.y + r.height);
715: x = x1;
716: y = y1;
717: width = x2 - x1;
718: height = y2 - y1;
719: }
720:
721: /**
722: * Resizes the <code>Rectangle</code> both horizontally and vertically.
723: * <p>
724: * This method modifies the <code>Rectangle</code> so that it is
725: * <code>h</code> units larger on both the left and right side,
726: * and <code>v</code> units larger at both the top and bottom.
727: * <p>
728: * The new <code>Rectangle</code> has (<code>x - h</code>,
729: * <code>y - v</code>) as its top-left corner, a
730: * width of
731: * <code>width</code> <code>+</code> <code>2h</code>,
732: * and a height of
733: * <code>height</code> <code>+</code> <code>2v</code>.
734: * <p>
735: * If negative values are supplied for <code>h</code> and
736: * <code>v</code>, the size of the <code>Rectangle</code>
737: * decreases accordingly.
738: * The <code>grow</code> method does not check whether the resulting
739: * values of <code>width</code> and <code>height</code> are
740: * non-negative.
741: * @param h the horizontal expansion
742: * @param v the vertical expansion
743: */
744: public void grow(int h, int v) {
745: x -= h;
746: y -= v;
747: width += h * 2;
748: height += v * 2;
749: }
750:
751: /**
752: * Determines whether or not this <code>Rectangle</code> is empty. A
753: * <code>Rectangle</code> is empty if its width or its height is less
754: * than or equal to zero.
755: * @return <code>true</code> if this <code>Rectangle</code> is empty;
756: * <code>false</code> otherwise.
757: */
758: public boolean isEmpty() {
759: return (width <= 0) || (height <= 0);
760: }
761:
762: /**
763: * Determines where the specified coordinates lie with respect
764: * to this <code>Rectangle</code>.
765: * This method computes a binary OR of the appropriate mask values
766: * indicating, for each side of this <code>Rectangle</code>,
767: * whether or not the specified coordinates are on the same side of the
768: * edge as the rest of this <code>Rectangle</code>.
769: * @param x the specified x coordinate
770: * @param y the specified y coordinate
771: * @return the logical OR of all appropriate out codes.
772: * @see #OUT_LEFT
773: * @see #OUT_TOP
774: * @see #OUT_RIGHT
775: * @see #OUT_BOTTOM
776: */
777: public int outcode(double x, double y) {
778: /*
779: * Calculate in doubel to avoud rounding errors!
780: */
781: int out = 0;
782: if (this .width <= 0) {
783: out |= OUT_LEFT | OUT_RIGHT;
784: } else if (x < this .x) {
785: out |= OUT_LEFT;
786: } else if (x > this .x + (double) this .width) {
787: out |= OUT_RIGHT;
788: }
789: if (this .height <= 0) {
790: out |= OUT_TOP | OUT_BOTTOM;
791: } else if (y < this .y) {
792: out |= OUT_TOP;
793: } else if (y > this .y + (double) this .height) {
794: out |= OUT_BOTTOM;
795: }
796: return out;
797: }
798:
799: /**
800: * Returns a new {@link Rectangle2D} object
801: * representing the intersection of this <code>Rectangle</code> with the
802: * specified <code>Rectangle2D</code>.
803: * @param r the <code>Rectangle2D</code> to be intersected
804: * with this <code>Rectangle</code>
805: * @return the largest <code>Rectangle2D</code> contained in both the
806: * specified <code>Rectangle2D</code> and in
807: * this <code>Rectangle</code>.
808: */
809: public Rectangle2D createIntersection(Rectangle2D r) {
810: if (r instanceof Rectangle) {
811: return intersection((Rectangle) r);
812: }
813: Rectangle2D dest = new Rectangle2D.Double();
814: Rectangle2D.intersect(this , r, dest);
815: return dest;
816: }
817:
818: /**
819: * Returns a new <code>Rectangle2D</code> object representing the
820: * union of this <code>Rectangle</code> with the specified
821: * <code>Rectangle2D</code>.
822: * @param r the <code>Rectangle2D</code> to be combined with
823: * this <code>Rectangle</code>
824: * @return the smallest <code>Rectangle2D</code> containing
825: * both the specified <code>Rectangle2D</code> and this
826: * <code>Rectangle</code>.
827: */
828: public Rectangle2D createUnion(Rectangle2D r) {
829: if (r instanceof Rectangle) {
830: return union((Rectangle) r);
831: }
832: Rectangle2D dest = new Rectangle2D.Double();
833: Rectangle2D.union(this , r, dest);
834: return dest;
835: }
836:
837: /**
838: * Checks whether two rectangles are equal.
839: * <p>
840: * The result is <code>true</code> if and only if the argument is not
841: * <code>null</code> and is a <code>Rectangle</code> object that has the
842: * same top-left corner, width, and height as this <code>Rectangle</code>.
843: * @param obj the <code>Object</code> to compare with
844: * this <code>Rectangle</code>
845: * @return <code>true</code> if the objects are equal;
846: * <code>false</code> otherwise.
847: */
848: public boolean equals(Object obj) {
849: if (obj instanceof Rectangle) {
850: Rectangle r = (Rectangle) obj;
851: return ((x == r.x) && (y == r.y) && (width == r.width) && (height == r.height));
852: }
853: return super .equals(obj);
854: }
855:
856: /**
857: * Returns a <code>String</code> representing this
858: * <code>Rectangle</code> and its values.
859: * @return a <code>String</code> representing this
860: * <code>Rectangle</code> object's coordinate and size values.
861: */
862: public String toString() {
863: return getClass().getName() + "[x=" + x + ",y=" + y + ",width="
864: + width + ",height=" + height + "]";
865: }
866: }
867: //#endif
|