1 /*
2  * Copyright (c) 1997, 2017, Oracle and/or its affiliates. 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.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */

25
26 package java.awt.geom;
27
28 import java.awt.Shape;
29 import java.awt.Rectangle;
30 import java.io.Serializable;
31
32 /**
33  * This {@code Line2D} represents a line segment in {@code (x,y)}
34  * coordinate space.
35  * <p>
36  * This class is only the abstract superclass for all objects that
37  * store a 2D line segment.
38  * The actual storage representation of the coordinates is left to
39  * the subclass.
40  *
41  * @author      Jim Graham
42  * @since 1.2
43  */

44 public abstract class Line2D implements Shape, Cloneable {
45
46     /**
47      * A line segment specified with float coordinates.
48      * @since 1.2
49      */

50     public static class Float extends Line2D implements Serializable {
51         /**
52          * The X coordinate of the start point of the line segment.
53          * @since 1.2
54          * @serial
55          */

56         public float x1;
57
58         /**
59          * The Y coordinate of the start point of the line segment.
60          * @since 1.2
61          * @serial
62          */

63         public float y1;
64
65         /**
66          * The X coordinate of the end point of the line segment.
67          * @since 1.2
68          * @serial
69          */

70         public float x2;
71
72         /**
73          * The Y coordinate of the end point of the line segment.
74          * @since 1.2
75          * @serial
76          */

77         public float y2;
78
79         /**
80          * Constructs and initializes a Line with coordinates (0, 0) &rarr; (0, 0).
81          * @since 1.2
82          */

83         public Float() {
84         }
85
86         /**
87          * Constructs and initializes a Line from the specified coordinates.
88          * @param x1 the X coordinate of the start point
89          * @param y1 the Y coordinate of the start point
90          * @param x2 the X coordinate of the end point
91          * @param y2 the Y coordinate of the end point
92          * @since 1.2
93          */

94         public Float(float x1, float y1, float x2, float y2) {
95             setLine(x1, y1, x2, y2);
96         }
97
98         /**
99          * Constructs and initializes a {@code Line2D} from the
100          * specified {@code Point2D} objects.
101          * @param p1 the start {@code Point2D} of this line segment
102          * @param p2 the end {@code Point2D} of this line segment
103          * @since 1.2
104          */

105         public Float(Point2D p1, Point2D p2) {
106             setLine(p1, p2);
107         }
108
109         /**
110          * {@inheritDoc}
111          * @since 1.2
112          */

113         public double getX1() {
114             return (double) x1;
115         }
116
117         /**
118          * {@inheritDoc}
119          * @since 1.2
120          */

121         public double getY1() {
122             return (double) y1;
123         }
124
125         /**
126          * {@inheritDoc}
127          * @since 1.2
128          */

129         public Point2D getP1() {
130             return new Point2D.Float(x1, y1);
131         }
132
133         /**
134          * {@inheritDoc}
135          * @since 1.2
136          */

137         public double getX2() {
138             return (double) x2;
139         }
140
141         /**
142          * {@inheritDoc}
143          * @since 1.2
144          */

145         public double getY2() {
146             return (double) y2;
147         }
148
149         /**
150          * {@inheritDoc}
151          * @since 1.2
152          */

153         public Point2D getP2() {
154             return new Point2D.Float(x2, y2);
155         }
156
157         /**
158          * {@inheritDoc}
159          * @since 1.2
160          */

161         public void setLine(double x1, double y1, double x2, double y2) {
162             this.x1 = (float) x1;
163             this.y1 = (float) y1;
164             this.x2 = (float) x2;
165             this.y2 = (float) y2;
166         }
167
168         /**
169          * Sets the location of the end points of this {@code Line2D}
170          * to the specified float coordinates.
171          * @param x1 the X coordinate of the start point
172          * @param y1 the Y coordinate of the start point
173          * @param x2 the X coordinate of the end point
174          * @param y2 the Y coordinate of the end point
175          * @since 1.2
176          */

177         public void setLine(float x1, float y1, float x2, float y2) {
178             this.x1 = x1;
179             this.y1 = y1;
180             this.x2 = x2;
181             this.y2 = y2;
182         }
183
184         /**
185          * {@inheritDoc}
186          * @since 1.2
187          */

188         public Rectangle2D getBounds2D() {
189             float x, y, w, h;
190             if (x1 < x2) {
191                 x = x1;
192                 w = x2 - x1;
193             } else {
194                 x = x2;
195                 w = x1 - x2;
196             }
197             if (y1 < y2) {
198                 y = y1;
199                 h = y2 - y1;
200             } else {
201                 y = y2;
202                 h = y1 - y2;
203             }
204             return new Rectangle2D.Float(x, y, w, h);
205         }
206
207         /*
208          * JDK 1.6 serialVersionUID
209          */

210         private static final long serialVersionUID = 6161772511649436349L;
211     }
212
213     /**
214      * A line segment specified with double coordinates.
215      * @since 1.2
216      */

217     public static class Double extends Line2D implements Serializable {
218         /**
219          * The X coordinate of the start point of the line segment.
220          * @since 1.2
221          * @serial
222          */

223         public double x1;
224
225         /**
226          * The Y coordinate of the start point of the line segment.
227          * @since 1.2
228          * @serial
229          */

230         public double y1;
231
232         /**
233          * The X coordinate of the end point of the line segment.
234          * @since 1.2
235          * @serial
236          */

237         public double x2;
238
239         /**
240          * The Y coordinate of the end point of the line segment.
241          * @since 1.2
242          * @serial
243          */

244         public double y2;
245
246         /**
247          * Constructs and initializes a Line with coordinates (0, 0) &rarr; (0, 0).
248          * @since 1.2
249          */

250         public Double() {
251         }
252
253         /**
254          * Constructs and initializes a {@code Line2D} from the
255          * specified coordinates.
256          * @param x1 the X coordinate of the start point
257          * @param y1 the Y coordinate of the start point
258          * @param x2 the X coordinate of the end point
259          * @param y2 the Y coordinate of the end point
260          * @since 1.2
261          */

262         public Double(double x1, double y1, double x2, double y2) {
263             setLine(x1, y1, x2, y2);
264         }
265
266         /**
267          * Constructs and initializes a {@code Line2D} from the
268          * specified {@code Point2D} objects.
269          * @param p1 the start {@code Point2D} of this line segment
270          * @param p2 the end {@code Point2D} of this line segment
271          * @since 1.2
272          */

273         public Double(Point2D p1, Point2D p2) {
274             setLine(p1, p2);
275         }
276
277         /**
278          * {@inheritDoc}
279          * @since 1.2
280          */

281         public double getX1() {
282             return x1;
283         }
284
285         /**
286          * {@inheritDoc}
287          * @since 1.2
288          */

289         public double getY1() {
290             return y1;
291         }
292
293         /**
294          * {@inheritDoc}
295          * @since 1.2
296          */

297         public Point2D getP1() {
298             return new Point2D.Double(x1, y1);
299         }
300
301         /**
302          * {@inheritDoc}
303          * @since 1.2
304          */

305         public double getX2() {
306             return x2;
307         }
308
309         /**
310          * {@inheritDoc}
311          * @since 1.2
312          */

313         public double getY2() {
314             return y2;
315         }
316
317         /**
318          * {@inheritDoc}
319          * @since 1.2
320          */

321         public Point2D getP2() {
322             return new Point2D.Double(x2, y2);
323         }
324
325         /**
326          * {@inheritDoc}
327          * @since 1.2
328          */

329         public void setLine(double x1, double y1, double x2, double y2) {
330             this.x1 = x1;
331             this.y1 = y1;
332             this.x2 = x2;
333             this.y2 = y2;
334         }
335
336         /**
337          * {@inheritDoc}
338          * @since 1.2
339          */

340         public Rectangle2D getBounds2D() {
341             double x, y, w, h;
342             if (x1 < x2) {
343                 x = x1;
344                 w = x2 - x1;
345             } else {
346                 x = x2;
347                 w = x1 - x2;
348             }
349             if (y1 < y2) {
350                 y = y1;
351                 h = y2 - y1;
352             } else {
353                 y = y2;
354                 h = y1 - y2;
355             }
356             return new Rectangle2D.Double(x, y, w, h);
357         }
358
359         /*
360          * JDK 1.6 serialVersionUID
361          */

362         private static final long serialVersionUID = 7979627399746467499L;
363     }
364
365     /**
366      * This is an abstract class that cannot be instantiated directly.
367      * Type-specific implementation subclasses are available for
368      * instantiation and provide a number of formats for storing
369      * the information necessary to satisfy the various accessory
370      * methods below.
371      *
372      * @see java.awt.geom.Line2D.Float
373      * @see java.awt.geom.Line2D.Double
374      * @since 1.2
375      */

376     protected Line2D() {
377     }
378
379     /**
380      * Returns the X coordinate of the start point in double precision.
381      * @return the X coordinate of the start point of this
382      *         {@code Line2D} object.
383      * @since 1.2
384      */

385     public abstract double getX1();
386
387     /**
388      * Returns the Y coordinate of the start point in double precision.
389      * @return the Y coordinate of the start point of this
390      *         {@code Line2D} object.
391      * @since 1.2
392      */

393     public abstract double getY1();
394
395     /**
396      * Returns the start {@code Point2D} of this {@code Line2D}.
397      * @return the start {@code Point2D} of this {@code Line2D}.
398      * @since 1.2
399      */

400     public abstract Point2D getP1();
401
402     /**
403      * Returns the X coordinate of the end point in double precision.
404      * @return the X coordinate of the end point of this
405      *         {@code Line2D} object.
406      * @since 1.2
407      */

408     public abstract double getX2();
409
410     /**
411      * Returns the Y coordinate of the end point in double precision.
412      * @return the Y coordinate of the end point of this
413      *         {@code Line2D} object.
414      * @since 1.2
415      */

416     public abstract double getY2();
417
418     /**
419      * Returns the end {@code Point2D} of this {@code Line2D}.
420      * @return the end {@code Point2D} of this {@code Line2D}.
421      * @since 1.2
422      */

423     public abstract Point2D getP2();
424
425     /**
426      * Sets the location of the end points of this {@code Line2D} to
427      * the specified double coordinates.
428      * @param x1 the X coordinate of the start point
429      * @param y1 the Y coordinate of the start point
430      * @param x2 the X coordinate of the end point
431      * @param y2 the Y coordinate of the end point
432      * @since 1.2
433      */

434     public abstract void setLine(double x1, double y1, double x2, double y2);
435
436     /**
437      * Sets the location of the end points of this {@code Line2D} to
438      * the specified {@code Point2D} coordinates.
439      * @param p1 the start {@code Point2D} of the line segment
440      * @param p2 the end {@code Point2D} of the line segment
441      * @since 1.2
442      */

443     public void setLine(Point2D p1, Point2D p2) {
444         setLine(p1.getX(), p1.getY(), p2.getX(), p2.getY());
445     }
446
447     /**
448      * Sets the location of the end points of this {@code Line2D} to
449      * the same as those end points of the specified {@code Line2D}.
450      * @param l the specified {@code Line2D}
451      * @since 1.2
452      */

453     public void setLine(Line2D l) {
454         setLine(l.getX1(), l.getY1(), l.getX2(), l.getY2());
455     }
456
457     /**
458      * Returns an indicator of where the specified point
459      * {@code (px,py)} lies with respect to the line segment from
460      * {@code (x1,y1)} to {@code (x2,y2)}.
461      * The return value can be either 1, -1, or 0 and indicates
462      * in which direction the specified line must pivot around its
463      * first end point, {@code (x1,y1)}, in order to point at the
464      * specified point {@code (px,py)}.
465      * <p>A return value of 1 indicates that the line segment must
466      * turn in the direction that takes the positive X axis towards
467      * the negative Y axis.  In the default coordinate system used by
468      * Java 2D, this direction is counterclockwise.
469      * <p>A return value of -1 indicates that the line segment must
470      * turn in the direction that takes the positive X axis towards
471      * the positive Y axis.  In the default coordinate system, this
472      * direction is clockwise.
473      * <p>A return value of 0 indicates that the point lies
474      * exactly on the line segment.  Note that an indicator value
475      * of 0 is rare and not useful for determining collinearity
476      * because of floating point rounding issues.
477      * <p>If the point is colinear with the line segment, but
478      * not between the end points, then the value will be -1 if the point
479      * lies "beyond {@code (x1,y1)}" or 1 if the point lies
480      * "beyond {@code (x2,y2)}".
481      *
482      * @param x1 the X coordinate of the start point of the
483      *           specified line segment
484      * @param y1 the Y coordinate of the start point of the
485      *           specified line segment
486      * @param x2 the X coordinate of the end point of the
487      *           specified line segment
488      * @param y2 the Y coordinate of the end point of the
489      *           specified line segment
490      * @param px the X coordinate of the specified point to be
491      *           compared with the specified line segment
492      * @param py the Y coordinate of the specified point to be
493      *           compared with the specified line segment
494      * @return an integer that indicates the position of the third specified
495      *                  coordinates with respect to the line segment formed
496      *                  by the first two specified coordinates.
497      * @since 1.2
498      */

499     public static int relativeCCW(double x1, double y1,
500                                   double x2, double y2,
501                                   double px, double py)
502     {
503         x2 -= x1;
504         y2 -= y1;
505         px -= x1;
506         py -= y1;
507         double ccw = px * y2 - py * x2;
508         if (ccw == 0.0) {
509             // The point is colinear, classify based on which side of
510             // the segment the point falls on.  We can calculate a
511             // relative value using the projection of px,py onto the
512             // segment - a negative value indicates the point projects
513             // outside of the segment in the direction of the particular
514             // endpoint used as the origin for the projection.
515             ccw = px * x2 + py * y2;
516             if (ccw > 0.0) {
517                 // Reverse the projection to be relative to the original x2,y2
518                 // x2 and y2 are simply negated.
519                 // px and py need to have (x2 - x1) or (y2 - y1) subtracted
520                 //    from them (based on the original values)
521                 // Since we really want to get a positive answer when the
522                 //    point is "beyond (x2,y2)", then we want to calculate
523                 //    the inverse anyway - thus we leave x2 & y2 negated.
524                 px -= x2;
525                 py -= y2;
526                 ccw = px * x2 + py * y2;
527                 if (ccw < 0.0) {
528                     ccw = 0.0;
529                 }
530             }
531         }
532         return (ccw < 0.0) ? -1 : ((ccw > 0.0) ? 1 : 0);
533     }
534
535     /**
536      * Returns an indicator of where the specified point
537      * {@code (px,py)} lies with respect to this line segment.
538      * See the method comments of
539      * {@link #relativeCCW(doubledoubledoubledoubledoubledouble)}
540      * to interpret the return value.
541      * @param px the X coordinate of the specified point
542      *           to be compared with this {@code Line2D}
543      * @param py the Y coordinate of the specified point
544      *           to be compared with this {@code Line2D}
545      * @return an integer that indicates the position of the specified
546      *         coordinates with respect to this {@code Line2D}
547      * @see #relativeCCW(doubledoubledoubledoubledoubledouble)
548      * @since 1.2
549      */

550     public int relativeCCW(double px, double py) {
551         return relativeCCW(getX1(), getY1(), getX2(), getY2(), px, py);
552     }
553
554     /**
555      * Returns an indicator of where the specified {@code Point2D}
556      * lies with respect to this line segment.
557      * See the method comments of
558      * {@link #relativeCCW(doubledoubledoubledoubledoubledouble)}
559      * to interpret the return value.
560      * @param p the specified {@code Point2D} to be compared
561      *          with this {@code Line2D}
562      * @return an integer that indicates the position of the specified
563      *         {@code Point2D} with respect to this {@code Line2D}
564      * @see #relativeCCW(doubledoubledoubledoubledoubledouble)
565      * @since 1.2
566      */

567     public int relativeCCW(Point2D p) {
568         return relativeCCW(getX1(), getY1(), getX2(), getY2(),
569                            p.getX(), p.getY());
570     }
571
572     /**
573      * Tests if the line segment from {@code (x1,y1)} to
574      * {@code (x2,y2)} intersects the line segment from {@code (x3,y3)}
575      * to {@code (x4,y4)}.
576      *
577      * @param x1 the X coordinate of the start point of the first
578      *           specified line segment
579      * @param y1 the Y coordinate of the start point of the first
580      *           specified line segment
581      * @param x2 the X coordinate of the end point of the first
582      *           specified line segment
583      * @param y2 the Y coordinate of the end point of the first
584      *           specified line segment
585      * @param x3 the X coordinate of the start point of the second
586      *           specified line segment
587      * @param y3 the Y coordinate of the start point of the second
588      *           specified line segment
589      * @param x4 the X coordinate of the end point of the second
590      *           specified line segment
591      * @param y4 the Y coordinate of the end point of the second
592      *           specified line segment
593      * @return {@code trueif the first specified line segment
594      *                  and the second specified line segment intersect
595      *                  each other; {@code false} otherwise.
596      * @since 1.2
597      */

598     public static boolean linesIntersect(double x1, double y1,
599                                          double x2, double y2,
600                                          double x3, double y3,
601                                          double x4, double y4)
602     {
603         return ((relativeCCW(x1, y1, x2, y2, x3, y3) *
604                  relativeCCW(x1, y1, x2, y2, x4, y4) <= 0)
605                 && (relativeCCW(x3, y3, x4, y4, x1, y1) *
606                     relativeCCW(x3, y3, x4, y4, x2, y2) <= 0));
607     }
608
609     /**
610      * Tests if the line segment from {@code (x1,y1)} to
611      * {@code (x2,y2)} intersects this line segment.
612      *
613      * @param x1 the X coordinate of the start point of the
614      *           specified line segment
615      * @param y1 the Y coordinate of the start point of the
616      *           specified line segment
617      * @param x2 the X coordinate of the end point of the
618      *           specified line segment
619      * @param y2 the Y coordinate of the end point of the
620      *           specified line segment
621      * @return {@code trueif this line segment and the specified line segment
622      *                  intersect each other; {@code false} otherwise.
623      * @since 1.2
624      */

625     public boolean intersectsLine(double x1, double y1, double x2, double y2) {
626         return linesIntersect(x1, y1, x2, y2,
627                               getX1(), getY1(), getX2(), getY2());
628     }
629
630     /**
631      * Tests if the specified line segment intersects this line segment.
632      * @param l the specified {@code Line2D}
633      * @return {@code trueif this line segment and the specified line
634      *                  segment intersect each other;
635      *                  {@code false} otherwise.
636      * @since 1.2
637      */

638     public boolean intersectsLine(Line2D l) {
639         return linesIntersect(l.getX1(), l.getY1(), l.getX2(), l.getY2(),
640                               getX1(), getY1(), getX2(), getY2());
641     }
642
643     /**
644      * Returns the square of the distance from a point to a line segment.
645      * The distance measured is the distance between the specified
646      * point and the closest point between the specified end points.
647      * If the specified point intersects the line segment in between the
648      * end points, this method returns 0.0.
649      *
650      * @param x1 the X coordinate of the start point of the
651      *           specified line segment
652      * @param y1 the Y coordinate of the start point of the
653      *           specified line segment
654      * @param x2 the X coordinate of the end point of the
655      *           specified line segment
656      * @param y2 the Y coordinate of the end point of the
657      *           specified line segment
658      * @param px the X coordinate of the specified point being
659      *           measured against the specified line segment
660      * @param py the Y coordinate of the specified point being
661      *           measured against the specified line segment
662      * @return a double value that is the square of the distance from the
663      *                  specified point to the specified line segment.
664      * @see #ptLineDistSq(doubledoubledoubledoubledoubledouble)
665      * @since 1.2
666      */

667     public static double ptSegDistSq(double x1, double y1,
668                                      double x2, double y2,
669                                      double px, double py)
670     {
671         // Adjust vectors relative to x1,y1
672         // x2,y2 becomes relative vector from x1,y1 to end of segment
673         x2 -= x1;
674         y2 -= y1;
675         // px,py becomes relative vector from x1,y1 to test point
676         px -= x1;
677         py -= y1;
678         double dotprod = px * x2 + py * y2;
679         double projlenSq;
680         if (dotprod <= 0.0) {
681             // px,py is on the side of x1,y1 away from x2,y2
682             // distance to segment is length of px,py vector
683             // "length of its (clipped) projection" is now 0.0
684             projlenSq = 0.0;
685         } else {
686             // switch to backwards vectors relative to x2,y2
687             // x2,y2 are already the negative of x1,y1=>x2,y2
688             // to get px,py to be the negative of px,py=>x2,y2
689             // the dot product of two negated vectors is the same
690             // as the dot product of the two normal vectors
691             px = x2 - px;
692             py = y2 - py;
693             dotprod = px * x2 + py * y2;
694             if (dotprod <= 0.0) {
695                 // px,py is on the side of x2,y2 away from x1,y1
696                 // distance to segment is length of (backwards) px,py vector
697                 // "length of its (clipped) projection" is now 0.0
698                 projlenSq = 0.0;
699             } else {
700                 // px,py is between x1,y1 and x2,y2
701                 // dotprod is the length of the px,py vector
702                 // projected on the x2,y2=>x1,y1 vector times the
703                 // length of the x2,y2=>x1,y1 vector
704                 projlenSq = dotprod * dotprod / (x2 * x2 + y2 * y2);
705             }
706         }
707         // Distance to line is now the length of the relative point
708         // vector minus the length of its projection onto the line
709         // (which is zero if the projection falls outside the range
710         //  of the line segment).
711         double lenSq = px * px + py * py - projlenSq;
712         if (lenSq < 0) {
713             lenSq = 0;
714         }
715         return lenSq;
716     }
717
718     /**
719      * Returns the distance from a point to a line segment.
720      * The distance measured is the distance between the specified
721      * point and the closest point between the specified end points.
722      * If the specified point intersects the line segment in between the
723      * end points, this method returns 0.0.
724      *
725      * @param x1 the X coordinate of the start point of the
726      *           specified line segment
727      * @param y1 the Y coordinate of the start point of the
728      *           specified line segment
729      * @param x2 the X coordinate of the end point of the
730      *           specified line segment
731      * @param y2 the Y coordinate of the end point of the
732      *           specified line segment
733      * @param px the X coordinate of the specified point being
734      *           measured against the specified line segment
735      * @param py the Y coordinate of the specified point being
736      *           measured against the specified line segment
737      * @return a double value that is the distance from the specified point
738      *                          to the specified line segment.
739      * @see #ptLineDist(doubledoubledoubledoubledoubledouble)
740      * @since 1.2
741      */

742     public static double ptSegDist(double x1, double y1,
743                                    double x2, double y2,
744                                    double px, double py)
745     {
746         return Math.sqrt(ptSegDistSq(x1, y1, x2, y2, px, py));
747     }
748
749     /**
750      * Returns the square of the distance from a point to this line segment.
751      * The distance measured is the distance between the specified
752      * point and the closest point between the current line's end points.
753      * If the specified point intersects the line segment in between the
754      * end points, this method returns 0.0.
755      *
756      * @param px the X coordinate of the specified point being
757      *           measured against this line segment
758      * @param py the Y coordinate of the specified point being
759      *           measured against this line segment
760      * @return a double value that is the square of the distance from the
761      *                  specified point to the current line segment.
762      * @see #ptLineDistSq(doubledouble)
763      * @since 1.2
764      */

765     public double ptSegDistSq(double px, double py) {
766         return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), px, py);
767     }
768
769     /**
770      * Returns the square of the distance from a {@code Point2D} to
771      * this line segment.
772      * The distance measured is the distance between the specified
773      * point and the closest point between the current line's end points.
774      * If the specified point intersects the line segment in between the
775      * end points, this method returns 0.0.
776      * @param pt the specified {@code Point2D} being measured against
777      *           this line segment.
778      * @return a double value that is the square of the distance from the
779      *                  specified {@code Point2D} to the current
780      *                  line segment.
781      * @see #ptLineDistSq(Point2D)
782      * @since 1.2
783      */

784     public double ptSegDistSq(Point2D pt) {
785         return ptSegDistSq(getX1(), getY1(), getX2(), getY2(),
786                            pt.getX(), pt.getY());
787     }
788
789     /**
790      * Returns the distance from a point to this line segment.
791      * The distance measured is the distance between the specified
792      * point and the closest point between the current line's end points.
793      * If the specified point intersects the line segment in between the
794      * end points, this method returns 0.0.
795      *
796      * @param px the X coordinate of the specified point being
797      *           measured against this line segment
798      * @param py the Y coordinate of the specified point being
799      *           measured against this line segment
800      * @return a double value that is the distance from the specified
801      *                  point to the current line segment.
802      * @see #ptLineDist(doubledouble)
803      * @since 1.2
804      */

805     public double ptSegDist(double px, double py) {
806         return ptSegDist(getX1(), getY1(), getX2(), getY2(), px, py);
807     }
808
809     /**
810      * Returns the distance from a {@code Point2D} to this line
811      * segment.
812      * The distance measured is the distance between the specified
813      * point and the closest point between the current line's end points.
814      * If the specified point intersects the line segment in between the
815      * end points, this method returns 0.0.
816      * @param pt the specified {@code Point2D} being measured
817      *          against this line segment
818      * @return a double value that is the distance from the specified
819      *                          {@code Point2D} to the current line
820      *                          segment.
821      * @see #ptLineDist(Point2D)
822      * @since 1.2
823      */

824     public double ptSegDist(Point2D pt) {
825         return ptSegDist(getX1(), getY1(), getX2(), getY2(),
826                          pt.getX(), pt.getY());
827     }
828
829     /**
830      * Returns the square of the distance from a point to a line.
831      * The distance measured is the distance between the specified
832      * point and the closest point on the infinitely-extended line
833      * defined by the specified coordinates.  If the specified point
834      * intersects the line, this method returns 0.0.
835      *
836      * @param x1 the X coordinate of the start point of the specified line
837      * @param y1 the Y coordinate of the start point of the specified line
838      * @param x2 the X coordinate of the end point of the specified line
839      * @param y2 the Y coordinate of the end point of the specified line
840      * @param px the X coordinate of the specified point being
841      *           measured against the specified line
842      * @param py the Y coordinate of the specified point being
843      *           measured against the specified line
844      * @return a double value that is the square of the distance from the
845      *                  specified point to the specified line.
846      * @see #ptSegDistSq(doubledoubledoubledoubledoubledouble)
847      * @since 1.2
848      */

849     public static double ptLineDistSq(double x1, double y1,
850                                       double x2, double y2,
851                                       double px, double py)
852     {
853         // Adjust vectors relative to x1,y1
854         // x2,y2 becomes relative vector from x1,y1 to end of segment
855         x2 -= x1;
856         y2 -= y1;
857         // px,py becomes relative vector from x1,y1 to test point
858         px -= x1;
859         py -= y1;
860         double dotprod = px * x2 + py * y2;
861         // dotprod is the length of the px,py vector
862         // projected on the x1,y1=>x2,y2 vector times the
863         // length of the x1,y1=>x2,y2 vector
864         double projlenSq = dotprod * dotprod / (x2 * x2 + y2 * y2);
865         // Distance to line is now the length of the relative point
866         // vector minus the length of its projection onto the line
867         double lenSq = px * px + py * py - projlenSq;
868         if (lenSq < 0) {
869             lenSq = 0;
870         }
871         return lenSq;
872     }
873
874     /**
875      * Returns the distance from a point to a line.
876      * The distance measured is the distance between the specified
877      * point and the closest point on the infinitely-extended line
878      * defined by the specified coordinates.  If the specified point
879      * intersects the line, this method returns 0.0.
880      *
881      * @param x1 the X coordinate of the start point of the specified line
882      * @param y1 the Y coordinate of the start point of the specified line
883      * @param x2 the X coordinate of the end point of the specified line
884      * @param y2 the Y coordinate of the end point of the specified line
885      * @param px the X coordinate of the specified point being
886      *           measured against the specified line
887      * @param py the Y coordinate of the specified point being
888      *           measured against the specified line
889      * @return a double value that is the distance from the specified
890      *                   point to the specified line.
891      * @see #ptSegDist(doubledoubledoubledoubledoubledouble)
892      * @since 1.2
893      */

894     public static double ptLineDist(double x1, double y1,
895                                     double x2, double y2,
896                                     double px, double py)
897     {
898         return Math.sqrt(ptLineDistSq(x1, y1, x2, y2, px, py));
899     }
900
901     /**
902      * Returns the square of the distance from a point to this line.
903      * The distance measured is the distance between the specified
904      * point and the closest point on the infinitely-extended line
905      * defined by this {@code Line2D}.  If the specified point
906      * intersects the line, this method returns 0.0.
907      *
908      * @param px the X coordinate of the specified point being
909      *           measured against this line
910      * @param py the Y coordinate of the specified point being
911      *           measured against this line
912      * @return a double value that is the square of the distance from a
913      *                  specified point to the current line.
914      * @see #ptSegDistSq(doubledouble)
915      * @since 1.2
916      */

917     public double ptLineDistSq(double px, double py) {
918         return ptLineDistSq(getX1(), getY1(), getX2(), getY2(), px, py);
919     }
920
921     /**
922      * Returns the square of the distance from a specified
923      * {@code Point2D} to this line.
924      * The distance measured is the distance between the specified
925      * point and the closest point on the infinitely-extended line
926      * defined by this {@code Line2D}.  If the specified point
927      * intersects the line, this method returns 0.0.
928      * @param pt the specified {@code Point2D} being measured
929      *           against this line
930      * @return a double value that is the square of the distance from a
931      *                  specified {@code Point2D} to the current
932      *                  line.
933      * @see #ptSegDistSq(Point2D)
934      * @since 1.2
935      */

936     public double ptLineDistSq(Point2D pt) {
937         return ptLineDistSq(getX1(), getY1(), getX2(), getY2(),
938                             pt.getX(), pt.getY());
939     }
940
941     /**
942      * Returns the distance from a point to this line.
943      * The distance measured is the distance between the specified
944      * point and the closest point on the infinitely-extended line
945      * defined by this {@code Line2D}.  If the specified point
946      * intersects the line, this method returns 0.0.
947      *
948      * @param px the X coordinate of the specified point being
949      *           measured against this line
950      * @param py the Y coordinate of the specified point being
951      *           measured against this line
952      * @return a double value that is the distance from a specified point
953      *                  to the current line.
954      * @see #ptSegDist(doubledouble)
955      * @since 1.2
956      */

957     public double ptLineDist(double px, double py) {
958         return ptLineDist(getX1(), getY1(), getX2(), getY2(), px, py);
959     }
960
961     /**
962      * Returns the distance from a {@code Point2D} to this line.
963      * The distance measured is the distance between the specified
964      * point and the closest point on the infinitely-extended line
965      * defined by this {@code Line2D}.  If the specified point
966      * intersects the line, this method returns 0.0.
967      * @param pt the specified {@code Point2D} being measured
968      * @return a double value that is the distance from a specified
969      *                  {@code Point2D} to the current line.
970      * @see #ptSegDist(Point2D)
971      * @since 1.2
972      */

973     public double ptLineDist(Point2D pt) {
974         return ptLineDist(getX1(), getY1(), getX2(), getY2(),
975                          pt.getX(), pt.getY());
976     }
977
978     /**
979      * Tests if a specified coordinate is inside the boundary of this
980      * {@code Line2D}.  This method is required to implement the
981      * {@link Shape} interface, but in the case of {@code Line2D}
982      * objects it always returns {@code false} since a line contains
983      * no area.
984      * @param x the X coordinate of the specified point to be tested
985      * @param y the Y coordinate of the specified point to be tested
986      * @return {@code false} because a {@code Line2D} contains
987      * no area.
988      * @since 1.2
989      */

990     public boolean contains(double x, double y) {
991         return false;
992     }
993
994     /**
995      * Tests if a given {@code Point2D} is inside the boundary of
996      * this {@code Line2D}.
997      * This method is required to implement the {@link Shape} interface,
998      * but in the case of {@code Line2D} objects it always returns
999      * {@code false} since a line contains no area.
1000      * @param p the specified {@code Point2D} to be tested
1001      * @return {@code false} because a {@code Line2D} contains
1002      * no area.
1003      * @since 1.2
1004      */

1005     public boolean contains(Point2D p) {
1006         return false;
1007     }
1008
1009     /**
1010      * {@inheritDoc}
1011      * @since 1.2
1012      */

1013     public boolean intersects(double x, double y, double w, double h) {
1014         return intersects(new Rectangle2D.Double(x, y, w, h));
1015     }
1016
1017     /**
1018      * {@inheritDoc}
1019      * @since 1.2
1020      */

1021     public boolean intersects(Rectangle2D r) {
1022         return r.intersectsLine(getX1(), getY1(), getX2(), getY2());
1023     }
1024
1025     /**
1026      * Tests if the interior of this {@code Line2D} entirely contains
1027      * the specified set of rectangular coordinates.
1028      * This method is required to implement the {@code Shape} interface,
1029      * but in the case of {@code Line2D} objects it always returns
1030      * false since a line contains no area.
1031      * @param x the X coordinate of the upper-left corner of the
1032      *          specified rectangular area
1033      * @param y the Y coordinate of the upper-left corner of the
1034      *          specified rectangular area
1035      * @param w the width of the specified rectangular area
1036      * @param h the height of the specified rectangular area
1037      * @return {@code false} because a {@code Line2D} contains
1038      * no area.
1039      * @since 1.2
1040      */

1041     public boolean contains(double x, double y, double w, double h) {
1042         return false;
1043     }
1044
1045     /**
1046      * Tests if the interior of this {@code Line2D} entirely contains
1047      * the specified {@code Rectangle2D}.
1048      * This method is required to implement the {@code Shape} interface,
1049      * but in the case of {@code Line2D} objects it always returns
1050      * {@code false} since a line contains no area.
1051      * @param r the specified {@code Rectangle2D} to be tested
1052      * @return {@code false} because a {@code Line2D} contains
1053      * no area.
1054      * @since 1.2
1055      */

1056     public boolean contains(Rectangle2D r) {
1057         return false;
1058     }
1059
1060     /**
1061      * {@inheritDoc}
1062      * @since 1.2
1063      */

1064     public Rectangle getBounds() {
1065         return getBounds2D().getBounds();
1066     }
1067
1068     /**
1069      * Returns an iteration object that defines the boundary of this
1070      * {@code Line2D}.
1071      * The iterator for this class is not multi-threaded safe,
1072      * which means that this {@code Line2D} class does not
1073      * guarantee that modifications to the geometry of this
1074      * {@code Line2D} object do not affect any iterations of that
1075      * geometry that are already in process.
1076      * @param at the specified {@link AffineTransform}
1077      * @return a {@link PathIterator} that defines the boundary of this
1078      *          {@code Line2D}.
1079      * @since 1.2
1080      */

1081     public PathIterator getPathIterator(AffineTransform at) {
1082         return new LineIterator(this, at);
1083     }
1084
1085     /**
1086      * Returns an iteration object that defines the boundary of this
1087      * flattened {@code Line2D}.
1088      * The iterator for this class is not multi-threaded safe,
1089      * which means that this {@code Line2D} class does not
1090      * guarantee that modifications to the geometry of this
1091      * {@code Line2D} object do not affect any iterations of that
1092      * geometry that are already in process.
1093      * @param at the specified {@code AffineTransform}
1094      * @param flatness the maximum amount that the control points for a
1095      *          given curve can vary from colinear before a subdivided
1096      *          curve is replaced by a straight line connecting the
1097      *          end points.  Since a {@code Line2D} object is
1098      *          always flat, this parameter is ignored.
1099      * @return a {@code PathIterator} that defines the boundary of the
1100      *                  flattened {@code Line2D}
1101      * @since 1.2
1102      */

1103     public PathIterator getPathIterator(AffineTransform at, double flatness) {
1104         return new LineIterator(this, at);
1105     }
1106
1107     /**
1108      * Creates a new object of the same class as this object.
1109      *
1110      * @return     a clone of this instance.
1111      * @exception  OutOfMemoryError            if there is not enough memory.
1112      * @see        java.lang.Cloneable
1113      * @since      1.2
1114      */

1115     public Object clone() {
1116         try {
1117             return super.clone();
1118         } catch (CloneNotSupportedException e) {
1119             // this shouldn't happen, since we are Cloneable
1120             throw new InternalError(e);
1121         }
1122     }
1123 }
1124