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 }