1. /*
  2. * @(#)Rectangle2D.java 1.22 00/02/02
  3. *
  4. * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
  5. *
  6. * This software is the proprietary information of Sun Microsystems, Inc.
  7. * Use is subject to license terms.
  8. *
  9. */
  10. package java.awt.geom;
  11. /**
  12. * The <code>Rectangle2D</code> class describes a rectangle
  13. * defined by a location (x, y) and dimension
  14. * (w x h).
  15. * <p>
  16. * This class is only the abstract superclass for all objects that
  17. * store a 2D rectangle.
  18. * The actual storage representation of the coordinates is left to
  19. * the subclass.
  20. *
  21. * @version 1.22, 02/02/00
  22. * @author Jim Graham
  23. */
  24. public abstract class Rectangle2D extends RectangularShape {
  25. /**
  26. * The bitmask that indicates that a point lies to the left of
  27. * this <code>Rectangle2D</code>.
  28. * @since 1.2
  29. */
  30. public static final int OUT_LEFT = 1;
  31. /**
  32. * The bitmask that indicates that a point lies above
  33. * this <code>Rectangle2D</code>.
  34. * @since 1.2
  35. */
  36. public static final int OUT_TOP = 2;
  37. /**
  38. * The bitmask that indicates that a point lies to the right of
  39. * this <code>Rectangle2D</code>.
  40. * @since 1.2
  41. */
  42. public static final int OUT_RIGHT = 4;
  43. /**
  44. * The bitmask that indicates that a point lies below
  45. * this <code>Rectangle2D</code>.
  46. * @since 1.2
  47. */
  48. public static final int OUT_BOTTOM = 8;
  49. /**
  50. * The <code>Float</code> class defines a rectangle specified in float
  51. * coordinates.
  52. * @since 1.2
  53. */
  54. public static class Float extends Rectangle2D {
  55. /**
  56. * The x coordinate of this <code>Rectangle2D</code>.
  57. * @since 1.2
  58. */
  59. public float x;
  60. /**
  61. * The y coordinate of this <code>Rectangle2D</code>.
  62. * @since 1.2
  63. */
  64. public float y;
  65. /**
  66. * The width of this <code>Rectangle2D</code>.
  67. * @since 1.2
  68. */
  69. public float width;
  70. /**
  71. * The height of this <code>Rectangle2D</code>.
  72. * @since 1.2
  73. */
  74. public float height;
  75. /**
  76. * Constructs a new <code>Rectangle2D</code>, initialized to
  77. * location (0.0, 0.0) and size (0.0, 0.0).
  78. * @since 1.2
  79. */
  80. public Float() {
  81. }
  82. /**
  83. * Constructs and initializes a <code>Rectangle2D</code>
  84. * from the specified float coordinates.
  85. * @param x, y the coordinates of the
  86. * upper left corner of the newly constructed
  87. * <code>Rectangle2D</code>
  88. * @param w the width of the newly constructed
  89. * <code>Rectangle2D</code>
  90. * @param h the height of the newly constructed
  91. * <code>Rectangle2D</code>
  92. * @since 1.2
  93. */
  94. public Float(float x, float y, float w, float h) {
  95. setRect(x, y, w, h);
  96. }
  97. /**
  98. * Returns the X coordinate of this <code>Rectangle2D</code>
  99. * in double precision.
  100. * @return the X coordinate of this <code>Rectangle2D</code>.
  101. * @since 1.2
  102. */
  103. public double getX() {
  104. return (double) x;
  105. }
  106. /**
  107. * Returns the Y coordinate of this <code>Rectangle2D</code>
  108. * in double precision.
  109. * @return the Y coordinate of this <code>Rectangle2D</code>.
  110. * @since 1.2
  111. */
  112. public double getY() {
  113. return (double) y;
  114. }
  115. /**
  116. * Returns the width of this <code>Rectangle2D</code>
  117. * in double precision.
  118. * @return the width of this <code>Rectangle2D</code>.
  119. * @since 1.2
  120. */
  121. public double getWidth() {
  122. return (double) width;
  123. }
  124. /**
  125. * Returns the height of this <code>Rectangle2D</code>
  126. * in double precision.
  127. * @return the height of this <code>Rectangle2D</code>.
  128. * @since 1.2
  129. */
  130. public double getHeight() {
  131. return (double) height;
  132. }
  133. /**
  134. * Determines whether or not this <code>Rectangle2D</code>
  135. * is empty.
  136. * @return <code>true</code> if this <code>Rectangle2D</code>
  137. * is empty; <code>false</code> otherwise.
  138. * @since 1.2
  139. */
  140. public boolean isEmpty() {
  141. return (width <= 0.0f) || (height <= 0.0f);
  142. }
  143. /**
  144. * Sets the location and size of this <code>Rectangle2D</code>
  145. * to the specified float values.
  146. * @param x, y the coordinates to which to set the
  147. * location of the upper left corner of this
  148. * <code>Rectangle2D</code>
  149. * @param w the value to use to set the width of this
  150. * <code>Rectangle2D</code>
  151. * @param h the value to use to set the height of this
  152. * <code>Rectangle2D</code>
  153. * @since 1.2
  154. */
  155. public void setRect(float x, float y, float w, float h) {
  156. this.x = x;
  157. this.y = y;
  158. this.width = w;
  159. this.height = h;
  160. }
  161. /**
  162. * Sets the location and size of this <code>Rectangle2D</code>
  163. * to the specified double values.
  164. * @param x, y the coordinates to which to set the
  165. * location of the upper left corner of this
  166. * <code>Rectangle2D</code>
  167. * @param w the value to use to set the width of this
  168. * <code>Rectangle2D</code>
  169. * @param h the value to use to set the height of this
  170. * <code>Rectangle2D</code>
  171. * @since 1.2
  172. */
  173. public void setRect(double x, double y, double w, double h) {
  174. this.x = (float) x;
  175. this.y = (float) y;
  176. this.width = (float) w;
  177. this.height = (float) h;
  178. }
  179. /**
  180. * Sets this <code>Rectangle2D</code> to be the same as the
  181. * specified <code>Rectangle2D</code>.
  182. * @param r the specified <code>Rectangle2D</code>
  183. * @since 1.2
  184. */
  185. public void setRect(Rectangle2D r) {
  186. this.x = (float) r.getX();
  187. this.y = (float) r.getY();
  188. this.width = (float) r.getWidth();
  189. this.height = (float) r.getHeight();
  190. }
  191. /**
  192. * Determines where the specified float coordinates lie with respect
  193. * to this <code>Rectangle2D</code>.
  194. * This method computes a binary OR of the appropriate mask values
  195. * indicating, for each side of this <code>Rectangle2D</code>,
  196. * whether or not the specified coordinates are on the same side
  197. * of the edge as the rest of this <code>Rectangle2D</code>.
  198. * @param x, y the specified coordinates
  199. * @return the logical OR of all appropriate out codes.
  200. * @see Rectangle2D#OUT_LEFT
  201. * @see Rectangle2D#OUT_TOP
  202. * @see Rectangle2D#OUT_RIGHT
  203. * @see Rectangle2D#OUT_BOTTOM
  204. * @since 1.2
  205. */
  206. public int outcode(double x, double y) {
  207. int out = 0;
  208. if (this.width <= 0) {
  209. out |= OUT_LEFT | OUT_RIGHT;
  210. } else if (x < this.x) {
  211. out |= OUT_LEFT;
  212. } else if (x > this.x + this.width) {
  213. out |= OUT_RIGHT;
  214. }
  215. if (this.height <= 0) {
  216. out |= OUT_TOP | OUT_BOTTOM;
  217. } else if (y < this.y) {
  218. out |= OUT_TOP;
  219. } else if (y > this.y + this.height) {
  220. out |= OUT_BOTTOM;
  221. }
  222. return out;
  223. }
  224. /**
  225. * Returns the high precision bounding box of this
  226. * <code>Rectangle2D</code>.
  227. * @return the bounding box of this <code>Rectangle2D</code>.
  228. * @since 1.2
  229. */
  230. public Rectangle2D getBounds2D() {
  231. return new Float(x, y, width, height);
  232. }
  233. /**
  234. * Returns a new <code>Rectangle2D</code> object
  235. * representing the intersection of
  236. * this <code>Rectangle2D</code> with the specified
  237. * <code>Rectangle2D</code>.
  238. * @param r the <code>Rectangle2D</code> that is
  239. * intersected with this <code>Rectangle2D</code>
  240. * @return the largest <code>Rectangle2D</code>
  241. * contained in both the specified
  242. * <code>Rectangle2D</code> and in this
  243. * <code>Rectangle2D</code>.
  244. * @since 1.2
  245. */
  246. public Rectangle2D createIntersection(Rectangle2D r) {
  247. Rectangle2D dest;
  248. if (r instanceof Float) {
  249. dest = new Rectangle2D.Float();
  250. } else {
  251. dest = new Rectangle2D.Double();
  252. }
  253. Rectangle2D.intersect(this, r, dest);
  254. return dest;
  255. }
  256. /**
  257. * Returns a new <code>Rectangle2D</code> object
  258. * representing the union of this <code>Rectangle2D</code>
  259. * with the specified <code>Rectangle2D</code>.
  260. * @param r the <code>Rectangle2D</code> to be combined with
  261. * this <code>Rectangle2D</code>
  262. * @return the smallest <code>Rectangle2D</code> containing
  263. * both the specified <code>Rectangle2D</code> and this
  264. * <code>Rectangle2D</code>.
  265. * @since 1.2
  266. */
  267. public Rectangle2D createUnion(Rectangle2D r) {
  268. Rectangle2D dest;
  269. if (r instanceof Float) {
  270. dest = new Rectangle2D.Float();
  271. } else {
  272. dest = new Rectangle2D.Double();
  273. }
  274. Rectangle2D.union(this, r, dest);
  275. return dest;
  276. }
  277. /**
  278. * Returns the <code>String</code> representation of this
  279. * <code>Rectangle2D</code>.
  280. * @return a <code>String</code> representing this
  281. * <code>Rectangle2D</code>.
  282. * @since 1.2
  283. */
  284. public String toString() {
  285. return getClass().getName()
  286. + "[x=" + x +
  287. ",y=" + y +
  288. ",w=" + width +
  289. ",h=" + height + "]";
  290. }
  291. }
  292. /**
  293. * The <code>Double</code> class defines a rectangle specified in
  294. * double coordinates.
  295. * @since 1.2
  296. */
  297. public static class Double extends Rectangle2D {
  298. /**
  299. * The x coordinate of this <code>Rectangle2D</code>.
  300. * @since 1.2
  301. */
  302. public double x;
  303. /**
  304. * The y coordinate of this <code>Rectangle2D</code>.
  305. * @since 1.2
  306. */
  307. public double y;
  308. /**
  309. * The width of this <code>Rectangle2D</code>.
  310. * @since 1.2
  311. */
  312. public double width;
  313. /**
  314. * The height of this <code>Rectangle2D</code>.
  315. * @since 1.2
  316. */
  317. public double height;
  318. /**
  319. * Constructs a new <code>Rectangle2D</code>, initialized to
  320. * location (0, 0) and size (0, 0).
  321. * @since 1.2
  322. */
  323. public Double() {
  324. }
  325. /**
  326. * Constructs and initializes a <code>Rectangle2D</code>
  327. * from the specified double coordinates.
  328. * @param x, y the coordinates of the upper left corner
  329. * of the newly constructed <code>Rectangle2D</code>
  330. * @param width the width of the
  331. * newly constructed <code>Rectangle2D</code>
  332. * @param height the height of the
  333. * newly constructed <code>Rectangle2D</code>
  334. * @since 1.2
  335. */
  336. public Double(double x, double y, double w, double h) {
  337. setRect(x, y, w, h);
  338. }
  339. /**
  340. * Returns the X coordinate of this <code>Rectangle2D</code> in
  341. * double precision.
  342. * @return the X coordinate of this <code>Rectangle2D</code>.
  343. * @since 1.2
  344. */
  345. public double getX() {
  346. return x;
  347. }
  348. /**
  349. * Returns the Y coordinate of this <code>Rectangle2D</code> in
  350. * double precision.
  351. * @return the Y coordinate of this <code>Rectangle2D</code>.
  352. * @since 1.2
  353. */
  354. public double getY() {
  355. return y;
  356. }
  357. /**
  358. * Returns the width of this <code>Rectangle2D</code> in
  359. * double precision.
  360. * @return the width of this <code>Rectangle2D</code>.
  361. * @since 1.2
  362. */
  363. public double getWidth() {
  364. return width;
  365. }
  366. /**
  367. * Returns the height of this <code>Rectangle2D</code> in
  368. * double precision.
  369. * @return the height of this <code>Rectangle2D</code>.
  370. * @since 1.2
  371. */
  372. public double getHeight() {
  373. return height;
  374. }
  375. /**
  376. * Determines whether or not this <code>Rectangle2D</code>
  377. * is empty.
  378. * @return <code>true</code> if this <code>Rectangle2D</code>
  379. * is empty; <code>false</code> otherwise.
  380. * @since 1.2
  381. */
  382. public boolean isEmpty() {
  383. return (width <= 0.0) || (height <= 0.0);
  384. }
  385. /**
  386. * Sets the location and size of this <code>Rectangle2D</code>
  387. * to the specified double values.
  388. * @param x, y the coordinates to which to set the
  389. * upper left corner of this <code>Rectangle2D</code>
  390. * @param w the value to use to set the width of this
  391. * <code>Rectangle2D</code>
  392. * @param h the value to use to set the height of this
  393. * <code>Rectangle2D</code>
  394. * @since 1.2
  395. */
  396. public void setRect(double x, double y, double w, double h) {
  397. this.x = x;
  398. this.y = y;
  399. this.width = w;
  400. this.height = h;
  401. }
  402. /**
  403. * Sets this <code>Rectangle2D</code> to be the same as the
  404. * specified <code>Rectangle2D</code>.
  405. * @param r the specified <code>Rectangle2D</code>
  406. * @since 1.2
  407. */
  408. public void setRect(Rectangle2D r) {
  409. this.x = r.getX();
  410. this.y = r.getY();
  411. this.width = r.getWidth();
  412. this.height = r.getHeight();
  413. }
  414. /**
  415. * Determines where the specified double coordinates lie with respect
  416. * to this <code>Rectangle2D</code>.
  417. * This method computes a binary OR of the appropriate mask values
  418. * indicating, for each side of this <code>Rectangle2D</code>,
  419. * whether or not the specified coordinates are on the same side
  420. * of the edge as the rest of this <code>Rectangle2D</code>.
  421. * @param x, y the specified coordinates
  422. * @return the logical OR of all appropriate out codes.
  423. * @see Rectangle2D#OUT_LEFT
  424. * @see Rectangle2D#OUT_TOP
  425. * @see Rectangle2D#OUT_RIGHT
  426. * @see Rectangle2D#OUT_BOTTOM
  427. * @since 1.2
  428. */
  429. public int outcode(double x, double y) {
  430. int out = 0;
  431. if (this.width <= 0) {
  432. out |= OUT_LEFT | OUT_RIGHT;
  433. } else if (x < this.x) {
  434. out |= OUT_LEFT;
  435. } else if (x > this.x + this.width) {
  436. out |= OUT_RIGHT;
  437. }
  438. if (this.height <= 0) {
  439. out |= OUT_TOP | OUT_BOTTOM;
  440. } else if (y < this.y) {
  441. out |= OUT_TOP;
  442. } else if (y > this.y + this.height) {
  443. out |= OUT_BOTTOM;
  444. }
  445. return out;
  446. }
  447. /**
  448. * Returns the high precision bounding box of this
  449. * <code>Rectangle2D</code>.
  450. * @return the bounding box of this <code>Rectangle2D</code>.
  451. * @since 1.2
  452. */
  453. public Rectangle2D getBounds2D() {
  454. return new Double(x, y, width, height);
  455. }
  456. /**
  457. * Returns a new <code>Rectangle2D</code> object representing
  458. * the intersection of this <code>Rectangle2D</code> with the
  459. * specified <code>Rectangle2D</code>.
  460. * @param r the <code>Rectangle2D</code> to be intersected
  461. * with this <code>Rectangle2D</code>
  462. * @return the largest <code>Rectangle2D</code> contained in
  463. * both the specified <code>Rectangle2D</code> and in this
  464. * <code>Rectangle2D</code>.
  465. * @since 1.2
  466. */
  467. public Rectangle2D createIntersection(Rectangle2D r) {
  468. Rectangle2D dest = new Rectangle2D.Double();
  469. Rectangle2D.intersect(this, r, dest);
  470. return dest;
  471. }
  472. /**
  473. * Returns a new <code>Rectangle2D</code> object representing
  474. * the union of this <code>Rectangle2D</code> with the
  475. * specified <code>Rectangle2D</code>.
  476. * @param r the <code>Rectangle2D</code> to be combined with
  477. * this <code>Rectangle2D</code>
  478. * @return the smallest <code>Rectangle2D</code> containing
  479. * both the specified <code>Rectangle2D</code> and this
  480. * <code>Rectangle2D</code>.
  481. * @since 1.2
  482. */
  483. public Rectangle2D createUnion(Rectangle2D r) {
  484. Rectangle2D dest = new Rectangle2D.Double();
  485. Rectangle2D.union(this, r, dest);
  486. return dest;
  487. }
  488. /**
  489. * Returns the <code>String</code> representation of this
  490. * <code>Rectangle2D</code>.
  491. * @return a <code>String</code> representing this
  492. * <code>Rectangle2D</code>.
  493. * @since 1.2
  494. */
  495. public String toString() {
  496. return getClass().getName()
  497. + "[x=" + x +
  498. ",y=" + y +
  499. ",w=" + width +
  500. ",h=" + height + "]";
  501. }
  502. }
  503. /**
  504. * This is an abstract class that cannot be instantiated directly.
  505. * Type-specific implementation subclasses are available for
  506. * instantiation and provide a number of formats for storing
  507. * the information necessary to satisfy the various accessor
  508. * methods below.
  509. *
  510. * @see java.awt.geom.Rectangle2D.Float
  511. * @see java.awt.geom.Rectangle2D.Double
  512. * @see java.awt.Rectangle
  513. */
  514. protected Rectangle2D() {
  515. }
  516. /**
  517. * Sets the location and size of this <code>Rectangle2D</code>
  518. * to the specified double values.
  519. * @param x, y the coordinates to which to set the
  520. * location of the upper left corner of this
  521. * <code>Rectangle2D</code>
  522. * @param w the value to use to set the width of this
  523. * <code>Rectangle2D</code>
  524. * @param h the value to use to set the height of this
  525. * <code>Rectangle2D</code>
  526. * @since 1.2
  527. */
  528. public abstract void setRect(double x, double y, double w, double h);
  529. /**
  530. * Sets this <code>Rectangle2D</code> to be the same as the specified
  531. * <code>Rectangle2D</code>.
  532. * @param r the specified <code>Rectangle2D</code>
  533. * @since 1.2
  534. */
  535. public void setRect(Rectangle2D r) {
  536. setRect(r.getX(), r.getY(), r.getWidth(), r.getHeight());
  537. }
  538. /**
  539. * Tests if the specified line segment intersects the interior of this
  540. * <code>Rectangle2D</code>.
  541. * @param x1, y1 the first endpoint of the specified
  542. * line segment
  543. * @param x2, y2 the second endpoint of the specified
  544. * line segment
  545. * @return <code>true</code> if the specified line segment intersects
  546. * the interior of this <code>Rectangle2D</code> <code>false</code>
  547. * otherwise.
  548. * @since 1.2
  549. */
  550. public boolean intersectsLine(double x1, double y1, double x2, double y2) {
  551. int out1 = outcode(x1, y1);
  552. int out2 = outcode(x2, y2);
  553. while (true) {
  554. if ((out1 & out2) != 0) {
  555. return false;
  556. }
  557. if (out1 == 0) {
  558. if (out2 == 0) {
  559. // Both are inside, line intersects
  560. return true;
  561. }
  562. double f = x1;
  563. x1 = x2;
  564. x2 = f;
  565. f = y1;
  566. y1 = y2;
  567. y2 = f;
  568. int out = out1;
  569. out1 = out2;
  570. out2 = out;
  571. }
  572. if ((out1 & (OUT_LEFT | OUT_RIGHT)) != 0) {
  573. double x = getX();
  574. if ((out1 & OUT_RIGHT) != 0) {
  575. x += getWidth();
  576. }
  577. y1 = y1 + (x - x1) * (y2 - y1) / (x2 - x1);
  578. x1 = x;
  579. } else if ((out1 & (OUT_TOP | OUT_BOTTOM)) != 0) {
  580. double y = getY();
  581. if ((out1 & OUT_BOTTOM) != 0) {
  582. y += getHeight();
  583. }
  584. x1 = x1 + (y - y1) * (x2 - x1) / (y2 - y1);
  585. y1 = y;
  586. }
  587. out1 = outcode(x1, y1);
  588. }
  589. }
  590. /**
  591. * Tests if the specified line segment intersects the interior of this
  592. * <code>Rectangle2D</code>.
  593. * @param l the specified {@link Line2D} to test for intersection
  594. * with the interior of this <code>Rectangle2D</code>
  595. * @return <code>true</code> if the specified <code>Line2D</code>
  596. * intersects the interior of this <code>Rectangle2D</code>
  597. * <code>false</code> otherwise.
  598. * @since 1.2
  599. */
  600. public boolean intersectsLine(Line2D l) {
  601. return intersectsLine(l.getX1(), l.getY1(), l.getX2(), l.getY2());
  602. }
  603. /**
  604. * Determines where the specified coordinates lie with respect
  605. * to this <code>Rectangle2D</code>.
  606. * This method computes a binary OR of the appropriate mask values
  607. * indicating, for each side of this <code>Rectangle2D</code>,
  608. * whether or not the specified coordinates are on the same side
  609. * of the edge as the rest of this <code>Rectangle2D</code>.
  610. * @param x, y the specified coordinates
  611. * @return the logical OR of all appropriate out codes.
  612. * @see #OUT_LEFT
  613. * @see #OUT_TOP
  614. * @see #OUT_RIGHT
  615. * @see #OUT_BOTTOM
  616. * @since 1.2
  617. */
  618. public abstract int outcode(double x, double y);
  619. /**
  620. * Determines where the specified {@link Point2D} lies with
  621. * respect to this <code>Rectangle2D</code>.
  622. * This method computes a binary OR of the appropriate mask values
  623. * indicating, for each side of this <code>Rectangle2D</code>,
  624. * whether or not the specified <code>Point2D</code> is on the same
  625. * side of the edge as the rest of this <code>Rectangle2D</code>.
  626. * @param p the specified <code>Point2D</code>
  627. * @return the logical OR of all appropriate out codes.
  628. * @see #OUT_LEFT
  629. * @see #OUT_TOP
  630. * @see #OUT_RIGHT
  631. * @see #OUT_BOTTOM
  632. * @since 1.2
  633. */
  634. public int outcode(Point2D p) {
  635. return outcode(p.getX(), p.getY());
  636. }
  637. /**
  638. * Sets the location and size of the outer bounds of this
  639. * <code>Rectangle2D</code> to the specified rectangular values.
  640. * @param x, y the coordinates to which to set the
  641. * location of the upper left corner of the outer bounds of
  642. * this <code>Rectangle2D</code>
  643. * @param w the value to use to set the width of the outer
  644. * bounds of this <code>Rectangle2D</code>
  645. * @param h the value to use to set the height of the outer
  646. * bounds of this <code>Rectangle2D</code>
  647. * @since 1.2
  648. */
  649. public void setFrame(double x, double y, double w, double h) {
  650. setRect(x, y, w, h);
  651. }
  652. /**
  653. * Returns the high precision bounding box of this
  654. * <code>Rectangle2D</code>.
  655. * @return the bounding box of this <code>Rectangle2D</code>.
  656. * @since 1.2
  657. */
  658. public Rectangle2D getBounds2D() {
  659. return (Rectangle2D) clone();
  660. }
  661. /**
  662. * Tests if a specified coordinate is inside the boundary of this
  663. * <code>Rectangle2D</code>.
  664. * @param x, y the coordinates to test
  665. * @return <code>true</code> if the specified coordinates are
  666. * inside the boundary of this <code>Rectangle2D</code>
  667. * <code>false</code> otherwise.
  668. * @since 1.2
  669. */
  670. public boolean contains(double x, double y) {
  671. double x0 = getX();
  672. double y0 = getY();
  673. return (x >= x0 &&
  674. y >= y0 &&
  675. x < x0 + getWidth() &&
  676. y < y0 + getHeight());
  677. }
  678. /**
  679. * Tests if the interior of this <code>Rectangle2D</code>
  680. * intersects the interior of a specified set of rectangular
  681. * coordinates.
  682. * @param x, y the coordinates of the upper left corner
  683. * of the specified set of rectangular coordinates
  684. * @param w the width of the specified set of rectangular
  685. * coordinates
  686. * @param h the height of the specified set of rectangular
  687. * coordinates
  688. * @return <code>true</code> if this <code>Rectangle2D</code>
  689. * intersects the interior of a specified set of rectangular
  690. * coordinates; <code>false</code> otherwise.
  691. * @since 1.2
  692. */
  693. public boolean intersects(double x, double y, double w, double h) {
  694. if (isEmpty() || w <= 0 || h <= 0) {
  695. return false;
  696. }
  697. double x0 = getX();
  698. double y0 = getY();
  699. return (x + w > x0 &&
  700. y + h > y0 &&
  701. x < x0 + getWidth() &&
  702. y < y0 + getHeight());
  703. }
  704. /**
  705. * Tests if the interior of this <code>Rectangle2D</code> entirely
  706. * contains the specified set of rectangular coordinates.
  707. * @param x, y the coordinates of the upper left corner
  708. * of the specified set of rectangular coordinates
  709. * @param w the width of the specified set of rectangular
  710. * coordinates
  711. * @param h the height of the specified set of rectangular
  712. * coordinates
  713. * @return <code>true</code> if this <code>Rectangle2D</code>
  714. * entirely contains specified set of rectangular
  715. * coordinates; <code>false</code> otherwise.
  716. * @since 1.2
  717. */
  718. public boolean contains(double x, double y, double w, double h) {
  719. if (isEmpty() || w <= 0 || h <= 0) {
  720. return false;
  721. }
  722. double x0 = getX();
  723. double y0 = getY();
  724. return (x >= x0 &&
  725. y >= y0 &&
  726. (x + w) <= x0 + getWidth() &&
  727. (y + h) <= y0 + getHeight());
  728. }
  729. /**
  730. * Returns a new <code>Rectangle2D</code> object representing the
  731. * intersection of this <code>Rectangle2D</code> with the specified
  732. * <code>Rectangle2D</code>.
  733. * @param r the <code>Rectangle2D</code> to be intersected with
  734. * this <code>Rectangle2D</code>
  735. * @return the largest <code>Rectangle2D</code> contained in both
  736. * the specified <code>Rectangle2D</code> and in this
  737. * <code>Rectangle2D</code>.
  738. * @since 1.2
  739. */
  740. public abstract Rectangle2D createIntersection(Rectangle2D r);
  741. /**
  742. * Intersects the pair of specified source <code>Rectangle2D</code>
  743. * objects and puts the result into the specified destination
  744. * <code>Rectangle2D</code> object.
  745. * @param src1 the first of a pair of <code>Rectangle2D</code>
  746. * objects to be intersected with each other
  747. * @param src2 the second of a pair of <code>Rectangle2D</code>
  748. * objects to be intersected with each other
  749. * @param dest the <code>Rectangle2D</code> that holds the
  750. * results of the intersection of <code>src1</code> and
  751. * <code>src2</code>
  752. * @since 1.2
  753. */
  754. public static void intersect(Rectangle2D src1,
  755. Rectangle2D src2,
  756. Rectangle2D dest) {
  757. double x1 = Math.max(src1.getMinX(), src2.getMinX());
  758. double y1 = Math.max(src1.getMinY(), src2.getMinY());
  759. double x2 = Math.min(src1.getMaxX(), src2.getMaxX());
  760. double y2 = Math.min(src1.getMaxY(), src2.getMaxY());
  761. dest.setFrameFromDiagonal(x1, y1, x2, y2);
  762. }
  763. /**
  764. * Returns a new <code>Rectangle2D</code> object representing the
  765. * union of this <code>Rectangle2D</code> with the specified
  766. * <code>Rectangle2D</code>.
  767. * @param r the <code>Rectangle2D</code> to be combined with
  768. * this <code>Rectangle2D</code>
  769. * @return the smallest <code>Rectangle2D</code> containing both
  770. * the specified <code>Rectangle2D</code> and this
  771. * <code>Rectangle2D</code>.
  772. * @since 1.2
  773. */
  774. public abstract Rectangle2D createUnion(Rectangle2D r);
  775. /**
  776. * Unions the pair of source <code>Rectangle2D</code> objects
  777. * and puts the result into the specified destination
  778. * <code>Rectangle2D</code> object.
  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. }