1. /*
  2. * @(#)Line2D.java 1.25 01/02/09
  3. *
  4. * Copyright 1997-2001 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. import java.awt.Shape;
  12. import java.awt.Rectangle;
  13. /**
  14. * This <code>Line2D</code> class represents a line segment in (x, y)
  15. * coordinate space. This class, like all of the Java 2D API, uses a
  16. * default coordinate system called <i>user space</i> in which the y-axis
  17. * values increase downward and x-axis values increase to the right. For
  18. * more information on the user space coordinate system, see the
  19. * <a href="http://java.sun.com/j2se/1.3/docs/guide/2d/spec/j2d-intro.fm2.html#61857">
  20. * Coordinate Systems</a> section of the Java 2D Programmer's Guide.
  21. * <p>
  22. * This class is only the abstract superclass for all objects that
  23. * store a 2D line segment.
  24. * The actual storage representation of the coordinates is left to
  25. * the subclass.
  26. *
  27. * @version 1.25, 02/09/01
  28. * @author Jim Graham
  29. */
  30. public abstract class Line2D implements Shape, Cloneable {
  31. /**
  32. * A line segment specified with float coordinates.
  33. */
  34. public static class Float extends Line2D {
  35. /**
  36. * The X coordinate of the start point of the line segment.
  37. */
  38. public float x1;
  39. /**
  40. * The Y coordinate of the start point of the line segment.
  41. */
  42. public float y1;
  43. /**
  44. * The X coordinate of the end point of the line segment.
  45. */
  46. public float x2;
  47. /**
  48. * The Y coordinate of the end point of the line segment.
  49. */
  50. public float y2;
  51. /**
  52. * Constructs and initializes a Line with coordinates (0, 0) -> (0, 0).
  53. */
  54. public Float() {
  55. }
  56. /**
  57. * Constructs and initializes a Line from the specified coordinates.
  58. * @param X1, Y1 the first specified coordinates
  59. * @param X2, Y2 the second specified coordinates
  60. */
  61. public Float(float X1, float Y1, float X2, float Y2) {
  62. setLine(X1, Y1, X2, Y2);
  63. }
  64. /**
  65. * Constructs and initializes a <code>Line2D</code> from the
  66. * specified {@link Point2D} objects.
  67. * @param p1 the first specified <code>Point2D</code>
  68. * @param p2 the second specified <code>Point2D</code>
  69. */
  70. public Float(Point2D p1, Point2D p2) {
  71. setLine(p1, p2);
  72. }
  73. /**
  74. * Returns the X coordinate of the start point in double precision.
  75. * @return the x coordinate of this <code>Line2D</code> object's
  76. * starting point in double precision.
  77. */
  78. public double getX1() {
  79. return (double) x1;
  80. }
  81. /**
  82. * Returns the Y coordinate of the start point in double precision.
  83. * @return the x coordinate of this <code>Line2D</code> object's
  84. * starting point in double precision.
  85. */
  86. public double getY1() {
  87. return (double) y1;
  88. }
  89. /**
  90. * Returns the start point.
  91. * @return the starting <code>Point2D</code> object of this
  92. * <code>Line2D</code>.
  93. */
  94. public Point2D getP1() {
  95. return new Point2D.Float(x1, y1);
  96. }
  97. /**
  98. * Returns the X coordinate of the end point in double precision.
  99. * @return the x coordinate of this <code>Line2D</code> object's
  100. * ending point in double precision.
  101. */
  102. public double getX2() {
  103. return (double) x2;
  104. }
  105. /**
  106. * Returns the Y coordinate of the end point in double precision.
  107. * @return the Y coordinate of this <code>Line2D</code> object's
  108. * ending point in double precision.
  109. */
  110. public double getY2() {
  111. return (double) y2;
  112. }
  113. /**
  114. * Returns the end point.
  115. * @return the ending <code>Point2D</code> object of this
  116. * <code>Line2D</code>.
  117. */
  118. public Point2D getP2() {
  119. return new Point2D.Float(x2, y2);
  120. }
  121. /**
  122. * Sets the location of the endpoints of this <code>Line2D</code>
  123. * to the specified double coordinates.
  124. * @param X1, Y1 the first specified coordinate
  125. * @param X2, Y2 the second specified coordinate
  126. */
  127. public void setLine(double X1, double Y1, double X2, double Y2) {
  128. this.x1 = (float) X1;
  129. this.y1 = (float) Y1;
  130. this.x2 = (float) X2;
  131. this.y2 = (float) Y2;
  132. }
  133. /**
  134. * Sets the location of the endpoints of this <code>Line2D</code>
  135. * to the specified float coordinates.
  136. * @param X1, Y1 the first specified coordinate
  137. * @param X2, Y2 the second specified coordinate
  138. */
  139. public void setLine(float X1, float Y1, float X2, float Y2) {
  140. this.x1 = X1;
  141. this.y1 = Y1;
  142. this.x2 = X2;
  143. this.y2 = Y2;
  144. }
  145. /**
  146. * Returns the high-precision bounding box of this
  147. * <code>Line2D</code>.
  148. * @return a {@link Rectangle2D} that is the high-precision
  149. * bounding box of this <code>Line2D</code>.
  150. */
  151. public Rectangle2D getBounds2D() {
  152. float x, y, w, h;
  153. if (x1 < x2) {
  154. x = x1;
  155. w = x2 - x1;
  156. } else {
  157. x = x2;
  158. w = x1 - x2;
  159. }
  160. if (y1 < y2) {
  161. y = y1;
  162. h = y2 - y1;
  163. } else {
  164. y = y2;
  165. h = y1 - y2;
  166. }
  167. return new Rectangle2D.Float(x, y, w, h);
  168. }
  169. }
  170. /**
  171. * A line segment specified with double coordinates.
  172. */
  173. public static class Double extends Line2D {
  174. /**
  175. * The X coordinate of the start point of the line segment.
  176. */
  177. public double x1;
  178. /**
  179. * The Y coordinate of the start point of the line segment.
  180. */
  181. public double y1;
  182. /**
  183. * The X coordinate of the end point of the line segment.
  184. */
  185. public double x2;
  186. /**
  187. * The Y coordinate of the end point of the line segment.
  188. */
  189. public double y2;
  190. /**
  191. * Constructs and initializes a Line with coordinates (0, 0) -> (0, 0).
  192. */
  193. public Double() {
  194. }
  195. /**
  196. * Constructs and initializes a <code>Line2D</code> from the
  197. * specified coordinates.
  198. * @param X1, Y1 the first specified coordinate
  199. * @param X2, Y2 the second specified coordinate
  200. */
  201. public Double(double X1, double Y1, double X2, double Y2) {
  202. setLine(X1, Y1, X2, Y2);
  203. }
  204. /**
  205. * Constructs and initializes a <code>Line2D</code> from the
  206. * specified <code>Point2D</code> objects.
  207. * @param p1, p2 the specified <code>Point2D</code> objects
  208. */
  209. public Double(Point2D p1, Point2D p2) {
  210. setLine(p1, p2);
  211. }
  212. /**
  213. * Returns the X coordinate of the start point in double precision.
  214. * @return the X coordinate of this <code>Line2D</code> object's
  215. * starting point.
  216. */
  217. public double getX1() {
  218. return x1;
  219. }
  220. /**
  221. * Returns the Y coordinate of the start point in double precision.
  222. * @return the X coordinate of this <code>Line2D</code> object's
  223. * starting point.
  224. */
  225. public double getY1() {
  226. return y1;
  227. }
  228. /**
  229. * Returns the starting <code>Point2D</code> of this
  230. * <code>Line2D</code>.
  231. * @return the starting <code>Point2D</code> of this
  232. * <code>Line2D</code>
  233. */
  234. public Point2D getP1() {
  235. return new Point2D.Double(x1, y1);
  236. }
  237. /**
  238. * Returns the X coordinate of the end point in double precision.
  239. * @return the X coordinate of this <code>Line2D</code> object's
  240. * ending point.
  241. */
  242. public double getX2() {
  243. return x2;
  244. }
  245. /**
  246. * Returns the Y coordinate of the end point in double precision.
  247. * @return the Y coordinate of this <code>Line2D</code> object's
  248. * starting point.
  249. */
  250. public double getY2() {
  251. return y2;
  252. }
  253. /**
  254. * Returns the end <code>Point2D</code> of this
  255. * <code>Line2D</code>.
  256. * @return the ending <code>Point2D</code> of this
  257. * <code>Line2D</code>.
  258. */
  259. public Point2D getP2() {
  260. return new Point2D.Double(x2, y2);
  261. }
  262. /**
  263. * Sets the location of the endpoints of this <code>Line2D</code>
  264. * to the specified double coordinates.
  265. * @param X1, Y1 the first specified coordinate
  266. * @param X2, Y2 the second specified coordinate
  267. */
  268. public void setLine(double X1, double Y1, double X2, double Y2) {
  269. this.x1 = X1;
  270. this.y1 = Y1;
  271. this.x2 = X2;
  272. this.y2 = Y2;
  273. }
  274. /**
  275. * Returns the high-precision bounding box of this
  276. * <code>Line2D</code>.
  277. * @return a <code>Rectangle2D</code> that is the high-precision
  278. * bounding box of this <code>Line2D</code>.
  279. */
  280. public Rectangle2D getBounds2D() {
  281. double x, y, w, h;
  282. if (x1 < x2) {
  283. x = x1;
  284. w = x2 - x1;
  285. } else {
  286. x = x2;
  287. w = x1 - x2;
  288. }
  289. if (y1 < y2) {
  290. y = y1;
  291. h = y2 - y1;
  292. } else {
  293. y = y2;
  294. h = y1 - y2;
  295. }
  296. return new Rectangle2D.Double(x, y, w, h);
  297. }
  298. }
  299. /**
  300. * This is an abstract class that cannot be instantiated directly.
  301. * Type-specific implementation subclasses are available for
  302. * instantiation and provide a number of formats for storing
  303. * the information necessary to satisfy the various accessory
  304. * methods below.
  305. *
  306. * @see java.awt.geom.Line2D.Float
  307. * @see java.awt.geom.Line2D.Double
  308. */
  309. protected Line2D() {
  310. }
  311. /**
  312. * Returns the X coordinate of the start point in double precision.
  313. * @return the X coordinate of this <code>Line2D</code> object's
  314. * starting point.
  315. */
  316. public abstract double getX1();
  317. /**
  318. * Returns the Y coordinate of the start point in double precision.
  319. * @return the Y coordinate of this <code>Line2D</code> object's
  320. * starting point.
  321. */
  322. public abstract double getY1();
  323. /**
  324. * Returns the starting <code>Point2D</code> of this
  325. * <code>Line2D</code>.
  326. * @return the starting <code>Point2D</code> of this
  327. * <code>Line2D</code>.
  328. */
  329. public abstract Point2D getP1();
  330. /**
  331. * Returns the X coordinate of the end point in double precision.
  332. * @return the X coordinate of this <code>Line2D</code> object's
  333. * starting point.
  334. */
  335. public abstract double getX2();
  336. /**
  337. * Returns the Y coordinate of the end point in double precision.
  338. * @return the Y coordinate of this <code>Line2D</code> object's
  339. * starting point.
  340. */
  341. public abstract double getY2();
  342. /**
  343. * Returns the end <code>Point2D</code> of this <code>Line2D</code>.
  344. * @return a <code>Point2D</code> that is the endpoint of this
  345. * <code>Line2D</code>.
  346. */
  347. public abstract Point2D getP2();
  348. /**
  349. * Sets the location of the endpoints of this <code>Line2D</code> to
  350. * the specified double coordinates.
  351. * @param X1, Y1 the first specified coordinate
  352. * @param X2, Y2 the second specified coordinate
  353. */
  354. public abstract void setLine(double X1, double Y1, double X2, double Y2);
  355. /**
  356. * Sets the location of the endpoints of this <code>Line2D</code> to
  357. * the specified <code>Point2D</code> coordinates.
  358. * @param p1, p2 the specified <code>Point2D</code> objects
  359. */
  360. public void setLine(Point2D p1, Point2D p2) {
  361. setLine(p1.getX(), p1.getY(), p2.getX(), p2.getY());
  362. }
  363. /**
  364. * Sets the location of the endpoints of this <code>Line2D</code> to
  365. * the same as those endpoints of the specified <code>Line2D</code>.
  366. * @param l the specified <code>Line2D</code>
  367. */
  368. public void setLine(Line2D l) {
  369. setLine(l.getX1(), l.getY1(), l.getX2(), l.getY2());
  370. }
  371. /**
  372. * Returns an indicator of where the specified point
  373. * (PX, PY) lies with respect to the line segment from
  374. * (X1, Y1) to (X2, Y2).
  375. * The return value can be either 1, -1, or 0 and indicates
  376. * in which direction the specified line must pivot around its
  377. * first endpoint, (X1, Y1), in order to point at the
  378. * specified point (PX, PY).
  379. * <p>A return value of 1 indicates that the line segment must
  380. * turn in the direction that takes the positive X axis towards
  381. * the negative Y axis. In the default coordinate system used by
  382. * Java 2D, this direction is counterclockwise.
  383. * <p>A return value of -1 indicates that the line segment must
  384. * turn in the direction that takes the positive X axis towards
  385. * the positive Y axis. In the default coordinate system, this
  386. * direction is clockwise.
  387. * <p>A return value of 0 indicates that the point lies
  388. * exactly on the line segment. Note that an indicator value
  389. * of 0 is rare and not useful for determining colinearity
  390. * because of floating point rounding issues.
  391. * <p>If the point is colinear with the line segment, but
  392. * not between the endpoints, then the value will be -1 if the point
  393. * lies "beyond (X1, Y1)" or 1 if the point lies
  394. * "beyond (X2, Y2)".
  395. * @param X1, Y1 the coordinates of the beginning of the
  396. * specified line segment
  397. * @param X2, Y2 the coordinates of the end of the specified
  398. * line segment
  399. * @param PX, PY the coordinates of the specified point to be
  400. * compared with the specified line segment
  401. * @return an integer that indicates the position of the third specified
  402. * coordinates with respect to the line segment formed
  403. * by the first two specified coordinates.
  404. */
  405. public static int relativeCCW(double X1, double Y1,
  406. double X2, double Y2,
  407. double PX, double PY) {
  408. X2 -= X1;
  409. Y2 -= Y1;
  410. PX -= X1;
  411. PY -= Y1;
  412. double ccw = PX * Y2 - PY * X2;
  413. if (ccw == 0.0) {
  414. // The point is colinear, classify based on which side of
  415. // the segment the point falls on. We can calculate a
  416. // relative value using the projection of PX,PY onto the
  417. // segment - a negative value indicates the point projects
  418. // outside of the segment in the direction of the particular
  419. // endpoint used as the origin for the projection.
  420. ccw = PX * X2 + PY * Y2;
  421. if (ccw > 0.0) {
  422. // Reverse the projection to be relative to the original X2,Y2
  423. // X2 and Y2 are simply negated.
  424. // PX and PY need to have (X2 - X1) or (Y2 - Y1) subtracted
  425. // from them (based on the original values)
  426. // Since we really want to get a positive answer when the
  427. // point is "beyond (X2,Y2)", then we want to calculate
  428. // the inverse anyway - thus we leave X2 & Y2 negated.
  429. PX -= X2;
  430. PY -= Y2;
  431. ccw = PX * X2 + PY * Y2;
  432. if (ccw < 0.0) {
  433. ccw = 0.0;
  434. }
  435. }
  436. }
  437. return (ccw < 0.0) ? -1 : ((ccw > 0.0) ? 1 : 0);
  438. }
  439. /**
  440. * Returns an indicator of where the specified point
  441. * (PX, PY) lies with respect to this line segment.
  442. * See the method comments of
  443. * {@link #relativeCCW(double, double, double, double, double, double)}
  444. * to interpret the return value.
  445. * @param PX, PY the coordinates of the specified point
  446. * to be compared with the current line segment
  447. * @return an integer that indicates the position of the specified
  448. * coordinates with respect to the current line segment.
  449. * @see #relativeCCW(double, double, double, double, double, double)
  450. */
  451. public int relativeCCW(double PX, double PY) {
  452. return relativeCCW(getX1(), getY1(), getX2(), getY2(), PX, PY);
  453. }
  454. /**
  455. * Returns an indicator of where the specified <code>Point2D</code>
  456. * lies with respect to this line segment.
  457. * See the method comments of
  458. * {@link #relativeCCW(double, double, double, double, double, double)}
  459. * to interpret the return value.
  460. * @param p the specified <code>Point2D</code> to be compared
  461. * with the current line segment
  462. * @return an integer that indicates the position of the
  463. * <code>Point2D</code> with respect to the current
  464. * line segment.
  465. * @see #relativeCCW(double, double, double, double, double, double)
  466. */
  467. public int relativeCCW(Point2D p) {
  468. return relativeCCW(getX1(), getY1(), getX2(), getY2(),
  469. p.getX(), p.getY());
  470. }
  471. /**
  472. * Tests if the line segment from (X1, Y1) to
  473. * (X2, Y2) intersects the line segment from (X3, Y3)
  474. * to (X4, Y4).
  475. * @param X1, Y1 the coordinates of the beginning of the first
  476. * specified line segment
  477. * @param X2, Y2 the coordinates of the end of the first
  478. * specified line segment
  479. * @param X3, Y3 the coordinates of the beginning of the second
  480. * specified line segment
  481. * @param X4, Y4 the coordinates of the end of the second
  482. * specified line segment
  483. * @return <code>true</code> if the first specified line segment
  484. * and the second specified line segment intersect
  485. * each other; <code>false</code> otherwise.
  486. */
  487. public static boolean linesIntersect(double X1, double Y1,
  488. double X2, double Y2,
  489. double X3, double Y3,
  490. double X4, double Y4) {
  491. return ((relativeCCW(X1, Y1, X2, Y2, X3, Y3) *
  492. relativeCCW(X1, Y1, X2, Y2, X4, Y4) <= 0)
  493. && (relativeCCW(X3, Y3, X4, Y4, X1, Y1) *
  494. relativeCCW(X3, Y3, X4, Y4, X2, Y2) <= 0));
  495. }
  496. /**
  497. * Tests if the line segment from (X1, Y1) to
  498. * (X2, Y2) intersects this line segment.
  499. * @param X1, Y1 the coordinates of the beginning of the
  500. * specified line segment
  501. * @param X2, Y2 the coordinates of the end of the specified
  502. * line segment
  503. * @return <true> if this line segment and the specified line segment
  504. * intersect each other; <code>false</code> otherwise.
  505. */
  506. public boolean intersectsLine(double X1, double Y1, double X2, double Y2) {
  507. return linesIntersect(X1, Y1, X2, Y2,
  508. getX1(), getY1(), getX2(), getY2());
  509. }
  510. /**
  511. * Tests if the specified line segment intersects this line segment.
  512. * @param l the specified <code>Line2D</code>
  513. * @return <code>true</code> if this line segment and the specified line
  514. * segment intersect each other;
  515. * <code>false</code> otherwise.
  516. */
  517. public boolean intersectsLine(Line2D l) {
  518. return linesIntersect(l.getX1(), l.getY1(), l.getX2(), l.getY2(),
  519. getX1(), getY1(), getX2(), getY2());
  520. }
  521. /**
  522. * Returns the square of the distance from a point to a line segment.
  523. * The distance measured is the distance between the specified
  524. * point and the closest point between the specified endpoints.
  525. * If the specified point intersects the line segment in between the
  526. * endpoints, this method returns 0.0.
  527. * @param X1, Y1 the coordinates of the beginning of the
  528. * specified line segment
  529. * @param X2, Y2 the coordinates of the end of the specified
  530. * line segment
  531. * @param PX, PY the coordinates of the specified point being
  532. * measured against the specified line segment
  533. * @return a double value that is the square of the distance from the
  534. * specified point to the specified line segment.
  535. * @see #ptLineDistSq(double, double, double, double, double, double)
  536. */
  537. public static double ptSegDistSq(double X1, double Y1,
  538. double X2, double Y2,
  539. double PX, double PY) {
  540. // Adjust vectors relative to X1,Y1
  541. // X2,Y2 becomes relative vector from X1,Y1 to end of segment
  542. X2 -= X1;
  543. Y2 -= Y1;
  544. // PX,PY becomes relative vector from X1,Y1 to test point
  545. PX -= X1;
  546. PY -= Y1;
  547. double dotprod = PX * X2 + PY * Y2;
  548. double projlenSq;
  549. if (dotprod <= 0.0) {
  550. // PX,PY is on the side of X1,Y1 away from X2,Y2
  551. // distance to segment is length of PX,PY vector
  552. // "length of its (clipped) projection" is now 0.0
  553. projlenSq = 0.0;
  554. } else {
  555. // switch to backwards vectors relative to X2,Y2
  556. // X2,Y2 are already the negative of X1,Y1=>X2,Y2
  557. // to get PX,PY to be the negative of PX,PY=>X2,Y2
  558. // the dot product of two negated vectors is the same
  559. // as the dot product of the two normal vectors
  560. PX = X2 - PX;
  561. PY = Y2 - PY;
  562. dotprod = PX * X2 + PY * Y2;
  563. if (dotprod <= 0.0) {
  564. // PX,PY is on the side of X2,Y2 away from X1,Y1
  565. // distance to segment is length of (backwards) PX,PY vector
  566. // "length of its (clipped) projection" is now 0.0
  567. projlenSq = 0.0;
  568. } else {
  569. // PX,PY is between X1,Y1 and X2,Y2
  570. // dotprod is the length of the PX,PY vector
  571. // projected on the X2,Y2=>X1,Y1 vector times the
  572. // length of the X2,Y2=>X1,Y1 vector
  573. projlenSq = dotprod * dotprod / (X2 * X2 + Y2 * Y2);
  574. }
  575. }
  576. // Distance to line is now the length of the relative point
  577. // vector minus the length of its projection onto the line
  578. // (which is zero if the projection falls outside the range
  579. // of the line segment).
  580. return PX * PX + PY * PY - projlenSq;
  581. }
  582. /**
  583. * Returns the distance from a point to a line segment.
  584. * The distance measured is the distance between the specified
  585. * point and the closest point between the specified endpoints.
  586. * If the specified point intersects the line segment in between the
  587. * endpoints, this method returns 0.0.
  588. * @param X1, Y1 the coordinates of the beginning of the
  589. * specified line segment
  590. * @param X2, Y2 the coordinates of the end of the specified line
  591. * segment
  592. * @param PX, PY the coordinates of the specified point being
  593. * measured against the specified line segment
  594. * @return a double value that is the distance from the specified point
  595. * to the specified line segment.
  596. * @see #ptLineDist(double, double, double, double, double, double)
  597. */
  598. public static double ptSegDist(double X1, double Y1,
  599. double X2, double Y2,
  600. double PX, double PY) {
  601. return Math.sqrt(ptSegDistSq(X1, Y1, X2, Y2, PX, PY));
  602. }
  603. /**
  604. * Returns the square of the distance from a point to this line segment.
  605. * The distance measured is the distance between the specified
  606. * point and the closest point between the current line's endpoints.
  607. * If the specified point intersects the line segment in between the
  608. * endpoints, this method returns 0.0.
  609. * @param PX, PY the coordinates of the specified point being
  610. * measured against this line segment
  611. * @return a double value that is the square of the distance from the
  612. * specified point to the current line segment.
  613. * @see #ptLineDistSq(double, double)
  614. */
  615. public double ptSegDistSq(double PX, double PY) {
  616. return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), PX, PY);
  617. }
  618. /**
  619. * Returns the square of the distance from a <code>Point2D</code> to
  620. * this line segment.
  621. * The distance measured is the distance between the specified
  622. * point and the closest point between the current line's endpoints.
  623. * If the specified point intersects the line segment in between the
  624. * endpoints, this method returns 0.0.
  625. * @param pt the specified <code>Point2D</code> being measured against
  626. * this line segment.
  627. * @return a double value that is the square of the distance from the
  628. * specified <code>Point2D</code> to the current
  629. * line segment.
  630. * @see #ptLineDistSq(Point2D)
  631. */
  632. public double ptSegDistSq(Point2D pt) {
  633. return ptSegDistSq(getX1(), getY1(), getX2(), getY2(),
  634. pt.getX(), pt.getY());
  635. }
  636. /**
  637. * Returns the distance from a point to this line segment.
  638. * The distance measured is the distance between the specified
  639. * point and the closest point between the current line's endpoints.
  640. * If the specified point intersects the line segment in between the
  641. * endpoints, this method returns 0.0.
  642. * @param PX, PY the coordinates of the specified point
  643. * being measured against this line segment
  644. * @return a double value that is the distance from the specified
  645. * point to the current line segment.
  646. * @see #ptLineDist(double, double)
  647. */
  648. public double ptSegDist(double PX, double PY) {
  649. return ptSegDist(getX1(), getY1(), getX2(), getY2(), PX, PY);
  650. }
  651. /**
  652. * Returns the distance from a <code>Point2D</code> to this line
  653. * segment.
  654. * The distance measured is the distance between the specified
  655. * point and the closest point between the current line's endpoints.
  656. * If the specified point intersects the line segment in between the
  657. * endpoints, this method returns 0.0.
  658. * @param pt the specified <code>Point2D</code> being measured
  659. * against this line segment
  660. * @return a double value that is the distance from the specified
  661. * <code>Point2D</code> to the current line
  662. * segment.
  663. * @see #ptLineDist(Point2D)
  664. */
  665. public double ptSegDist(Point2D pt) {
  666. return ptSegDist(getX1(), getY1(), getX2(), getY2(),
  667. pt.getX(), pt.getY());
  668. }
  669. /**
  670. * Returns the square of the distance from a point to a line.
  671. * The distance measured is the distance between the specified
  672. * point and the closest point on the infinitely-extended line
  673. * defined by the specified coordinates. If the specified point
  674. * intersects the line, this method returns 0.0.
  675. * @param X1, Y1 the coordinates of one point on the
  676. * specified line
  677. * @param X2, Y2 the coordinates of another point on
  678. * the specified line
  679. * @param PX, PY the coordinates of the specified point being
  680. * measured against the specified line
  681. * @return a double value that is the square of the distance from the
  682. * specified point to the specified line.
  683. * @see #ptSegDistSq(double, double, double, double, double, double)
  684. */
  685. public static double ptLineDistSq(double X1, double Y1,
  686. double X2, double Y2,
  687. double PX, double PY) {
  688. // Adjust vectors relative to X1,Y1
  689. // X2,Y2 becomes relative vector from X1,Y1 to end of segment
  690. X2 -= X1;
  691. Y2 -= Y1;
  692. // PX,PY becomes relative vector from X1,Y1 to test point
  693. PX -= X1;
  694. PY -= Y1;
  695. double dotprod = PX * X2 + PY * Y2;
  696. // dotprod is the length of the PX,PY vector
  697. // projected on the X1,Y1=>X2,Y2 vector times the
  698. // length of the X1,Y1=>X2,Y2 vector
  699. double projlenSq = dotprod * dotprod / (X2 * X2 + Y2 * Y2);
  700. // Distance to line is now the length of the relative point
  701. // vector minus the length of its projection onto the line
  702. return PX * PX + PY * PY - projlenSq;
  703. }
  704. /**
  705. * Returns the distance from a point to a line.
  706. * The distance measured is the distance between the specified
  707. * point and the closest point on the infinitely-extended line
  708. * defined by the specified coordinates. If the specified point
  709. * intersects the line, this method returns 0.0.
  710. * @param X1, Y1 the coordinates of one point on the
  711. * specified line
  712. * @param X2, Y2 the coordinates of another point on the
  713. * specified line
  714. * @param PX, PY the coordinates of the specified point being
  715. * measured against the specified line
  716. * @return a double value that is the distance from the specified
  717. * point to the specified line.
  718. * @see #ptSegDist(double, double, double, double, double, double)
  719. */
  720. public static double ptLineDist(double X1, double Y1,
  721. double X2, double Y2,
  722. double PX, double PY) {
  723. return Math.sqrt(ptLineDistSq(X1, Y1, X2, Y2, PX, PY));
  724. }
  725. /**
  726. * Returns the square of the distance from a point to this line.
  727. * The distance measured is the distance between the specified
  728. * point and the closest point on the infinitely-extended line
  729. * defined by this <code>Line2D</code>. If the specified point
  730. * intersects the line, this method returns 0.0.
  731. * @param PX, PY the coordinates of the specified point being
  732. * measured against this line
  733. * @return a double value that is the square of the distance from a
  734. * specified point to the current line.
  735. * @see #ptSegDistSq(double, double)
  736. */
  737. public double ptLineDistSq(double PX, double PY) {
  738. return ptLineDistSq(getX1(), getY1(), getX2(), getY2(), PX, PY);
  739. }
  740. /**
  741. * Returns the square of the distance from a specified
  742. * <code>Point2D</code> to this line.
  743. * The distance measured is the distance between the specified
  744. * point and the closest point on the infinitely-extended line
  745. * defined by this <code>Line2D</code>. If the specified point
  746. * intersects the line, this method returns 0.0.
  747. * @param pt the specified <code>Point2D</code> being measured
  748. * against this line
  749. * @return a double value that is the square of the distance from a
  750. * specified <code>Point2D</code> to the current
  751. * line.
  752. * @see #ptSegDistSq(Point2D)
  753. */
  754. public double ptLineDistSq(Point2D pt) {
  755. return ptLineDistSq(getX1(), getY1(), getX2(), getY2(),
  756. pt.getX(), pt.getY());
  757. }
  758. /**
  759. * Returns the distance from a point to this line.
  760. * The distance measured is the distance between the specified
  761. * point and the closest point on the infinitely-extended line
  762. * defined by this <code>Line2D</code>. If the specified point
  763. * intersects the line, this method returns 0.0.
  764. * @param PX, PY the coordinates of the specified point being
  765. * measured against this line
  766. * @return a double value that is the distance from a specified point
  767. * to the current line.
  768. * @see #ptSegDist(double, double)
  769. */
  770. public double ptLineDist(double PX, double PY) {
  771. return ptLineDist(getX1(), getY1(), getX2(), getY2(), PX, PY);
  772. }
  773. /**
  774. * Returns the distance from a <code>Point2D</code> to this line.
  775. * The distance measured is the distance between the specified
  776. * point and the closest point on the infinitely-extended line
  777. * defined by this <code>Line2D</code>. If the specified point
  778. * intersects the line, this method returns 0.0.
  779. * @param pt the specified <code>Point2D</code> being measured
  780. * @return a double value that is the distance from a specified
  781. * <code>Point2D</code> to the current line.
  782. * @see #ptSegDist(Point2D)
  783. */
  784. public double ptLineDist(Point2D pt) {
  785. return ptLineDist(getX1(), getY1(), getX2(), getY2(),
  786. pt.getX(), pt.getY());
  787. }
  788. /**
  789. * Tests if a specified coordinate is inside the boundary of this
  790. * <code>Line2D</code>. This method is required to implement the
  791. * {@link Shape} interface, but in the case of <code>Line2D</code>
  792. * objects it always returns <code>false</code> since a line contains
  793. * no area.
  794. * @param x, y the coordinates of the specified point
  795. * @return <code>false</code> because a <code>Line2D</code> contains
  796. * no area.
  797. */
  798. public boolean contains(double x, double y) {
  799. return false;
  800. }
  801. /**
  802. * Tests if a given <code>Point2D</code> is inside the boundary of
  803. * this <code>Line2D</code>.
  804. * This method is required to implement the <code>Shape</code> interface,
  805. * but in the case of <code>Line2D</code> objects it always returns
  806. * <code>false</code> since a line contains no area.
  807. * @param p the specified <code>Point2D</code> to be tested
  808. * @return <code>false</code> because a <code>Line2D</code> contains
  809. * no area.
  810. */
  811. public boolean contains(Point2D p) {
  812. return false;
  813. }
  814. /**
  815. * Tests if this <code>Line2D</code> intersects the interior of a
  816. * specified set of rectangular coordinates.
  817. * @param x, y the coordinates of the top-left corner of the
  818. * specified rectangular area
  819. * @param w the width of the specified rectangular area
  820. * @param h the height of the specified rectangular area
  821. * @return <code>true</code> if this <code>Line2D</code> intersects
  822. * the interior of the specified set of rectangular
  823. * coordinates; <code>false</code> otherwise.
  824. */
  825. public boolean intersects(double x, double y, double w, double h) {
  826. return intersects(new Rectangle2D.Double(x, y, w, h));
  827. }
  828. /**
  829. * Tests if this <code>Line2D</code> intersects the interior of a
  830. * specified <code>Rectangle2D</code>.
  831. * @param r the specified <code>Rectangle2D</code> to be tested
  832. * @return <code>true</code> if this <code>Line2D</code> intersects
  833. * the interior of the specified <code>Rectangle2D</code>
  834. * <code>false</code> otherwise.
  835. */
  836. public boolean intersects(Rectangle2D r) {
  837. return r.intersectsLine(getX1(), getY1(), getX2(), getY2());
  838. }
  839. /**
  840. * Tests if the interior of this <code>Line2D</code> entirely contains
  841. * the specified set of rectangular coordinates.
  842. * This method is required to implement the <code>Shape</code> interface,
  843. * but in the case of <code>Line2D</code> objects it always returns
  844. * false since a line contains no area.
  845. * @param x, y the coordinates of the top-left corner of the
  846. * specified rectangular area
  847. * @param w the width of the specified rectangular area
  848. * @param h the height of the specified rectangular area
  849. * @return <code>false</code> because a <code>Line2D</code> contains
  850. * no area.
  851. */
  852. public boolean contains(double x, double y, double w, double h) {
  853. return false;
  854. }
  855. /**
  856. * Tests if the interior of this <code>Line2D</code> entirely contains
  857. * the specified <code>Rectangle2D</code>.
  858. * This method is required to implement the <code>Shape</code> interface,
  859. * but in the case of <code>Line2D</code> objects it always returns
  860. * <code>false</code> since a line contains no area.
  861. * @param r the specified <code>Rectangle2D</code> to be tested
  862. * @return <code>false</code> because a <code>Line2D</code> contains
  863. * no area.
  864. */
  865. public boolean contains(Rectangle2D r) {
  866. return false;
  867. }
  868. /**
  869. * Returns the bounding box of this <code>Line2D</code>.
  870. * @return a {@link Rectangle} that is the bounding box of the
  871. * <code>Line2D</code>.
  872. */
  873. public Rectangle getBounds() {
  874. return getBounds2D().getBounds();
  875. }
  876. /**
  877. * Returns an iteration object that defines the boundary of this
  878. * <code>Line2D</code>.
  879. * The iterator for this class is not multi-threaded safe,
  880. * which means that this <code>Line2D</code> class does not
  881. * guarantee that modifications to the geometry of this
  882. * <code>Line2D</code> object do not affect any iterations of that
  883. * geometry that are already in process.
  884. * @param at the specified {@link AffineTransform}
  885. * @return a {@link PathIterator} that defines the boundary of this
  886. * <code>Line2D</code>.
  887. */
  888. public PathIterator getPathIterator(AffineTransform at) {
  889. return new LineIterator(this, at);
  890. }
  891. /**
  892. * Returns an iteration object that defines the boundary of this
  893. * flattened <code>Line2D</code>.
  894. * The iterator for this class is not multi-threaded safe,
  895. * which means that this <code>Line2D</code> class does not
  896. * guarantee that modifications to the geometry of this
  897. * <code>Line2D</code> object do not affect any iterations of that
  898. * geometry that are already in process.
  899. * @param at the specified <code>AffineTransform</code>
  900. * @param flatness the maximum amount that the control points for a
  901. * given curve can vary from colinear before a subdivided
  902. * curve is replaced by a straight line connecting the
  903. * endpoints. Since a <code>Line2D</code> object is
  904. * always flat, this parameter is ignored.
  905. * @return a <code>PathIterator</code> that defines the boundary of the
  906. * flattened <code>Line2D</code>
  907. */
  908. public PathIterator getPathIterator(AffineTransform at, double flatness) {
  909. return new LineIterator(this, at);
  910. }
  911. /**
  912. * Creates a new object of the same class as this object.
  913. *
  914. * @return a clone of this instance.
  915. * @exception OutOfMemoryError if there is not enough memory.
  916. * @see java.lang.Cloneable
  917. * @since 1.2
  918. */
  919. public Object clone() {
  920. try {
  921. return super.clone();
  922. } catch (CloneNotSupportedException e) {
  923. // this shouldn't happen, since we are Cloneable
  924. throw new InternalError();
  925. }
  926. }
  927. }