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