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.Rectangle2D.
007: */
008:
009: //#ifndef j2se
010: package org.awt.geom;
011:
012: /**
013: * The <code>Rectangle2D</code> class describes a rectangle
014: * defined by a location (x, y) and dimension
015: * (w x h).
016: * <p>
017: * This class is only the abstract superclass for all objects that
018: * store a 2D rectangle.
019: * The actual storage representation of the coordinates is left to
020: * the subclass.
021: */
022: public abstract class Rectangle2D
023: //extends RectangularShape
024: //implements Cloneable
025: {
026: /**
027: * The bitmask that indicates that a point lies to the left of
028: * this <code>Rectangle2D</code>.
029: */
030: public static final int OUT_LEFT = 1;
031:
032: /**
033: * The bitmask that indicates that a point lies above
034: * this <code>Rectangle2D</code>.
035: */
036: public static final int OUT_TOP = 2;
037:
038: /**
039: * The bitmask that indicates that a point lies to the right of
040: * this <code>Rectangle2D</code>.
041: */
042: public static final int OUT_RIGHT = 4;
043:
044: /**
045: * The bitmask that indicates that a point lies below
046: * this <code>Rectangle2D</code>.
047: */
048: public static final int OUT_BOTTOM = 8;
049:
050: /**
051: * The <code>Float</code> class defines a rectangle specified in float
052: * coordinates.
053: */
054: public static class Float extends Rectangle2D {
055: /**
056: * The x coordinate of this <code>Rectangle2D</code>.
057: */
058: public float x;
059:
060: /**
061: * The y coordinate of this <code>Rectangle2D</code>.
062: */
063: public float y;
064:
065: /**
066: * The width of this <code>Rectangle2D</code>.
067: */
068: public float width;
069:
070: /**
071: * The height of this <code>Rectangle2D</code>.
072: */
073: public float height;
074:
075: /**
076: * Constructs a new <code>Rectangle2D</code>, initialized to
077: * location (0.0, 0.0) and size (0.0, 0.0).
078: */
079: public Float() {
080: }
081:
082: /**
083: * Constructs and initializes a <code>Rectangle2D</code>
084: * from the specified float coordinates.
085: * @param x, y the coordinates of the
086: * upper left corner of the newly constructed
087: * <code>Rectangle2D</code>
088: * @param w the width of the newly constructed
089: * <code>Rectangle2D</code>
090: * @param h the height of the newly constructed
091: * <code>Rectangle2D</code>
092: */
093: public Float(float x, float y, float w, float h) {
094: setRect(x, y, w, h);
095: }
096:
097: //#ifdef notdef
098: public Object clone() /*throws CloneNotSupportedException*/{
099: return new Float(x, y, width, height);
100: }
101:
102: //#endif
103: /**
104: * Returns the X coordinate of this <code>Rectangle2D</code>
105: * in double precision.
106: * @return the X coordinate of this <code>Rectangle2D</code>.
107: */
108: public double getX() {
109: return (double) x;
110: }
111:
112: /**
113: * Returns the Y coordinate of this <code>Rectangle2D</code>
114: * in double precision.
115: * @return the Y coordinate of this <code>Rectangle2D</code>.
116: */
117: public double getY() {
118: return (double) y;
119: }
120:
121: /**
122: * Returns the width of this <code>Rectangle2D</code>
123: * in double precision.
124: * @return the width of this <code>Rectangle2D</code>.
125: */
126: public double getWidth() {
127: return (double) width;
128: }
129:
130: /**
131: * Returns the height of this <code>Rectangle2D</code>
132: * in double precision.
133: * @return the height of this <code>Rectangle2D</code>.
134: */
135: public double getHeight() {
136: return (double) height;
137: }
138:
139: /**
140: * Determines whether or not this <code>Rectangle2D</code>
141: * is empty.
142: * @return <code>true</code> if this <code>Rectangle2D</code>
143: * is empty; <code>false</code> otherwise.
144: */
145: public boolean isEmpty() {
146: return (width <= 0.0f) || (height <= 0.0f);
147: }
148:
149: /**
150: * Sets the location and size of this <code>Rectangle2D</code>
151: * to the specified float values.
152: * @param x, y the coordinates to which to set the
153: * location of the upper left corner of this
154: * <code>Rectangle2D</code>
155: * @param w the value to use to set the width of this
156: * <code>Rectangle2D</code>
157: * @param h the value to use to set the height of this
158: * <code>Rectangle2D</code>
159: */
160: public void setRect(float x, float y, float w, float h) {
161: this .x = x;
162: this .y = y;
163: this .width = w;
164: this .height = h;
165: }
166:
167: /**
168: * Sets the location and size of this <code>Rectangle2D</code>
169: * to the specified double values.
170: * @param x, y the coordinates to which to set the
171: * location of the upper left corner of this
172: * <code>Rectangle2D</code>
173: * @param w the value to use to set the width of this
174: * <code>Rectangle2D</code>
175: * @param h the value to use to set the height of this
176: * <code>Rectangle2D</code>
177: */
178: public void setRect(double x, double y, double w, double h) {
179: this .x = (float) x;
180: this .y = (float) y;
181: this .width = (float) w;
182: this .height = (float) h;
183: }
184:
185: /**
186: * Sets this <code>Rectangle2D</code> to be the same as the
187: * specified <code>Rectangle2D</code>.
188: * @param r the specified <code>Rectangle2D</code>
189: */
190: public void setRect(Rectangle2D r) {
191: this .x = (float) r.getX();
192: this .y = (float) r.getY();
193: this .width = (float) r.getWidth();
194: this .height = (float) r.getHeight();
195: }
196:
197: /**
198: * Determines where the specified float coordinates lie with respect
199: * to this <code>Rectangle2D</code>.
200: * This method computes a binary OR of the appropriate mask values
201: * indicating, for each side of this <code>Rectangle2D</code>,
202: * whether or not the specified coordinates are on the same side
203: * of the edge as the rest of this <code>Rectangle2D</code>.
204: * @param x, y the specified coordinates
205: * @return the logical OR of all appropriate out codes.
206: * @see Rectangle2D#OUT_LEFT
207: * @see Rectangle2D#OUT_TOP
208: * @see Rectangle2D#OUT_RIGHT
209: * @see Rectangle2D#OUT_BOTTOM
210: */
211: public int outcode(double x, double y) {
212: /*
213: * use double to avoid rounding errors...
214: */
215: int out = 0;
216: if (this .width <= 0) {
217: out |= OUT_LEFT | OUT_RIGHT;
218: } else if (x < this .x) {
219: out |= OUT_LEFT;
220: } else if (x > this .x + (double) this .width) {
221: out |= OUT_RIGHT;
222: }
223: if (this .height <= 0) {
224: out |= OUT_TOP | OUT_BOTTOM;
225: } else if (y < this .y) {
226: out |= OUT_TOP;
227: } else if (y > this .y + (double) this .height) {
228: out |= OUT_BOTTOM;
229: }
230: return out;
231: }
232:
233: /**
234: * Returns the high precision bounding box of this
235: * <code>Rectangle2D</code>.
236: * @return the bounding box of this <code>Rectangle2D</code>.
237: */
238: public Rectangle2D getBounds2D() {
239: return new Float(x, y, width, height);
240: }
241:
242: /**
243: * Returns a new <code>Rectangle2D</code> object
244: * representing the intersection of
245: * this <code>Rectangle2D</code> with the specified
246: * <code>Rectangle2D</code>.
247: * @param r the <code>Rectangle2D</code> that is
248: * intersected with this <code>Rectangle2D</code>
249: * @return the largest <code>Rectangle2D</code>
250: * contained in both the specified
251: * <code>Rectangle2D</code> and in this
252: * <code>Rectangle2D</code>.
253: */
254: public Rectangle2D createIntersection(Rectangle2D r) {
255: Rectangle2D dest;
256: if (r instanceof Float) {
257: dest = new Rectangle2D.Float();
258: } else {
259: dest = new Rectangle2D.Double();
260: }
261: Rectangle2D.intersect(this , r, dest);
262: return dest;
263: }
264:
265: /**
266: * Returns a new <code>Rectangle2D</code> object
267: * representing the union of this <code>Rectangle2D</code>
268: * with the specified <code>Rectangle2D</code>.
269: * @param r the <code>Rectangle2D</code> to be combined with
270: * this <code>Rectangle2D</code>
271: * @return the smallest <code>Rectangle2D</code> containing
272: * both the specified <code>Rectangle2D</code> and this
273: * <code>Rectangle2D</code>.
274: */
275: public Rectangle2D createUnion(Rectangle2D r) {
276: Rectangle2D dest;
277: if (r instanceof Float) {
278: dest = new Rectangle2D.Float();
279: } else {
280: dest = new Rectangle2D.Double();
281: }
282: Rectangle2D.union(this , r, dest);
283: return dest;
284: }
285:
286: /**
287: * Returns the <code>String</code> representation of this
288: * <code>Rectangle2D</code>.
289: * @return a <code>String</code> representing this
290: * <code>Rectangle2D</code>.
291: */
292: public String toString() {
293: return getClass().getName() + "[x=" + x + ",y=" + y + ",w="
294: + width + ",h=" + height + "]";
295: }
296: }
297:
298: /**
299: * The <code>Double</code> class defines a rectangle specified in
300: * double coordinates.
301: */
302: public static class Double extends Rectangle2D {
303: /**
304: * The x coordinate of this <code>Rectangle2D</code>.
305: */
306: public double x;
307:
308: /**
309: * The y coordinate of this <code>Rectangle2D</code>.
310: */
311: public double y;
312:
313: /**
314: * The width of this <code>Rectangle2D</code>.
315: */
316: public double width;
317:
318: /**
319: * The height of this <code>Rectangle2D</code>.
320: */
321: public double height;
322:
323: /**
324: * Constructs a new <code>Rectangle2D</code>, initialized to
325: * location (0, 0) and size (0, 0).
326: */
327: public Double() {
328: }
329:
330: /**
331: * Constructs and initializes a <code>Rectangle2D</code>
332: * from the specified double coordinates.
333: * @param x, y the coordinates of the upper left corner
334: * of the newly constructed <code>Rectangle2D</code>
335: * @param w the width of the
336: * newly constructed <code>Rectangle2D</code>
337: * @param h the height of the
338: * newly constructed <code>Rectangle2D</code>
339: */
340: public Double(double x, double y, double w, double h) {
341: setRect(x, y, w, h);
342: }
343:
344: //#ifdef notdef
345: public Object clone() /*throws CloneNotSupportedException*/{
346: return new Double(x, y, width, height);
347: }
348:
349: //#endif
350: /**
351: * Returns the X coordinate of this <code>Rectangle2D</code> in
352: * double precision.
353: * @return the X coordinate of this <code>Rectangle2D</code>.
354: */
355: public double getX() {
356: return x;
357: }
358:
359: /**
360: * Returns the Y coordinate of this <code>Rectangle2D</code> in
361: * double precision.
362: * @return the Y coordinate of this <code>Rectangle2D</code>.
363: */
364: public double getY() {
365: return y;
366: }
367:
368: /**
369: * Returns the width of this <code>Rectangle2D</code> in
370: * double precision.
371: * @return the width of this <code>Rectangle2D</code>.
372: */
373: public double getWidth() {
374: return width;
375: }
376:
377: /**
378: * Returns the height of this <code>Rectangle2D</code> in
379: * double precision.
380: * @return the height of this <code>Rectangle2D</code>.
381: */
382: public double getHeight() {
383: return height;
384: }
385:
386: /**
387: * Determines whether or not this <code>Rectangle2D</code>
388: * is empty.
389: * @return <code>true</code> if this <code>Rectangle2D</code>
390: * is empty; <code>false</code> otherwise.
391: */
392: public boolean isEmpty() {
393: return (width <= 0.0) || (height <= 0.0);
394: }
395:
396: /**
397: * Sets the location and size of this <code>Rectangle2D</code>
398: * to the specified double values.
399: * @param x, y the coordinates to which to set the
400: * upper left corner of this <code>Rectangle2D</code>
401: * @param w the value to use to set the width of this
402: * <code>Rectangle2D</code>
403: * @param h the value to use to set the height of this
404: * <code>Rectangle2D</code>
405: */
406: public void setRect(double x, double y, double w, double h) {
407: this .x = x;
408: this .y = y;
409: this .width = w;
410: this .height = h;
411: }
412:
413: /**
414: * Sets this <code>Rectangle2D</code> to be the same as the
415: * specified <code>Rectangle2D</code>.
416: * @param r the specified <code>Rectangle2D</code>
417: */
418: public void setRect(Rectangle2D r) {
419: this .x = r.getX();
420: this .y = r.getY();
421: this .width = r.getWidth();
422: this .height = r.getHeight();
423: }
424:
425: /**
426: * Determines where the specified double coordinates lie with respect
427: * to this <code>Rectangle2D</code>.
428: * This method computes a binary OR of the appropriate mask values
429: * indicating, for each side of this <code>Rectangle2D</code>,
430: * whether or not the specified coordinates are on the same side
431: * of the edge as the rest of this <code>Rectangle2D</code>.
432: * @param x, y the specified coordinates
433: * @return the logical OR of all appropriate out codes.
434: * @see Rectangle2D#OUT_LEFT
435: * @see Rectangle2D#OUT_TOP
436: * @see Rectangle2D#OUT_RIGHT
437: * @see Rectangle2D#OUT_BOTTOM
438: */
439: public int outcode(double x, double y) {
440: int out = 0;
441: if (this .width <= 0) {
442: out |= OUT_LEFT | OUT_RIGHT;
443: } else if (x < this .x) {
444: out |= OUT_LEFT;
445: } else if (x > this .x + this .width) {
446: out |= OUT_RIGHT;
447: }
448: if (this .height <= 0) {
449: out |= OUT_TOP | OUT_BOTTOM;
450: } else if (y < this .y) {
451: out |= OUT_TOP;
452: } else if (y > this .y + this .height) {
453: out |= OUT_BOTTOM;
454: }
455: return out;
456: }
457:
458: /**
459: * Returns the high precision bounding box of this
460: * <code>Rectangle2D</code>.
461: * @return the bounding box of this <code>Rectangle2D</code>.
462: */
463: public Rectangle2D getBounds2D() {
464: return new Double(x, y, width, height);
465: }
466:
467: /**
468: * Returns a new <code>Rectangle2D</code> object representing
469: * the intersection of this <code>Rectangle2D</code> with the
470: * specified <code>Rectangle2D</code>.
471: * @param r the <code>Rectangle2D</code> to be intersected
472: * with this <code>Rectangle2D</code>
473: * @return the largest <code>Rectangle2D</code> contained in
474: * both the specified <code>Rectangle2D</code> and in this
475: * <code>Rectangle2D</code>.
476: */
477: public Rectangle2D createIntersection(Rectangle2D r) {
478: Rectangle2D dest = new Rectangle2D.Double();
479: Rectangle2D.intersect(this , r, dest);
480: return dest;
481: }
482:
483: /**
484: * Returns a new <code>Rectangle2D</code> object representing
485: * the union of this <code>Rectangle2D</code> with the
486: * specified <code>Rectangle2D</code>.
487: * @param r the <code>Rectangle2D</code> to be combined with
488: * this <code>Rectangle2D</code>
489: * @return the smallest <code>Rectangle2D</code> containing
490: * both the specified <code>Rectangle2D</code> and this
491: * <code>Rectangle2D</code>.
492: */
493: public Rectangle2D createUnion(Rectangle2D r) {
494: Rectangle2D dest = new Rectangle2D.Double();
495: Rectangle2D.union(this , r, dest);
496: return dest;
497: }
498:
499: /**
500: * Returns the <code>String</code> representation of this
501: * <code>Rectangle2D</code>.
502: * @return a <code>String</code> representing this
503: * <code>Rectangle2D</code>.
504: */
505: public String toString() {
506: return getClass().getName() + "[x=" + x + ",y=" + y + ",w="
507: + width + ",h=" + height + "]";
508: }
509: }
510:
511: /**
512: * This is an abstract class that cannot be instantiated directly.
513: * Type-specific implementation subclasses are available for
514: * instantiation and provide a number of formats for storing
515: * the information necessary to satisfy the various accessor
516: * methods below.
517: *
518: * @see java.awt.geom.Rectangle2D.Float
519: * @see java.awt.geom.Rectangle2D.Double
520: * @see java.awt.Rectangle
521: */
522: protected Rectangle2D() {
523: }
524:
525: /**
526: * Sets the location and size of this <code>Rectangle2D</code>
527: * to the specified double values.
528: * @param x, y the coordinates to which to set the
529: * location of the upper left corner of this
530: * <code>Rectangle2D</code>
531: * @param w the value to use to set the width of this
532: * <code>Rectangle2D</code>
533: * @param h the value to use to set the height of this
534: * <code>Rectangle2D</code>
535: */
536: public abstract void setRect(double x, double y, double w, double h);
537:
538: /**
539: * Sets this <code>Rectangle2D</code> to be the same as the specified
540: * <code>Rectangle2D</code>.
541: * @param r the specified <code>Rectangle2D</code>
542: */
543: public void setRect(Rectangle2D r) {
544: setRect(r.getX(), r.getY(), r.getWidth(), r.getHeight());
545: }
546:
547: /**
548: * Tests if the specified line segment intersects the interior of this
549: * <code>Rectangle2D</code>.
550: * @param x1, y1 the first endpoint of the specified
551: * line segment
552: * @param x2, y2 the second endpoint of the specified
553: * line segment
554: * @return <code>true</code> if the specified line segment intersects
555: * the interior of this <code>Rectangle2D</code>; <code>false</code>
556: * otherwise.
557: */
558: public boolean intersectsLine(double x1, double y1, double x2,
559: double y2) {
560: int out1, out2;
561: if ((out2 = outcode(x2, y2)) == 0) {
562: return true;
563: }
564: while ((out1 = outcode(x1, y1)) != 0) {
565: if ((out1 & out2) != 0) {
566: return false;
567: }
568: if ((out1 & (OUT_LEFT | OUT_RIGHT)) != 0) {
569: double x = getX();
570: if ((out1 & OUT_RIGHT) != 0) {
571: x += getWidth();
572: }
573: y1 = y1 + (x - x1) * (y2 - y1) / (x2 - x1);
574: x1 = x;
575: } else {
576: double y = getY();
577: if ((out1 & OUT_BOTTOM) != 0) {
578: y += getHeight();
579: }
580: x1 = x1 + (y - y1) * (x2 - x1) / (y2 - y1);
581: y1 = y;
582: }
583: }
584: return true;
585: }
586:
587: //#ifdef notdef
588: /**
589: * Tests if the specified line segment intersects the interior of this
590: * <code>Rectangle2D</code>.
591: * @param l the specified {@link Line2D} to test for intersection
592: * with the interior of this <code>Rectangle2D</code>
593: * @return <code>true</code> if the specified <code>Line2D</code>
594: * intersects the interior of this <code>Rectangle2D</code>;
595: * <code>false</code> otherwise.
596: */
597: public boolean intersectsLine(Line2D l) {
598: return intersectsLine(l.getX1(), l.getY1(), l.getX2(), l
599: .getY2());
600: }
601:
602: //#endif
603:
604: /**
605: * Determines where the specified coordinates lie with respect
606: * to this <code>Rectangle2D</code>.
607: * This method computes a binary OR of the appropriate mask values
608: * indicating, for each side of this <code>Rectangle2D</code>,
609: * whether or not the specified coordinates are on the same side
610: * of the edge as the rest of this <code>Rectangle2D</code>.
611: * @param x, y the specified coordinates
612: * @return the logical OR of all appropriate out codes.
613: * @see #OUT_LEFT
614: * @see #OUT_TOP
615: * @see #OUT_RIGHT
616: * @see #OUT_BOTTOM
617: */
618: public abstract int outcode(double x, double y);
619:
620: /**
621: * Determines where the specified {@link Point2D} lies with
622: * respect to this <code>Rectangle2D</code>.
623: * This method computes a binary OR of the appropriate mask values
624: * indicating, for each side of this <code>Rectangle2D</code>,
625: * whether or not the specified <code>Point2D</code> is on the same
626: * side of the edge as the rest of this <code>Rectangle2D</code>.
627: * @param p the specified <code>Point2D</code>
628: * @return the logical OR of all appropriate out codes.
629: * @see #OUT_LEFT
630: * @see #OUT_TOP
631: * @see #OUT_RIGHT
632: * @see #OUT_BOTTOM
633: */
634: public int outcode(Point2D p) {
635: return outcode(p.getX(), p.getY());
636: }
637:
638: /**
639: * Sets the location and size of the outer bounds of this
640: * <code>Rectangle2D</code> to the specified rectangular values.
641: * @param x, y the coordinates to which to set the
642: * location of the upper left corner of the outer bounds of
643: * this <code>Rectangle2D</code>
644: * @param w the value to use to set the width of the outer
645: * bounds of this <code>Rectangle2D</code>
646: * @param h the value to use to set the height of the outer
647: * bounds of this <code>Rectangle2D</code>
648: */
649: public void setFrame(double x, double y, double w, double h) {
650: setRect(x, y, w, h);
651: }
652:
653: /**
654: * Returns the high precision bounding box of this
655: * <code>Rectangle2D</code>.
656: * @return the bounding box of this <code>Rectangle2D</code>.
657: */
658: //#ifdef j2se
659: public Rectangle2D getBounds2D() {
660: return (Rectangle2D) clone();
661: }
662:
663: //#else
664: public abstract Rectangle2D getBounds2D();
665:
666: //#endif
667:
668: /**
669: * Tests if a specified coordinate is inside the boundary of this
670: * <code>Rectangle2D</code>.
671: * @param x, y the coordinates to test
672: * @return <code>true</code> if the specified coordinates are
673: * inside the boundary of this <code>Rectangle2D</code>;
674: * <code>false</code> otherwise.
675: */
676: public boolean contains(double x, double y) {
677: double x0 = getX();
678: double y0 = getY();
679: return (x >= x0 && y >= y0 && x < x0 + getWidth() && y < y0
680: + getHeight());
681: }
682:
683: /**
684: * Tests if the interior of this <code>Rectangle2D</code>
685: * intersects the interior of a specified set of rectangular
686: * coordinates.
687: * @param x, y the coordinates of the upper left corner
688: * of the specified set of rectangular coordinates
689: * @param w the width of the specified set of rectangular
690: * coordinates
691: * @param h the height of the specified set of rectangular
692: * coordinates
693: * @return <code>true</code> if this <code>Rectangle2D</code>
694: * intersects the interior of a specified set of rectangular
695: * coordinates; <code>false</code> otherwise.
696: */
697: public boolean intersects(double x, double y, double w, double h) {
698: if (isEmpty() || w <= 0 || h <= 0) {
699: return false;
700: }
701: double x0 = getX();
702: double y0 = getY();
703: return (x + w > x0 && y + h > y0 && x < x0 + getWidth() && y < y0
704: + getHeight());
705: }
706:
707: /**
708: * Tests if the interior of this <code>Rectangle2D</code> entirely
709: * contains the specified set of rectangular coordinates.
710: * @param x, y the coordinates of the upper left corner
711: * of the specified set of rectangular coordinates
712: * @param w the width of the specified set of rectangular
713: * coordinates
714: * @param h the height of the specified set of rectangular
715: * coordinates
716: * @return <code>true</code> if this <code>Rectangle2D</code>
717: * entirely contains specified set of rectangular
718: * coordinates; <code>false</code> otherwise.
719: */
720: public boolean contains(double x, double y, double w, double h) {
721: if (isEmpty() || w <= 0 || h <= 0) {
722: return false;
723: }
724: double x0 = getX();
725: double y0 = getY();
726: return (x >= x0 && y >= y0 && (x + w) <= x0 + getWidth() && (y + h) <= y0
727: + getHeight());
728: }
729:
730: /**
731: * Returns a new <code>Rectangle2D</code> object representing the
732: * intersection of this <code>Rectangle2D</code> with the specified
733: * <code>Rectangle2D</code>.
734: * @param r the <code>Rectangle2D</code> to be intersected with
735: * this <code>Rectangle2D</code>
736: * @return the largest <code>Rectangle2D</code> contained in both
737: * the specified <code>Rectangle2D</code> and in this
738: * <code>Rectangle2D</code>.
739: */
740: public abstract Rectangle2D createIntersection(Rectangle2D r);
741:
742: /**
743: * Intersects the pair of specified source <code>Rectangle2D</code>
744: * objects and puts the result into the specified destination
745: * <code>Rectangle2D</code> object. One of the source rectangles
746: * can also be the destination to avoid creating a third Rectangle2D
747: * object, but in this case the original points of this source
748: * rectangle will be overwritten by this method.
749: * @param src1 the first of a pair of <code>Rectangle2D</code>
750: * objects to be intersected with each other
751: * @param src2 the second of a pair of <code>Rectangle2D</code>
752: * objects to be intersected with each other
753: * @param dest the <code>Rectangle2D</code> that holds the
754: * results of the intersection of <code>src1</code> and
755: * <code>src2</code>
756: */
757: public static void intersect(Rectangle2D src1, Rectangle2D src2,
758: Rectangle2D dest) {
759: double x1 = Math.max(src1.getMinX(), src2.getMinX());
760: double y1 = Math.max(src1.getMinY(), src2.getMinY());
761: double x2 = Math.min(src1.getMaxX(), src2.getMaxX());
762: double y2 = Math.min(src1.getMaxY(), src2.getMaxY());
763: dest.setFrame(x1, y1, x2 - x1, y2 - y1);
764: }
765:
766: /**
767: * Returns a new <code>Rectangle2D</code> object representing the
768: * union of this <code>Rectangle2D</code> with the specified
769: * <code>Rectangle2D</code>.
770: * @param r the <code>Rectangle2D</code> to be combined with
771: * this <code>Rectangle2D</code>
772: * @return the smallest <code>Rectangle2D</code> containing both
773: * the specified <code>Rectangle2D</code> and this
774: * <code>Rectangle2D</code>.
775: */
776: public abstract Rectangle2D createUnion(Rectangle2D r);
777:
778: /**
779: * Unions the pair of source <code>Rectangle2D</code> objects
780: * and puts the result into the specified destination
781: * <code>Rectangle2D</code> object. One of the source rectangles
782: * can also be the destination to avoid creating a third Rectangle2D
783: * object, but in this case the original points of this source
784: * rectangle will be overwritten by this method.
785: * @param src1 the first of a pair of <code>Rectangle2D</code>
786: * objects to be combined with each other
787: * @param src2 the second of a pair of <code>Rectangle2D</code>
788: * objects to be combined with each other
789: * @param dest the <code>Rectangle2D</code> that holds the
790: * results of the union of <code>src1</code> and
791: * <code>src2</code>
792: */
793: public static void union(Rectangle2D src1, Rectangle2D src2,
794: Rectangle2D dest) {
795: double x1 = Math.min(src1.getMinX(), src2.getMinX());
796: double y1 = Math.min(src1.getMinY(), src2.getMinY());
797: double x2 = Math.max(src1.getMaxX(), src2.getMaxX());
798: double y2 = Math.max(src1.getMaxY(), src2.getMaxY());
799: dest.setFrameFromDiagonal(x1, y1, x2, y2);
800: }
801:
802: /**
803: * Adds a point, specified by the double precision arguments
804: * <code>newx</code> and <code>newy</code>, to this
805: * <code>Rectangle2D</code>. The resulting <code>Rectangle2D</code>
806: * is the smallest <code>Rectangle2D</code> that
807: * contains both the original <code>Rectangle2D</code> and the
808: * specified point.
809: * <p>
810: * After adding a point, a call to <code>contains</code> with the
811: * added point as an argument does not necessarily return
812: * <code>true</code>. The <code>contains</code> method does not
813: * return <code>true</code> for points on the right or bottom
814: * edges of a rectangle. Therefore, if the added point falls on
815: * the left or bottom edge of the enlarged rectangle,
816: * <code>contains</code> returns <code>false</code> for that point.
817: * @param newx, newy the coordinates of the new point
818: */
819: public void add(double newx, double newy) {
820: double x1 = Math.min(getMinX(), newx);
821: double x2 = Math.max(getMaxX(), newx);
822: double y1 = Math.min(getMinY(), newy);
823: double y2 = Math.max(getMaxY(), newy);
824: setRect(x1, y1, x2 - x1, y2 - y1);
825: }
826:
827: /**
828: * Adds the <code>Point2D</code> object <code>pt</code> to this
829: * <code>Rectangle2D</code>.
830: * The resulting <code>Rectangle2D</code> is the smallest
831: * <code>Rectangle2D</code> that contains both the original
832: * <code>Rectangle2D</code> and the specified <code>Point2D</code>.
833: * <p>
834: * After adding a point, a call to <code>contains</code> with the
835: * added point as an argument does not necessarily return
836: * <code>true</code>. The <code>contains</code>
837: * method does not return <code>true</code> for points on the right
838: * or bottom edges of a rectangle. Therefore, if the added point falls
839: * on the left or bottom edge of the enlarged rectangle,
840: * <code>contains</code> returns <code>false</code> for that point.
841: * @param pt the new <code>Point2D</code> to add to this
842: * <code>Rectangle2D</code>.
843: */
844: public void add(Point2D pt) {
845: add(pt.getX(), pt.getY());
846: }
847:
848: /**
849: * Adds a <code>Rectangle2D</code> object to this
850: * <code>Rectangle2D</code>. The resulting <code>Rectangle2D</code>
851: * is the union of the two <code>Rectangle2D</code> objects.
852: * @param r the <code>Rectangle2D</code> to add to this
853: * <code>Rectangle2D</code>.
854: */
855: public void add(Rectangle2D r) {
856: double x1 = Math.min(getMinX(), r.getMinX());
857: double x2 = Math.max(getMaxX(), r.getMaxX());
858: double y1 = Math.min(getMinY(), r.getMinY());
859: double y2 = Math.max(getMaxY(), r.getMaxY());
860: setRect(x1, y1, x2 - x1, y2 - y1);
861: }
862:
863: //#ifdef notdef
864: /**
865: * Returns an iteration object that defines the boundary of this
866: * <code>Rectangle2D</code>.
867: * The iterator for this class is multi-threaded safe, which means
868: * that this <code>Rectangle2D</code> class guarantees that
869: * modifications to the geometry of this <code>Rectangle2D</code>
870: * object do not affect any iterations of that geometry that
871: * are already in process.
872: * @param at an optional <code>AffineTransform</code> to be applied to
873: * the coordinates as they are returned in the iteration, or
874: * <code>null</code> if untransformed coordinates are desired
875: * @return the <code>PathIterator</code> object that returns the
876: * geometry of the outline of this
877: * <code>Rectangle2D</code>, one segment at a time.
878: */
879: public PathIterator getPathIterator(AffineTransform at) {
880: return new RectIterator(this , at);
881: }
882:
883: /**
884: * Returns an iteration object that defines the boundary of the
885: * flattened <code>Rectangle2D</code>. Since rectangles are already
886: * flat, the <code>flatness</code> parameter is ignored.
887: * The iterator for this class is multi-threaded safe, which means
888: * that this <code>Rectangle2D</code> class guarantees that
889: * modifications to the geometry of this <code>Rectangle2D</code>
890: * object do not affect any iterations of that geometry that
891: * are already in process.
892: * @param at an optional <code>AffineTransform</code> to be applied to
893: * the coordinates as they are returned in the iteration, or
894: * <code>null</code> if untransformed coordinates are desired
895: * @param flatness the maximum distance that the line segments used to
896: * approximate the curved segments are allowed to deviate from any
897: * point on the original curve. Since rectangles are already flat,
898: * the <code>flatness</code> parameter is ignored.
899: * @return the <code>PathIterator</code> object that returns the
900: * geometry of the outline of this
901: * <code>Rectangle2D</code>, one segment at a time.
902: */
903: public PathIterator getPathIterator(AffineTransform at,
904: double flatness) {
905: return new RectIterator(this , at);
906: }
907:
908: //#endif
909:
910: public abstract double getX();
911:
912: public abstract double getY();
913:
914: public abstract double getWidth();
915:
916: public abstract double getHeight();
917:
918: public abstract boolean isEmpty();
919:
920: public double getMinX() {
921: return getX();
922: }
923:
924: public double getMaxX() {
925: return getX() + getWidth();
926: }
927:
928: public double getMinY() {
929: return getY();
930: }
931:
932: public double getMaxY() {
933: return getX() + getWidth();
934: }
935:
936: public void setFrameFromDiagonal(double x1, double y1, double x2,
937: double y2) {
938: if (x2 < x1) {
939: double t = x1;
940: x1 = x2;
941: x2 = t;
942: }
943: if (y2 < y1) {
944: double t = y1;
945: y1 = y2;
946: y2 = t;
947: }
948: setFrame(x1, y1, x2 - x1, y2 - y1);
949: }
950:
951: /**
952: * Returns the hashcode for this <code>Rectangle2D</code>.
953: * @return the hashcode for this <code>Rectangle2D</code>.
954: */
955: public int hashCode() {
956: long bits = java.lang.Double.doubleToLongBits(getX());
957: bits += java.lang.Double.doubleToLongBits(getY()) * 37;
958: bits += java.lang.Double.doubleToLongBits(getWidth()) * 43;
959: bits += java.lang.Double.doubleToLongBits(getHeight()) * 47;
960: return (((int) bits) ^ ((int) (bits >> 32)));
961: }
962:
963: /**
964: * Determines whether or not the specified <code>Object</code> is
965: * equal to this <code>Rectangle2D</code>. The specified
966: * <code>Object</code> is equal to this <code>Rectangle2D</code>
967: * if it is an instance of <code>Rectangle2D</code> and if its
968: * location and size are the same as this <code>Rectangle2D</code>.
969: * @param obj an <code>Object</code> to be compared with this
970: * <code>Rectangle2D</code>.
971: * @return <code>true</code> if <code>obj</code> is an instance
972: * of <code>Rectangle2D</code> and has
973: * the same values; <code>false</code> otherwise.
974: */
975: public boolean equals(Object obj) {
976: if (obj == this ) {
977: return true;
978: }
979: if (obj instanceof Rectangle2D) {
980: Rectangle2D r2d = (Rectangle2D) obj;
981: return ((getX() == r2d.getX()) && (getY() == r2d.getY())
982: && (getWidth() == r2d.getWidth()) && (getHeight() == r2d
983: .getHeight()));
984: }
985: return false;
986: }
987: }
988: //#endif
|