blob: 55bb67b3c78675d303382ce77e3c0d84ff606c11 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package java.awt.geom;
27
28import java.awt.Shape;
29import java.awt.Rectangle;
30import java.io.Serializable;
31
32/**
33 * This <code>Line2D</code> represents a line segment in {@code (x,y)}
34 * coordinate space. This class, like all of the Java 2D API, uses a
35 * default coordinate system called <i>user space</i> in which the y-axis
36 * values increase downward and x-axis values increase to the right. For
37 * more information on the user space coordinate system, see the
38 * <a href="http://java.sun.com/j2se/1.3/docs/guide/2d/spec/j2d-intro.fm2.html#61857">
39 * Coordinate Systems</a> section of the Java 2D Programmer's Guide.
40 * <p>
41 * This class is only the abstract superclass for all objects that
42 * store a 2D line segment.
43 * The actual storage representation of the coordinates is left to
44 * the subclass.
45 *
46 * @author Jim Graham
47 * @since 1.2
48 */
49public abstract class Line2D implements Shape, Cloneable {
50
51 /**
52 * A line segment specified with float coordinates.
53 * @since 1.2
54 */
55 public static class Float extends Line2D implements Serializable {
56 /**
57 * The X coordinate of the start point of the line segment.
58 * @since 1.2
59 * @serial
60 */
61 public float x1;
62
63 /**
64 * The Y coordinate of the start point of the line segment.
65 * @since 1.2
66 * @serial
67 */
68 public float y1;
69
70 /**
71 * The X coordinate of the end point of the line segment.
72 * @since 1.2
73 * @serial
74 */
75 public float x2;
76
77 /**
78 * The Y coordinate of the end point of the line segment.
79 * @since 1.2
80 * @serial
81 */
82 public float y2;
83
84 /**
85 * Constructs and initializes a Line with coordinates (0, 0) -> (0, 0).
86 * @since 1.2
87 */
88 public Float() {
89 }
90
91 /**
92 * Constructs and initializes a Line from the specified coordinates.
93 * @param x1 the X coordinate of the start point
94 * @param y1 the Y coordinate of the start point
95 * @param x2 the X coordinate of the end point
96 * @param y2 the Y coordinate of the end point
97 * @since 1.2
98 */
99 public Float(float x1, float y1, float x2, float y2) {
100 setLine(x1, y1, x2, y2);
101 }
102
103 /**
104 * Constructs and initializes a <code>Line2D</code> from the
105 * specified <code>Point2D</code> objects.
106 * @param p1 the start <code>Point2D</code> of this line segment
107 * @param p2 the end <code>Point2D</code> of this line segment
108 * @since 1.2
109 */
110 public Float(Point2D p1, Point2D p2) {
111 setLine(p1, p2);
112 }
113
114 /**
115 * {@inheritDoc}
116 * @since 1.2
117 */
118 public double getX1() {
119 return (double) x1;
120 }
121
122 /**
123 * {@inheritDoc}
124 * @since 1.2
125 */
126 public double getY1() {
127 return (double) y1;
128 }
129
130 /**
131 * {@inheritDoc}
132 * @since 1.2
133 */
134 public Point2D getP1() {
135 return new Point2D.Float(x1, y1);
136 }
137
138 /**
139 * {@inheritDoc}
140 * @since 1.2
141 */
142 public double getX2() {
143 return (double) x2;
144 }
145
146 /**
147 * {@inheritDoc}
148 * @since 1.2
149 */
150 public double getY2() {
151 return (double) y2;
152 }
153
154 /**
155 * {@inheritDoc}
156 * @since 1.2
157 */
158 public Point2D getP2() {
159 return new Point2D.Float(x2, y2);
160 }
161
162 /**
163 * {@inheritDoc}
164 * @since 1.2
165 */
166 public void setLine(double x1, double y1, double x2, double y2) {
167 this.x1 = (float) x1;
168 this.y1 = (float) y1;
169 this.x2 = (float) x2;
170 this.y2 = (float) y2;
171 }
172
173 /**
174 * Sets the location of the end points of this <code>Line2D</code>
175 * to the specified float coordinates.
176 * @param x1 the X coordinate of the start point
177 * @param y1 the Y coordinate of the start point
178 * @param x2 the X coordinate of the end point
179 * @param y2 the Y coordinate of the end point
180 * @since 1.2
181 */
182 public void setLine(float x1, float y1, float x2, float y2) {
183 this.x1 = x1;
184 this.y1 = y1;
185 this.x2 = x2;
186 this.y2 = y2;
187 }
188
189 /**
190 * {@inheritDoc}
191 * @since 1.2
192 */
193 public Rectangle2D getBounds2D() {
194 float x, y, w, h;
195 if (x1 < x2) {
196 x = x1;
197 w = x2 - x1;
198 } else {
199 x = x2;
200 w = x1 - x2;
201 }
202 if (y1 < y2) {
203 y = y1;
204 h = y2 - y1;
205 } else {
206 y = y2;
207 h = y1 - y2;
208 }
209 return new Rectangle2D.Float(x, y, w, h);
210 }
211
212 /*
213 * JDK 1.6 serialVersionUID
214 */
215 private static final long serialVersionUID = 6161772511649436349L;
216 }
217
218 /**
219 * A line segment specified with double coordinates.
220 * @since 1.2
221 */
222 public static class Double extends Line2D implements Serializable {
223 /**
224 * The X coordinate of the start point of the line segment.
225 * @since 1.2
226 * @serial
227 */
228 public double x1;
229
230 /**
231 * The Y coordinate of the start point of the line segment.
232 * @since 1.2
233 * @serial
234 */
235 public double y1;
236
237 /**
238 * The X coordinate of the end point of the line segment.
239 * @since 1.2
240 * @serial
241 */
242 public double x2;
243
244 /**
245 * The Y coordinate of the end point of the line segment.
246 * @since 1.2
247 * @serial
248 */
249 public double y2;
250
251 /**
252 * Constructs and initializes a Line with coordinates (0, 0) -> (0, 0).
253 * @since 1.2
254 */
255 public Double() {
256 }
257
258 /**
259 * Constructs and initializes a <code>Line2D</code> from the
260 * specified coordinates.
261 * @param x1 the X coordinate of the start point
262 * @param y1 the Y coordinate of the start point
263 * @param x2 the X coordinate of the end point
264 * @param y2 the Y coordinate of the end point
265 * @since 1.2
266 */
267 public Double(double x1, double y1, double x2, double y2) {
268 setLine(x1, y1, x2, y2);
269 }
270
271 /**
272 * Constructs and initializes a <code>Line2D</code> from the
273 * specified <code>Point2D</code> objects.
274 * @param p1 the start <code>Point2D</code> of this line segment
275 * @param p2 the end <code>Point2D</code> of this line segment
276 * @since 1.2
277 */
278 public Double(Point2D p1, Point2D p2) {
279 setLine(p1, p2);
280 }
281
282 /**
283 * {@inheritDoc}
284 * @since 1.2
285 */
286 public double getX1() {
287 return x1;
288 }
289
290 /**
291 * {@inheritDoc}
292 * @since 1.2
293 */
294 public double getY1() {
295 return y1;
296 }
297
298 /**
299 * {@inheritDoc}
300 * @since 1.2
301 */
302 public Point2D getP1() {
303 return new Point2D.Double(x1, y1);
304 }
305
306 /**
307 * {@inheritDoc}
308 * @since 1.2
309 */
310 public double getX2() {
311 return x2;
312 }
313
314 /**
315 * {@inheritDoc}
316 * @since 1.2
317 */
318 public double getY2() {
319 return y2;
320 }
321
322 /**
323 * {@inheritDoc}
324 * @since 1.2
325 */
326 public Point2D getP2() {
327 return new Point2D.Double(x2, y2);
328 }
329
330 /**
331 * {@inheritDoc}
332 * @since 1.2
333 */
334 public void setLine(double x1, double y1, double x2, double y2) {
335 this.x1 = x1;
336 this.y1 = y1;
337 this.x2 = x2;
338 this.y2 = y2;
339 }
340
341 /**
342 * {@inheritDoc}
343 * @since 1.2
344 */
345 public Rectangle2D getBounds2D() {
346 double x, y, w, h;
347 if (x1 < x2) {
348 x = x1;
349 w = x2 - x1;
350 } else {
351 x = x2;
352 w = x1 - x2;
353 }
354 if (y1 < y2) {
355 y = y1;
356 h = y2 - y1;
357 } else {
358 y = y2;
359 h = y1 - y2;
360 }
361 return new Rectangle2D.Double(x, y, w, h);
362 }
363
364 /*
365 * JDK 1.6 serialVersionUID
366 */
367 private static final long serialVersionUID = 7979627399746467499L;
368 }
369
370 /**
371 * This is an abstract class that cannot be instantiated directly.
372 * Type-specific implementation subclasses are available for
373 * instantiation and provide a number of formats for storing
374 * the information necessary to satisfy the various accessory
375 * methods below.
376 *
377 * @see java.awt.geom.Line2D.Float
378 * @see java.awt.geom.Line2D.Double
379 * @since 1.2
380 */
381 protected Line2D() {
382 }
383
384 /**
385 * Returns the X coordinate of the start point in double precision.
386 * @return the X coordinate of the start point of this
387 * {@code Line2D} object.
388 * @since 1.2
389 */
390 public abstract double getX1();
391
392 /**
393 * Returns the Y coordinate of the start point in double precision.
394 * @return the Y coordinate of the start point of this
395 * {@code Line2D} object.
396 * @since 1.2
397 */
398 public abstract double getY1();
399
400 /**
401 * Returns the start <code>Point2D</code> of this <code>Line2D</code>.
402 * @return the start <code>Point2D</code> of this <code>Line2D</code>.
403 * @since 1.2
404 */
405 public abstract Point2D getP1();
406
407 /**
408 * Returns the X coordinate of the end point in double precision.
409 * @return the X coordinate of the end point of this
410 * {@code Line2D} object.
411 * @since 1.2
412 */
413 public abstract double getX2();
414
415 /**
416 * Returns the Y coordinate of the end point in double precision.
417 * @return the Y coordinate of the end point of this
418 * {@code Line2D} object.
419 * @since 1.2
420 */
421 public abstract double getY2();
422
423 /**
424 * Returns the end <code>Point2D</code> of this <code>Line2D</code>.
425 * @return the end <code>Point2D</code> of this <code>Line2D</code>.
426 * @since 1.2
427 */
428 public abstract Point2D getP2();
429
430 /**
431 * Sets the location of the end points of this <code>Line2D</code> to
432 * the specified double coordinates.
433 * @param x1 the X coordinate of the start point
434 * @param y1 the Y coordinate of the start point
435 * @param x2 the X coordinate of the end point
436 * @param y2 the Y coordinate of the end point
437 * @since 1.2
438 */
439 public abstract void setLine(double x1, double y1, double x2, double y2);
440
441 /**
442 * Sets the location of the end points of this <code>Line2D</code> to
443 * the specified <code>Point2D</code> coordinates.
444 * @param p1 the start <code>Point2D</code> of the line segment
445 * @param p2 the end <code>Point2D</code> of the line segment
446 * @since 1.2
447 */
448 public void setLine(Point2D p1, Point2D p2) {
449 setLine(p1.getX(), p1.getY(), p2.getX(), p2.getY());
450 }
451
452 /**
453 * Sets the location of the end points of this <code>Line2D</code> to
454 * the same as those end points of the specified <code>Line2D</code>.
455 * @param l the specified <code>Line2D</code>
456 * @since 1.2
457 */
458 public void setLine(Line2D l) {
459 setLine(l.getX1(), l.getY1(), l.getX2(), l.getY2());
460 }
461
462 /**
463 * Returns an indicator of where the specified point
464 * {@code (px,py)} lies with respect to the line segment from
465 * {@code (x1,y1)} to {@code (x2,y2)}.
466 * The return value can be either 1, -1, or 0 and indicates
467 * in which direction the specified line must pivot around its
468 * first end point, {@code (x1,y1)}, in order to point at the
469 * specified point {@code (px,py)}.
470 * <p>A return value of 1 indicates that the line segment must
471 * turn in the direction that takes the positive X axis towards
472 * the negative Y axis. In the default coordinate system used by
473 * Java 2D, this direction is counterclockwise.
474 * <p>A return value of -1 indicates that the line segment must
475 * turn in the direction that takes the positive X axis towards
476 * the positive Y axis. In the default coordinate system, this
477 * direction is clockwise.
478 * <p>A return value of 0 indicates that the point lies
479 * exactly on the line segment. Note that an indicator value
480 * of 0 is rare and not useful for determining colinearity
481 * because of floating point rounding issues.
482 * <p>If the point is colinear with the line segment, but
483 * not between the end points, then the value will be -1 if the point
484 * lies "beyond {@code (x1,y1)}" or 1 if the point lies
485 * "beyond {@code (x2,y2)}".
486 *
487 * @param x1 the X coordinate of the start point of the
488 * specified line segment
489 * @param y1 the Y coordinate of the start point of the
490 * specified line segment
491 * @param x2 the X coordinate of the end point of the
492 * specified line segment
493 * @param y2 the Y coordinate of the end point of the
494 * specified line segment
495 * @param px the X coordinate of the specified point to be
496 * compared with the specified line segment
497 * @param py the Y coordinate of the specified point to be
498 * compared with the specified line segment
499 * @return an integer that indicates the position of the third specified
500 * coordinates with respect to the line segment formed
501 * by the first two specified coordinates.
502 * @since 1.2
503 */
504 public static int relativeCCW(double x1, double y1,
505 double x2, double y2,
506 double px, double py)
507 {
508 x2 -= x1;
509 y2 -= y1;
510 px -= x1;
511 py -= y1;
512 double ccw = px * y2 - py * x2;
513 if (ccw == 0.0) {
514 // The point is colinear, classify based on which side of
515 // the segment the point falls on. We can calculate a
516 // relative value using the projection of px,py onto the
517 // segment - a negative value indicates the point projects
518 // outside of the segment in the direction of the particular
519 // endpoint used as the origin for the projection.
520 ccw = px * x2 + py * y2;
521 if (ccw > 0.0) {
522 // Reverse the projection to be relative to the original x2,y2
523 // x2 and y2 are simply negated.
524 // px and py need to have (x2 - x1) or (y2 - y1) subtracted
525 // from them (based on the original values)
526 // Since we really want to get a positive answer when the
527 // point is "beyond (x2,y2)", then we want to calculate
528 // the inverse anyway - thus we leave x2 & y2 negated.
529 px -= x2;
530 py -= y2;
531 ccw = px * x2 + py * y2;
532 if (ccw < 0.0) {
533 ccw = 0.0;
534 }
535 }
536 }
537 return (ccw < 0.0) ? -1 : ((ccw > 0.0) ? 1 : 0);
538 }
539
540 /**
541 * Returns an indicator of where the specified point
542 * {@code (px,py)} lies with respect to this line segment.
543 * See the method comments of
544 * {@link #relativeCCW(double, double, double, double, double, double)}
545 * to interpret the return value.
546 * @param px the X coordinate of the specified point
547 * to be compared with this <code>Line2D</code>
548 * @param py the Y coordinate of the specified point
549 * to be compared with this <code>Line2D</code>
550 * @return an integer that indicates the position of the specified
551 * coordinates with respect to this <code>Line2D</code>
552 * @see #relativeCCW(double, double, double, double, double, double)
553 * @since 1.2
554 */
555 public int relativeCCW(double px, double py) {
556 return relativeCCW(getX1(), getY1(), getX2(), getY2(), px, py);
557 }
558
559 /**
560 * Returns an indicator of where the specified <code>Point2D</code>
561 * lies with respect to this line segment.
562 * See the method comments of
563 * {@link #relativeCCW(double, double, double, double, double, double)}
564 * to interpret the return value.
565 * @param p the specified <code>Point2D</code> to be compared
566 * with this <code>Line2D</code>
567 * @return an integer that indicates the position of the specified
568 * <code>Point2D</code> with respect to this <code>Line2D</code>
569 * @see #relativeCCW(double, double, double, double, double, double)
570 * @since 1.2
571 */
572 public int relativeCCW(Point2D p) {
573 return relativeCCW(getX1(), getY1(), getX2(), getY2(),
574 p.getX(), p.getY());
575 }
576
577 /**
578 * Tests if the line segment from {@code (x1,y1)} to
579 * {@code (x2,y2)} intersects the line segment from {@code (x3,y3)}
580 * to {@code (x4,y4)}.
581 *
582 * @param x1 the X coordinate of the start point of the first
583 * specified line segment
584 * @param y1 the Y coordinate of the start point of the first
585 * specified line segment
586 * @param x2 the X coordinate of the end point of the first
587 * specified line segment
588 * @param y2 the Y coordinate of the end point of the first
589 * specified line segment
590 * @param x3 the X coordinate of the start point of the second
591 * specified line segment
592 * @param y3 the Y coordinate of the start point of the second
593 * specified line segment
594 * @param x4 the X coordinate of the end point of the second
595 * specified line segment
596 * @param y4 the Y coordinate of the end point of the second
597 * specified line segment
598 * @return <code>true</code> if the first specified line segment
599 * and the second specified line segment intersect
600 * each other; <code>false</code> otherwise.
601 * @since 1.2
602 */
603 public static boolean linesIntersect(double x1, double y1,
604 double x2, double y2,
605 double x3, double y3,
606 double x4, double y4)
607 {
608 return ((relativeCCW(x1, y1, x2, y2, x3, y3) *
609 relativeCCW(x1, y1, x2, y2, x4, y4) <= 0)
610 && (relativeCCW(x3, y3, x4, y4, x1, y1) *
611 relativeCCW(x3, y3, x4, y4, x2, y2) <= 0));
612 }
613
614 /**
615 * Tests if the line segment from {@code (x1,y1)} to
616 * {@code (x2,y2)} intersects this line segment.
617 *
618 * @param x1 the X coordinate of the start point of the
619 * specified line segment
620 * @param y1 the Y coordinate of the start point of the
621 * specified line segment
622 * @param x2 the X coordinate of the end point of the
623 * specified line segment
624 * @param y2 the Y coordinate of the end point of the
625 * specified line segment
626 * @return <true> if this line segment and the specified line segment
627 * intersect each other; <code>false</code> otherwise.
628 * @since 1.2
629 */
630 public boolean intersectsLine(double x1, double y1, double x2, double y2) {
631 return linesIntersect(x1, y1, x2, y2,
632 getX1(), getY1(), getX2(), getY2());
633 }
634
635 /**
636 * Tests if the specified line segment intersects this line segment.
637 * @param l the specified <code>Line2D</code>
638 * @return <code>true</code> if this line segment and the specified line
639 * segment intersect each other;
640 * <code>false</code> otherwise.
641 * @since 1.2
642 */
643 public boolean intersectsLine(Line2D l) {
644 return linesIntersect(l.getX1(), l.getY1(), l.getX2(), l.getY2(),
645 getX1(), getY1(), getX2(), getY2());
646 }
647
648 /**
649 * Returns the square of the distance from a point to a line segment.
650 * The distance measured is the distance between the specified
651 * point and the closest point between the specified end points.
652 * If the specified point intersects the line segment in between the
653 * end points, this method returns 0.0.
654 *
655 * @param x1 the X coordinate of the start point of the
656 * specified line segment
657 * @param y1 the Y coordinate of the start point of the
658 * specified line segment
659 * @param x2 the X coordinate of the end point of the
660 * specified line segment
661 * @param y2 the Y coordinate of the end point of the
662 * specified line segment
663 * @param px the X coordinate of the specified point being
664 * measured against the specified line segment
665 * @param py the Y coordinate of the specified point being
666 * measured against the specified line segment
667 * @return a double value that is the square of the distance from the
668 * specified point to the specified line segment.
669 * @see #ptLineDistSq(double, double, double, double, double, double)
670 * @since 1.2
671 */
672 public static double ptSegDistSq(double x1, double y1,
673 double x2, double y2,
674 double px, double py)
675 {
676 // Adjust vectors relative to x1,y1
677 // x2,y2 becomes relative vector from x1,y1 to end of segment
678 x2 -= x1;
679 y2 -= y1;
680 // px,py becomes relative vector from x1,y1 to test point
681 px -= x1;
682 py -= y1;
683 double dotprod = px * x2 + py * y2;
684 double projlenSq;
685 if (dotprod <= 0.0) {
686 // px,py is on the side of x1,y1 away from x2,y2
687 // distance to segment is length of px,py vector
688 // "length of its (clipped) projection" is now 0.0
689 projlenSq = 0.0;
690 } else {
691 // switch to backwards vectors relative to x2,y2
692 // x2,y2 are already the negative of x1,y1=>x2,y2
693 // to get px,py to be the negative of px,py=>x2,y2
694 // the dot product of two negated vectors is the same
695 // as the dot product of the two normal vectors
696 px = x2 - px;
697 py = y2 - py;
698 dotprod = px * x2 + py * y2;
699 if (dotprod <= 0.0) {
700 // px,py is on the side of x2,y2 away from x1,y1
701 // distance to segment is length of (backwards) px,py vector
702 // "length of its (clipped) projection" is now 0.0
703 projlenSq = 0.0;
704 } else {
705 // px,py is between x1,y1 and x2,y2
706 // dotprod is the length of the px,py vector
707 // projected on the x2,y2=>x1,y1 vector times the
708 // length of the x2,y2=>x1,y1 vector
709 projlenSq = dotprod * dotprod / (x2 * x2 + y2 * y2);
710 }
711 }
712 // Distance to line is now the length of the relative point
713 // vector minus the length of its projection onto the line
714 // (which is zero if the projection falls outside the range
715 // of the line segment).
716 double lenSq = px * px + py * py - projlenSq;
717 if (lenSq < 0) {
718 lenSq = 0;
719 }
720 return lenSq;
721 }
722
723 /**
724 * Returns the distance from a point to a line segment.
725 * The distance measured is the distance between the specified
726 * point and the closest point between the specified end points.
727 * If the specified point intersects the line segment in between the
728 * end points, this method returns 0.0.
729 *
730 * @param x1 the X coordinate of the start point of the
731 * specified line segment
732 * @param y1 the Y coordinate of the start point of the
733 * specified line segment
734 * @param x2 the X coordinate of the end point of the
735 * specified line segment
736 * @param y2 the Y coordinate of the end point of the
737 * specified line segment
738 * @param px the X coordinate of the specified point being
739 * measured against the specified line segment
740 * @param py the Y coordinate of the specified point being
741 * measured against the specified line segment
742 * @return a double value that is the distance from the specified point
743 * to the specified line segment.
744 * @see #ptLineDist(double, double, double, double, double, double)
745 * @since 1.2
746 */
747 public static double ptSegDist(double x1, double y1,
748 double x2, double y2,
749 double px, double py)
750 {
751 return Math.sqrt(ptSegDistSq(x1, y1, x2, y2, px, py));
752 }
753
754 /**
755 * Returns the square of the distance from a point to this line segment.
756 * The distance measured is the distance between the specified
757 * point and the closest point between the current line's end points.
758 * If the specified point intersects the line segment in between the
759 * end points, this method returns 0.0.
760 *
761 * @param px the X coordinate of the specified point being
762 * measured against this line segment
763 * @param py the Y coordinate of the specified point being
764 * measured against this line segment
765 * @return a double value that is the square of the distance from the
766 * specified point to the current line segment.
767 * @see #ptLineDistSq(double, double)
768 * @since 1.2
769 */
770 public double ptSegDistSq(double px, double py) {
771 return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), px, py);
772 }
773
774 /**
775 * Returns the square of the distance from a <code>Point2D</code> to
776 * this line segment.
777 * The distance measured is the distance between the specified
778 * point and the closest point between the current line's end points.
779 * If the specified point intersects the line segment in between the
780 * end points, this method returns 0.0.
781 * @param pt the specified <code>Point2D</code> being measured against
782 * this line segment.
783 * @return a double value that is the square of the distance from the
784 * specified <code>Point2D</code> to the current
785 * line segment.
786 * @see #ptLineDistSq(Point2D)
787 * @since 1.2
788 */
789 public double ptSegDistSq(Point2D pt) {
790 return ptSegDistSq(getX1(), getY1(), getX2(), getY2(),
791 pt.getX(), pt.getY());
792 }
793
794 /**
795 * Returns the distance from a point to this line segment.
796 * The distance measured is the distance between the specified
797 * point and the closest point between the current line's end points.
798 * If the specified point intersects the line segment in between the
799 * end points, this method returns 0.0.
800 *
801 * @param px the X coordinate of the specified point being
802 * measured against this line segment
803 * @param py the Y coordinate of the specified point being
804 * measured against this line segment
805 * @return a double value that is the distance from the specified
806 * point to the current line segment.
807 * @see #ptLineDist(double, double)
808 * @since 1.2
809 */
810 public double ptSegDist(double px, double py) {
811 return ptSegDist(getX1(), getY1(), getX2(), getY2(), px, py);
812 }
813
814 /**
815 * Returns the distance from a <code>Point2D</code> to this line
816 * segment.
817 * The distance measured is the distance between the specified
818 * point and the closest point between the current line's end points.
819 * If the specified point intersects the line segment in between the
820 * end points, this method returns 0.0.
821 * @param pt the specified <code>Point2D</code> being measured
822 * against this line segment
823 * @return a double value that is the distance from the specified
824 * <code>Point2D</code> to the current line
825 * segment.
826 * @see #ptLineDist(Point2D)
827 * @since 1.2
828 */
829 public double ptSegDist(Point2D pt) {
830 return ptSegDist(getX1(), getY1(), getX2(), getY2(),
831 pt.getX(), pt.getY());
832 }
833
834 /**
835 * Returns the square of the distance from a point to a line.
836 * The distance measured is the distance between the specified
837 * point and the closest point on the infinitely-extended line
838 * defined by the specified coordinates. If the specified point
839 * intersects the line, this method returns 0.0.
840 *
841 * @param x1 the X coordinate of the start point of the specified line
842 * @param y1 the Y coordinate of the start point of the specified line
843 * @param x2 the X coordinate of the end point of the specified line
844 * @param y2 the Y coordinate of the end point of the specified line
845 * @param px the X coordinate of the specified point being
846 * measured against the specified line
847 * @param py the Y coordinate of the specified point being
848 * measured against the specified line
849 * @return a double value that is the square of the distance from the
850 * specified point to the specified line.
851 * @see #ptSegDistSq(double, double, double, double, double, double)
852 * @since 1.2
853 */
854 public static double ptLineDistSq(double x1, double y1,
855 double x2, double y2,
856 double px, double py)
857 {
858 // Adjust vectors relative to x1,y1
859 // x2,y2 becomes relative vector from x1,y1 to end of segment
860 x2 -= x1;
861 y2 -= y1;
862 // px,py becomes relative vector from x1,y1 to test point
863 px -= x1;
864 py -= y1;
865 double dotprod = px * x2 + py * y2;
866 // dotprod is the length of the px,py vector
867 // projected on the x1,y1=>x2,y2 vector times the
868 // length of the x1,y1=>x2,y2 vector
869 double projlenSq = dotprod * dotprod / (x2 * x2 + y2 * y2);
870 // Distance to line is now the length of the relative point
871 // vector minus the length of its projection onto the line
872 double lenSq = px * px + py * py - projlenSq;
873 if (lenSq < 0) {
874 lenSq = 0;
875 }
876 return lenSq;
877 }
878
879 /**
880 * Returns the distance from a point to a line.
881 * The distance measured is the distance between the specified
882 * point and the closest point on the infinitely-extended line
883 * defined by the specified coordinates. If the specified point
884 * intersects the line, this method returns 0.0.
885 *
886 * @param x1 the X coordinate of the start point of the specified line
887 * @param y1 the Y coordinate of the start point of the specified line
888 * @param x2 the X coordinate of the end point of the specified line
889 * @param y2 the Y coordinate of the end point of the specified line
890 * @param px the X coordinate of the specified point being
891 * measured against the specified line
892 * @param py the Y coordinate of the specified point being
893 * measured against the specified line
894 * @return a double value that is the distance from the specified
895 * point to the specified line.
896 * @see #ptSegDist(double, double, double, double, double, double)
897 * @since 1.2
898 */
899 public static double ptLineDist(double x1, double y1,
900 double x2, double y2,
901 double px, double py)
902 {
903 return Math.sqrt(ptLineDistSq(x1, y1, x2, y2, px, py));
904 }
905
906 /**
907 * Returns the square of the distance from a point to this line.
908 * The distance measured is the distance between the specified
909 * point and the closest point on the infinitely-extended line
910 * defined by this <code>Line2D</code>. If the specified point
911 * intersects the line, this method returns 0.0.
912 *
913 * @param px the X coordinate of the specified point being
914 * measured against this line
915 * @param py the Y coordinate of the specified point being
916 * measured against this line
917 * @return a double value that is the square of the distance from a
918 * specified point to the current line.
919 * @see #ptSegDistSq(double, double)
920 * @since 1.2
921 */
922 public double ptLineDistSq(double px, double py) {
923 return ptLineDistSq(getX1(), getY1(), getX2(), getY2(), px, py);
924 }
925
926 /**
927 * Returns the square of the distance from a specified
928 * <code>Point2D</code> to this line.
929 * The distance measured is the distance between the specified
930 * point and the closest point on the infinitely-extended line
931 * defined by this <code>Line2D</code>. If the specified point
932 * intersects the line, this method returns 0.0.
933 * @param pt the specified <code>Point2D</code> being measured
934 * against this line
935 * @return a double value that is the square of the distance from a
936 * specified <code>Point2D</code> to the current
937 * line.
938 * @see #ptSegDistSq(Point2D)
939 * @since 1.2
940 */
941 public double ptLineDistSq(Point2D pt) {
942 return ptLineDistSq(getX1(), getY1(), getX2(), getY2(),
943 pt.getX(), pt.getY());
944 }
945
946 /**
947 * Returns the distance from a point to this line.
948 * The distance measured is the distance between the specified
949 * point and the closest point on the infinitely-extended line
950 * defined by this <code>Line2D</code>. If the specified point
951 * intersects the line, this method returns 0.0.
952 *
953 * @param px the X coordinate of the specified point being
954 * measured against this line
955 * @param py the Y coordinate of the specified point being
956 * measured against this line
957 * @return a double value that is the distance from a specified point
958 * to the current line.
959 * @see #ptSegDist(double, double)
960 * @since 1.2
961 */
962 public double ptLineDist(double px, double py) {
963 return ptLineDist(getX1(), getY1(), getX2(), getY2(), px, py);
964 }
965
966 /**
967 * Returns the distance from a <code>Point2D</code> to this line.
968 * The distance measured is the distance between the specified
969 * point and the closest point on the infinitely-extended line
970 * defined by this <code>Line2D</code>. If the specified point
971 * intersects the line, this method returns 0.0.
972 * @param pt the specified <code>Point2D</code> being measured
973 * @return a double value that is the distance from a specified
974 * <code>Point2D</code> to the current line.
975 * @see #ptSegDist(Point2D)
976 * @since 1.2
977 */
978 public double ptLineDist(Point2D pt) {
979 return ptLineDist(getX1(), getY1(), getX2(), getY2(),
980 pt.getX(), pt.getY());
981 }
982
983 /**
984 * Tests if a specified coordinate is inside the boundary of this
985 * <code>Line2D</code>. This method is required to implement the
986 * {@link Shape} interface, but in the case of <code>Line2D</code>
987 * objects it always returns <code>false</code> since a line contains
988 * no area.
989 * @param x the X coordinate of the specified point to be tested
990 * @param y the Y coordinate of the specified point to be tested
991 * @return <code>false</code> because a <code>Line2D</code> contains
992 * no area.
993 * @since 1.2
994 */
995 public boolean contains(double x, double y) {
996 return false;
997 }
998
999 /**
1000 * Tests if a given <code>Point2D</code> is inside the boundary of
1001 * this <code>Line2D</code>.
1002 * This method is required to implement the {@link Shape} interface,
1003 * but in the case of <code>Line2D</code> objects it always returns
1004 * <code>false</code> since a line contains no area.
1005 * @param p the specified <code>Point2D</code> to be tested
1006 * @return <code>false</code> because a <code>Line2D</code> contains
1007 * no area.
1008 * @since 1.2
1009 */
1010 public boolean contains(Point2D p) {
1011 return false;
1012 }
1013
1014 /**
1015 * {@inheritDoc}
1016 * @since 1.2
1017 */
1018 public boolean intersects(double x, double y, double w, double h) {
1019 return intersects(new Rectangle2D.Double(x, y, w, h));
1020 }
1021
1022 /**
1023 * {@inheritDoc}
1024 * @since 1.2
1025 */
1026 public boolean intersects(Rectangle2D r) {
1027 return r.intersectsLine(getX1(), getY1(), getX2(), getY2());
1028 }
1029
1030 /**
1031 * Tests if the interior of this <code>Line2D</code> entirely contains
1032 * the specified set of rectangular coordinates.
1033 * This method is required to implement the <code>Shape</code> interface,
1034 * but in the case of <code>Line2D</code> objects it always returns
1035 * false since a line contains no area.
1036 * @param x the X coordinate of the upper-left corner of the
1037 * specified rectangular area
1038 * @param y the Y coordinate of the upper-left corner of the
1039 * specified rectangular area
1040 * @param w the width of the specified rectangular area
1041 * @param h the height of the specified rectangular area
1042 * @return <code>false</code> because a <code>Line2D</code> contains
1043 * no area.
1044 * @since 1.2
1045 */
1046 public boolean contains(double x, double y, double w, double h) {
1047 return false;
1048 }
1049
1050 /**
1051 * Tests if the interior of this <code>Line2D</code> entirely contains
1052 * the specified <code>Rectangle2D</code>.
1053 * This method is required to implement the <code>Shape</code> interface,
1054 * but in the case of <code>Line2D</code> objects it always returns
1055 * <code>false</code> since a line contains no area.
1056 * @param r the specified <code>Rectangle2D</code> to be tested
1057 * @return <code>false</code> because a <code>Line2D</code> contains
1058 * no area.
1059 * @since 1.2
1060 */
1061 public boolean contains(Rectangle2D r) {
1062 return false;
1063 }
1064
1065 /**
1066 * {@inheritDoc}
1067 * @since 1.2
1068 */
1069 public Rectangle getBounds() {
1070 return getBounds2D().getBounds();
1071 }
1072
1073 /**
1074 * Returns an iteration object that defines the boundary of this
1075 * <code>Line2D</code>.
1076 * The iterator for this class is not multi-threaded safe,
1077 * which means that this <code>Line2D</code> class does not
1078 * guarantee that modifications to the geometry of this
1079 * <code>Line2D</code> object do not affect any iterations of that
1080 * geometry that are already in process.
1081 * @param at the specified {@link AffineTransform}
1082 * @return a {@link PathIterator} that defines the boundary of this
1083 * <code>Line2D</code>.
1084 * @since 1.2
1085 */
1086 public PathIterator getPathIterator(AffineTransform at) {
1087 return new LineIterator(this, at);
1088 }
1089
1090 /**
1091 * Returns an iteration object that defines the boundary of this
1092 * flattened <code>Line2D</code>.
1093 * The iterator for this class is not multi-threaded safe,
1094 * which means that this <code>Line2D</code> class does not
1095 * guarantee that modifications to the geometry of this
1096 * <code>Line2D</code> object do not affect any iterations of that
1097 * geometry that are already in process.
1098 * @param at the specified <code>AffineTransform</code>
1099 * @param flatness the maximum amount that the control points for a
1100 * given curve can vary from colinear before a subdivided
1101 * curve is replaced by a straight line connecting the
1102 * end points. Since a <code>Line2D</code> object is
1103 * always flat, this parameter is ignored.
1104 * @return a <code>PathIterator</code> that defines the boundary of the
1105 * flattened <code>Line2D</code>
1106 * @since 1.2
1107 */
1108 public PathIterator getPathIterator(AffineTransform at, double flatness) {
1109 return new LineIterator(this, at);
1110 }
1111
1112 /**
1113 * Creates a new object of the same class as this object.
1114 *
1115 * @return a clone of this instance.
1116 * @exception OutOfMemoryError if there is not enough memory.
1117 * @see java.lang.Cloneable
1118 * @since 1.2
1119 */
1120 public Object clone() {
1121 try {
1122 return super.clone();
1123 } catch (CloneNotSupportedException e) {
1124 // this shouldn't happen, since we are Cloneable
1125 throw new InternalError();
1126 }
1127 }
1128}