View Javadoc
1   /*
2    * Copyright (c) 1997, 2013, 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</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://docs.oracle.com/javase/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   */
49  public 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) &rarr; (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) &rarr; (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 collinearity
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 {@code <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(e);
1126         }
1127     }
1128 }