KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > awt > geom > Line2D


1 /*
2  * @(#)Line2D.java 1.28 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.awt.geom;
9
10 import java.awt.Shape JavaDoc;
11 import java.awt.Rectangle JavaDoc;
12
13 /**
14  * This <code>Line2D</code> represents a line segment in (x,&nbsp;y)
15  * coordinate space. This class, like all of the Java 2D API, uses a
16  * default coordinate system called <i>user space</i> in which the y-axis
17  * values increase downward and x-axis values increase to the right. For
18  * more information on the user space coordinate system, see the
19  * <a HREF="http://java.sun.com/j2se/1.3/docs/guide/2d/spec/j2d-intro.fm2.html#61857">
20  * Coordinate Systems</a> section of the Java 2D Programmer's Guide.
21  * <p>
22  * This class is only the abstract superclass for all objects that
23  * store a 2D line segment.
24  * The actual storage representation of the coordinates is left to
25  * the subclass.
26  *
27  * @version 1.28, 12/19/03
28  * @author Jim Graham
29  */

30 public abstract class Line2D implements Shape JavaDoc, Cloneable JavaDoc {
31     /**
32      * A line segment specified with float coordinates.
33      */

34     public static class Float extends Line2D JavaDoc {
35     /**
36      * The X coordinate of the start point of the line segment.
37      */

38     public float x1;
39
40     /**
41      * The Y coordinate of the start point of the line segment.
42      */

43     public float y1;
44
45     /**
46      * The X coordinate of the end point of the line segment.
47      */

48     public float x2;
49
50     /**
51      * The Y coordinate of the end point of the line segment.
52      */

53     public float y2;
54
55     /**
56      * Constructs and initializes a Line with coordinates (0, 0) -> (0, 0).
57      */

58     public Float() {
59     }
60
61     /**
62      * Constructs and initializes a Line from the specified coordinates.
63      * @param X1,&nbsp;Y1 the first specified coordinates
64      * @param X2,&nbsp;Y2 the second specified coordinates
65      */

66     public Float(float X1, float Y1, float X2, float Y2) {
67         setLine(X1, Y1, X2, Y2);
68     }
69
70     /**
71      * Constructs and initializes a <code>Line2D</code> from the
72      * specified {@link Point2D} objects.
73      * @param p1 the first specified <code>Point2D</code>
74      * @param p2 the second specified <code>Point2D</code>
75      */

76     public Float(Point2D JavaDoc p1, Point2D JavaDoc p2) {
77         setLine(p1, p2);
78     }
79
80     /**
81      * Returns the X coordinate of the start point in double precision.
82      * @return the x coordinate of this <code>Line2D</code> object's
83      * starting point in double precision.
84      */

85     public double getX1() {
86         return (double) x1;
87     }
88
89     /**
90      * Returns the Y coordinate of the start point in double precision.
91          * @return the x coordinate of this <code>Line2D</code> object's
92      * starting point in double precision.
93      */

94     public double getY1() {
95         return (double) y1;
96     }
97
98     /**
99      * Returns the start point.
100      * @return the starting <code>Point2D</code> object of this
101      * <code>Line2D</code>.
102      */

103     public Point2D JavaDoc getP1() {
104         return new Point2D.Float JavaDoc(x1, y1);
105     }
106
107     /**
108      * Returns the X coordinate of the end point in double precision.
109          * @return the x coordinate of this <code>Line2D</code> object's
110      * ending point in double precision.
111      */

112     public double getX2() {
113         return (double) x2;
114     }
115
116     /**
117      * Returns the Y coordinate of the end point in double precision.
118          * @return the Y coordinate of this <code>Line2D</code> object's
119      * ending point in double precision.
120      */

121
122     public double getY2() {
123         return (double) y2;
124     }
125
126     /**
127      * Returns the end point.
128          * @return the ending <code>Point2D</code> object of this
129          * <code>Line2D</code>.
130      */

131     public Point2D JavaDoc getP2() {
132         return new Point2D.Float JavaDoc(x2, y2);
133     }
134
135     /**
136      * Sets the location of the endpoints of this <code>Line2D</code>
137      * to the specified double coordinates.
138      * @param X1,&nbsp;Y1 the first specified coordinate
139      * @param X2,&nbsp;Y2 the second specified coordinate
140      */

141     public void setLine(double X1, double Y1, double X2, double Y2) {
142         this.x1 = (float) X1;
143         this.y1 = (float) Y1;
144         this.x2 = (float) X2;
145         this.y2 = (float) Y2;
146     }
147
148     /**
149      * Sets the location of the endpoints of this <code>Line2D</code>
150      * to the specified float coordinates.
151      * @param X1,&nbsp;Y1 the first specified coordinate
152      * @param X2,&nbsp;Y2 the second specified coordinate
153      */

154     public void setLine(float X1, float Y1, float X2, float Y2) {
155         this.x1 = X1;
156         this.y1 = Y1;
157         this.x2 = X2;
158         this.y2 = Y2;
159     }
160
161     /**
162      * Returns the high-precision bounding box of this
163      * <code>Line2D</code>.
164      * @return a {@link Rectangle2D} that is the high-precision
165      * bounding box of this <code>Line2D</code>.
166      */

167     public Rectangle2D JavaDoc getBounds2D() {
168         float x, y, w, h;
169         if (x1 < x2) {
170         x = x1;
171         w = x2 - x1;
172         } else {
173         x = x2;
174         w = x1 - x2;
175         }
176         if (y1 < y2) {
177         y = y1;
178         h = y2 - y1;
179         } else {
180         y = y2;
181         h = y1 - y2;
182         }
183         return new Rectangle2D.Float JavaDoc(x, y, w, h);
184     }
185     }
186
187     /**
188      * A line segment specified with double coordinates.
189      */

190     public static class Double extends Line2D JavaDoc {
191     /**
192      * The X coordinate of the start point of the line segment.
193      */

194     public double x1;
195
196     /**
197      * The Y coordinate of the start point of the line segment.
198      */

199     public double y1;
200
201     /**
202      * The X coordinate of the end point of the line segment.
203      */

204     public double x2;
205
206     /**
207      * The Y coordinate of the end point of the line segment.
208      */

209     public double y2;
210
211     /**
212      * Constructs and initializes a Line with coordinates (0, 0) -> (0, 0).
213      */

214     public Double() {
215     }
216
217     /**
218      * Constructs and initializes a <code>Line2D</code> from the
219          * specified coordinates.
220      * @param X1,&nbsp;Y1 the first specified coordinate
221      * @param X2,&nbsp;Y2 the second specified coordinate
222      */

223     public Double(double X1, double Y1, double X2, double Y2) {
224         setLine(X1, Y1, X2, Y2);
225     }
226
227     /**
228      * Constructs and initializes a <code>Line2D</code> from the
229      * specified <code>Point2D</code> objects.
230      * @param p1,&nbsp;p2 the specified <code>Point2D</code> objects
231      */

232     public Double(Point2D JavaDoc p1, Point2D JavaDoc p2) {
233         setLine(p1, p2);
234     }
235
236     /**
237      * Returns the X coordinate of the start point in double precision.
238          * @return the X coordinate of this <code>Line2D</code> object's
239      * starting point.
240      */

241     public double getX1() {
242         return x1;
243     }
244
245     /**
246      * Returns the Y coordinate of the start point in double precision.
247          * @return the X coordinate of this <code>Line2D</code> object's
248      * starting point.
249      */

250     public double getY1() {
251         return y1;
252     }
253
254     /**
255      * Returns the starting <code>Point2D</code> of this
256      * <code>Line2D</code>.
257      * @return the starting <code>Point2D</code> of this
258      * <code>Line2D</code>
259      */

260     public Point2D JavaDoc getP1() {
261         return new Point2D.Double JavaDoc(x1, y1);
262     }
263
264     /**
265      * Returns the X coordinate of the end point in double precision.
266          * @return the X coordinate of this <code>Line2D</code> object's
267      * ending point.
268      */

269     public double getX2() {
270         return x2;
271     }
272
273     /**
274      * Returns the Y coordinate of the end point in double precision.
275          * @return the Y coordinate of this <code>Line2D</code> object's
276      * starting point.
277      */

278     public double getY2() {
279         return y2;
280     }
281
282     /**
283      * Returns the end <code>Point2D</code> of this
284      * <code>Line2D</code>.
285      * @return the ending <code>Point2D</code> of this
286      * <code>Line2D</code>.
287      */

288     public Point2D JavaDoc getP2() {
289         return new Point2D.Double JavaDoc(x2, y2);
290     }
291
292     /**
293      * Sets the location of the endpoints of this <code>Line2D</code>
294      * to the specified double coordinates.
295      * @param X1,&nbsp;Y1 the first specified coordinate
296      * @param X2,&nbsp;Y2 the second specified coordinate
297      */

298     public void setLine(double X1, double Y1, double X2, double Y2) {
299         this.x1 = X1;
300         this.y1 = Y1;
301         this.x2 = X2;
302         this.y2 = Y2;
303     }
304
305     /**
306      * Returns the high-precision bounding box of this
307      * <code>Line2D</code>.
308      * @return a <code>Rectangle2D</code> that is the high-precision
309      * bounding box of this <code>Line2D</code>.
310      */

311     public Rectangle2D JavaDoc getBounds2D() {
312         double x, y, w, h;
313         if (x1 < x2) {
314         x = x1;
315         w = x2 - x1;
316         } else {
317         x = x2;
318         w = x1 - x2;
319         }
320         if (y1 < y2) {
321         y = y1;
322         h = y2 - y1;
323         } else {
324         y = y2;
325         h = y1 - y2;
326         }
327         return new Rectangle2D.Double JavaDoc(x, y, w, h);
328     }
329     }
330
331     /**
332      * This is an abstract class that cannot be instantiated directly.
333      * Type-specific implementation subclasses are available for
334      * instantiation and provide a number of formats for storing
335      * the information necessary to satisfy the various accessory
336      * methods below.
337      *
338      * @see java.awt.geom.Line2D.Float
339      * @see java.awt.geom.Line2D.Double
340      */

341     protected Line2D() {
342     }
343
344     /**
345      * Returns the X coordinate of the start point in double precision.
346      * @return the X coordinate of this <code>Line2D</code> object's
347      * starting point.
348      */

349     public abstract double getX1();
350
351     /**
352      * Returns the Y coordinate of the start point in double precision.
353      * @return the Y coordinate of this <code>Line2D</code> object's
354      * starting point.
355      */

356     public abstract double getY1();
357
358     /**
359      * Returns the starting <code>Point2D</code> of this
360      * <code>Line2D</code>.
361      * @return the starting <code>Point2D</code> of this
362      * <code>Line2D</code>.
363      */

364     public abstract Point2D JavaDoc getP1();
365
366     /**
367      * Returns the X coordinate of the end point in double precision.
368      * @return the X coordinate of this <code>Line2D</code> object's
369      * starting point.
370      */

371     public abstract double getX2();
372
373     /**
374      * Returns the Y coordinate of the end point in double precision.
375      * @return the Y coordinate of this <code>Line2D</code> object's
376      * starting point.
377      */

378     public abstract double getY2();
379
380     /**
381      * Returns the end <code>Point2D</code> of this <code>Line2D</code>.
382      * @return a <code>Point2D</code> that is the endpoint of this
383      * <code>Line2D</code>.
384      */

385     public abstract Point2D JavaDoc getP2();
386
387     /**
388      * Sets the location of the endpoints of this <code>Line2D</code> to
389      * the specified double coordinates.
390      * @param X1,&nbsp;Y1 the first specified coordinate
391      * @param X2,&nbsp;Y2 the second specified coordinate
392      */

393     public abstract void setLine(double X1, double Y1, double X2, double Y2);
394
395     /**
396      * Sets the location of the endpoints of this <code>Line2D</code> to
397      * the specified <code>Point2D</code> coordinates.
398      * @param p1,&nbsp;p2 the specified <code>Point2D</code> objects
399      */

400     public void setLine(Point2D JavaDoc p1, Point2D JavaDoc p2) {
401     setLine(p1.getX(), p1.getY(), p2.getX(), p2.getY());
402     }
403
404     /**
405      * Sets the location of the endpoints of this <code>Line2D</code> to
406      * the same as those endpoints of the specified <code>Line2D</code>.
407      * @param l the specified <code>Line2D</code>
408      */

409     public void setLine(Line2D JavaDoc l) {
410     setLine(l.getX1(), l.getY1(), l.getX2(), l.getY2());
411     }
412
413     /**
414      * Returns an indicator of where the specified point
415      * (PX,&nbsp;PY) lies with respect to the line segment from
416      * (X1,&nbsp;Y1) to (X2,&nbsp;Y2).
417      * The return value can be either 1, -1, or 0 and indicates
418      * in which direction the specified line must pivot around its
419      * first endpoint, (X1,&nbsp;Y1), in order to point at the
420      * specified point (PX,&nbsp;PY).
421      * <p>A return value of 1 indicates that the line segment must
422      * turn in the direction that takes the positive X axis towards
423      * the negative Y axis. In the default coordinate system used by
424      * Java 2D, this direction is counterclockwise.
425      * <p>A return value of -1 indicates that the line segment must
426      * turn in the direction that takes the positive X axis towards
427      * the positive Y axis. In the default coordinate system, this
428      * direction is clockwise.
429      * <p>A return value of 0 indicates that the point lies
430      * exactly on the line segment. Note that an indicator value
431      * of 0 is rare and not useful for determining colinearity
432      * because of floating point rounding issues.
433      * <p>If the point is colinear with the line segment, but
434      * not between the endpoints, then the value will be -1 if the point
435      * lies "beyond (X1,&nbsp;Y1)" or 1 if the point lies
436      * "beyond (X2,&nbsp;Y2)".
437      * @param X1,&nbsp;Y1 the coordinates of the beginning of the
438      * specified line segment
439      * @param X2,&nbsp;Y2 the coordinates of the end of the specified
440      * line segment
441      * @param PX,&nbsp;PY the coordinates of the specified point to be
442      * compared with the specified line segment
443      * @return an integer that indicates the position of the third specified
444      * coordinates with respect to the line segment formed
445      * by the first two specified coordinates.
446      */

447     public static int relativeCCW(double X1, double Y1,
448                   double X2, double Y2,
449                   double PX, double PY) {
450     X2 -= X1;
451     Y2 -= Y1;
452     PX -= X1;
453     PY -= Y1;
454     double ccw = PX * Y2 - PY * X2;
455     if (ccw == 0.0) {
456         // The point is colinear, classify based on which side of
457
// the segment the point falls on. We can calculate a
458
// relative value using the projection of PX,PY onto the
459
// segment - a negative value indicates the point projects
460
// outside of the segment in the direction of the particular
461
// endpoint used as the origin for the projection.
462
ccw = PX * X2 + PY * Y2;
463         if (ccw > 0.0) {
464         // Reverse the projection to be relative to the original X2,Y2
465
// X2 and Y2 are simply negated.
466
// PX and PY need to have (X2 - X1) or (Y2 - Y1) subtracted
467
// from them (based on the original values)
468
// Since we really want to get a positive answer when the
469
// point is "beyond (X2,Y2)", then we want to calculate
470
// the inverse anyway - thus we leave X2 & Y2 negated.
471
PX -= X2;
472         PY -= Y2;
473         ccw = PX * X2 + PY * Y2;
474         if (ccw < 0.0) {
475             ccw = 0.0;
476         }
477         }
478     }
479     return (ccw < 0.0) ? -1 : ((ccw > 0.0) ? 1 : 0);
480     }
481
482     /**
483      * Returns an indicator of where the specified point
484      * (PX,&nbsp;PY) lies with respect to this line segment.
485      * See the method comments of
486      * {@link #relativeCCW(double, double, double, double, double, double)}
487      * to interpret the return value.
488      * @param PX,&nbsp;PY the coordinates of the specified point
489      * to be compared with the current line segment
490      * @return an integer that indicates the position of the specified
491      * coordinates with respect to the current line segment.
492      * @see #relativeCCW(double, double, double, double, double, double)
493      */

494     public int relativeCCW(double PX, double PY) {
495     return relativeCCW(getX1(), getY1(), getX2(), getY2(), PX, PY);
496     }
497
498     /**
499      * Returns an indicator of where the specified <code>Point2D</code>
500      * lies with respect to this line segment.
501      * See the method comments of
502      * {@link #relativeCCW(double, double, double, double, double, double)}
503      * to interpret the return value.
504      * @param p the specified <code>Point2D</code> to be compared
505      * with the current line segment
506      * @return an integer that indicates the position of the
507      * <code>Point2D</code> with respect to the current
508      * line segment.
509      * @see #relativeCCW(double, double, double, double, double, double)
510      */

511     public int relativeCCW(Point2D JavaDoc p) {
512     return relativeCCW(getX1(), getY1(), getX2(), getY2(),
513                p.getX(), p.getY());
514     }
515
516     /**
517      * Tests if the line segment from (X1,&nbsp;Y1) to
518      * (X2,&nbsp;Y2) intersects the line segment from (X3,&nbsp;Y3)
519      * to (X4,&nbsp;Y4).
520      * @param X1,&nbsp;Y1 the coordinates of the beginning of the first
521      * specified line segment
522      * @param X2,&nbsp;Y2 the coordinates of the end of the first
523      * specified line segment
524      * @param X3,&nbsp;Y3 the coordinates of the beginning of the second
525      * specified line segment
526      * @param X4,&nbsp;Y4 the coordinates of the end of the second
527      * specified line segment
528      * @return <code>true</code> if the first specified line segment
529      * and the second specified line segment intersect
530      * each other; <code>false</code> otherwise.
531      */

532     public static boolean linesIntersect(double X1, double Y1,
533                      double X2, double Y2,
534                      double X3, double Y3,
535                      double X4, double Y4) {
536     return ((relativeCCW(X1, Y1, X2, Y2, X3, Y3) *
537          relativeCCW(X1, Y1, X2, Y2, X4, Y4) <= 0)
538         && (relativeCCW(X3, Y3, X4, Y4, X1, Y1) *
539             relativeCCW(X3, Y3, X4, Y4, X2, Y2) <= 0));
540     }
541
542     /**
543      * Tests if the line segment from (X1,&nbsp;Y1) to
544      * (X2,&nbsp;Y2) intersects this line segment.
545      * @param X1,&nbsp;Y1 the coordinates of the beginning of the
546      * specified line segment
547      * @param X2,&nbsp;Y2 the coordinates of the end of the specified
548      * line segment
549      * @return <true> if this line segment and the specified line segment
550      * intersect each other; <code>false</code> otherwise.
551      */

552     public boolean intersectsLine(double X1, double Y1, double X2, double Y2) {
553     return linesIntersect(X1, Y1, X2, Y2,
554                   getX1(), getY1(), getX2(), getY2());
555     }
556
557     /**
558      * Tests if the specified line segment intersects this line segment.
559      * @param l the specified <code>Line2D</code>
560      * @return <code>true</code> if this line segment and the specified line
561      * segment intersect each other;
562      * <code>false</code> otherwise.
563      */

564     public boolean intersectsLine(Line2D JavaDoc l) {
565     return linesIntersect(l.getX1(), l.getY1(), l.getX2(), l.getY2(),
566                   getX1(), getY1(), getX2(), getY2());
567     }
568
569     /**
570      * Returns the square of the distance from a point to a line segment.
571      * The distance measured is the distance between the specified
572      * point and the closest point between the specified endpoints.
573      * If the specified point intersects the line segment in between the
574      * endpoints, this method returns 0.0.
575      * @param X1,&nbsp;Y1 the coordinates of the beginning of the
576      * specified line segment
577      * @param X2,&nbsp;Y2 the coordinates of the end of the specified
578      * line segment
579      * @param PX,&nbsp;PY the coordinates of the specified point being
580      * measured against the specified line segment
581      * @return a double value that is the square of the distance from the
582      * specified point to the specified line segment.
583      * @see #ptLineDistSq(double, double, double, double, double, double)
584      */

585     public static double ptSegDistSq(double X1, double Y1,
586                      double X2, double Y2,
587                      double PX, double PY) {
588     // Adjust vectors relative to X1,Y1
589
// X2,Y2 becomes relative vector from X1,Y1 to end of segment
590
X2 -= X1;
591     Y2 -= Y1;
592     // PX,PY becomes relative vector from X1,Y1 to test point
593
PX -= X1;
594     PY -= Y1;
595     double dotprod = PX * X2 + PY * Y2;
596     double projlenSq;
597     if (dotprod <= 0.0) {
598         // PX,PY is on the side of X1,Y1 away from X2,Y2
599
// distance to segment is length of PX,PY vector
600
// "length of its (clipped) projection" is now 0.0
601
projlenSq = 0.0;
602     } else {
603         // switch to backwards vectors relative to X2,Y2
604
// X2,Y2 are already the negative of X1,Y1=>X2,Y2
605
// to get PX,PY to be the negative of PX,PY=>X2,Y2
606
// the dot product of two negated vectors is the same
607
// as the dot product of the two normal vectors
608
PX = X2 - PX;
609         PY = Y2 - PY;
610         dotprod = PX * X2 + PY * Y2;
611         if (dotprod <= 0.0) {
612         // PX,PY is on the side of X2,Y2 away from X1,Y1
613
// distance to segment is length of (backwards) PX,PY vector
614
// "length of its (clipped) projection" is now 0.0
615
projlenSq = 0.0;
616         } else {
617         // PX,PY is between X1,Y1 and X2,Y2
618
// dotprod is the length of the PX,PY vector
619
// projected on the X2,Y2=>X1,Y1 vector times the
620
// length of the X2,Y2=>X1,Y1 vector
621
projlenSq = dotprod * dotprod / (X2 * X2 + Y2 * Y2);
622         }
623     }
624     // Distance to line is now the length of the relative point
625
// vector minus the length of its projection onto the line
626
// (which is zero if the projection falls outside the range
627
// of the line segment).
628
double lenSq = PX * PX + PY * PY - projlenSq;
629     if (lenSq < 0) {
630         lenSq = 0;
631     }
632     return lenSq;
633     }
634
635     /**
636      * Returns the distance from a point to a line segment.
637      * The distance measured is the distance between the specified
638      * point and the closest point between the specified endpoints.
639      * If the specified point intersects the line segment in between the
640      * endpoints, this method returns 0.0.
641      * @param X1,&nbsp;Y1 the coordinates of the beginning of the
642      * specified line segment
643      * @param X2,&nbsp;Y2 the coordinates of the end of the specified line
644      * segment
645      * @param PX,&nbsp;PY the coordinates of the specified point being
646      * measured against the specified line segment
647      * @return a double value that is the distance from the specified point
648      * to the specified line segment.
649      * @see #ptLineDist(double, double, double, double, double, double)
650      */

651     public static double ptSegDist(double X1, double Y1,
652                    double X2, double Y2,
653                    double PX, double PY) {
654     return Math.sqrt(ptSegDistSq(X1, Y1, X2, Y2, PX, PY));
655     }
656
657     /**
658      * Returns the square of the distance from a point to this line segment.
659      * The distance measured is the distance between the specified
660      * point and the closest point between the current line's endpoints.
661      * If the specified point intersects the line segment in between the
662      * endpoints, this method returns 0.0.
663      * @param PX,&nbsp;PY the coordinates of the specified point being
664      * measured against this line segment
665      * @return a double value that is the square of the distance from the
666      * specified point to the current line segment.
667      * @see #ptLineDistSq(double, double)
668      */

669     public double ptSegDistSq(double PX, double PY) {
670     return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), PX, PY);
671     }
672
673     /**
674      * Returns the square of the distance from a <code>Point2D</code> to
675      * this line segment.
676      * The distance measured is the distance between the specified
677      * point and the closest point between the current line's endpoints.
678      * If the specified point intersects the line segment in between the
679      * endpoints, this method returns 0.0.
680      * @param pt the specified <code>Point2D</code> being measured against
681      * this line segment.
682      * @return a double value that is the square of the distance from the
683      * specified <code>Point2D</code> to the current
684      * line segment.
685      * @see #ptLineDistSq(Point2D)
686      */

687     public double ptSegDistSq(Point2D JavaDoc pt) {
688     return ptSegDistSq(getX1(), getY1(), getX2(), getY2(),
689                pt.getX(), pt.getY());
690     }
691
692     /**
693      * Returns the distance from a point to this line segment.
694      * The distance measured is the distance between the specified
695      * point and the closest point between the current line's endpoints.
696      * If the specified point intersects the line segment in between the
697      * endpoints, this method returns 0.0.
698      * @param PX,&nbsp;PY the coordinates of the specified point
699      * being measured against this line segment
700      * @return a double value that is the distance from the specified
701      * point to the current line segment.
702      * @see #ptLineDist(double, double)
703      */

704     public double ptSegDist(double PX, double PY) {
705     return ptSegDist(getX1(), getY1(), getX2(), getY2(), PX, PY);
706     }
707
708     /**
709      * Returns the distance from a <code>Point2D</code> to this line
710      * segment.
711      * The distance measured is the distance between the specified
712      * point and the closest point between the current line's endpoints.
713      * If the specified point intersects the line segment in between the
714      * endpoints, this method returns 0.0.
715      * @param pt the specified <code>Point2D</code> being measured
716      * against this line segment
717      * @return a double value that is the distance from the specified
718      * <code>Point2D</code> to the current line
719      * segment.
720      * @see #ptLineDist(Point2D)
721      */

722     public double ptSegDist(Point2D JavaDoc pt) {
723     return ptSegDist(getX1(), getY1(), getX2(), getY2(),
724              pt.getX(), pt.getY());
725     }
726
727     /**
728      * Returns the square of the distance from a point to a line.
729      * The distance measured is the distance between the specified
730      * point and the closest point on the infinitely-extended line
731      * defined by the specified coordinates. If the specified point
732      * intersects the line, this method returns 0.0.
733      * @param X1,&nbsp;Y1 the coordinates of one point on the
734      * specified line
735      * @param X2,&nbsp;Y2 the coordinates of another point on
736      * the specified line
737      * @param PX,&nbsp;PY the coordinates of the specified point being
738      * measured against the specified line
739      * @return a double value that is the square of the distance from the
740      * specified point to the specified line.
741      * @see #ptSegDistSq(double, double, double, double, double, double)
742      */

743     public static double ptLineDistSq(double X1, double Y1,
744                       double X2, double Y2,
745                       double PX, double PY) {
746     // Adjust vectors relative to X1,Y1
747
// X2,Y2 becomes relative vector from X1,Y1 to end of segment
748
X2 -= X1;
749     Y2 -= Y1;
750     // PX,PY becomes relative vector from X1,Y1 to test point
751
PX -= X1;
752     PY -= Y1;
753     double dotprod = PX * X2 + PY * Y2;
754     // dotprod is the length of the PX,PY vector
755
// projected on the X1,Y1=>X2,Y2 vector times the
756
// length of the X1,Y1=>X2,Y2 vector
757
double projlenSq = dotprod * dotprod / (X2 * X2 + Y2 * Y2);
758     // Distance to line is now the length of the relative point
759
// vector minus the length of its projection onto the line
760
double lenSq = PX * PX + PY * PY - projlenSq;
761     if (lenSq < 0) {
762         lenSq = 0;
763     }
764     return lenSq;
765     }
766
767     /**
768      * Returns the distance from a point to a line.
769      * The distance measured is the distance between the specified
770      * point and the closest point on the infinitely-extended line
771      * defined by the specified coordinates. If the specified point
772      * intersects the line, this method returns 0.0.
773      * @param X1,&nbsp;Y1 the coordinates of one point on the
774      * specified line
775      * @param X2,&nbsp;Y2 the coordinates of another point on the
776      * specified line
777      * @param PX,&nbsp;PY the coordinates of the specified point being
778      * measured against the specified line
779      * @return a double value that is the distance from the specified
780      * point to the specified line.
781      * @see #ptSegDist(double, double, double, double, double, double)
782      */

783     public static double ptLineDist(double X1, double Y1,
784                     double X2, double Y2,
785                     double PX, double PY) {
786     return Math.sqrt(ptLineDistSq(X1, Y1, X2, Y2, PX, PY));
787     }
788
789     /**
790      * Returns the square of the distance from a point to this line.
791      * The distance measured is the distance between the specified
792      * point and the closest point on the infinitely-extended line
793      * defined by this <code>Line2D</code>. If the specified point
794      * intersects the line, this method returns 0.0.
795      * @param PX,&nbsp;PY the coordinates of the specified point being
796      * measured against this line
797      * @return a double value that is the square of the distance from a
798      * specified point to the current line.
799      * @see #ptSegDistSq(double, double)
800      */

801     public double ptLineDistSq(double PX, double PY) {
802     return ptLineDistSq(getX1(), getY1(), getX2(), getY2(), PX, PY);
803     }
804
805     /**
806      * Returns the square of the distance from a specified
807      * <code>Point2D</code> to this line.
808      * The distance measured is the distance between the specified
809      * point and the closest point on the infinitely-extended line
810      * defined by this <code>Line2D</code>. If the specified point
811      * intersects the line, this method returns 0.0.
812      * @param pt the specified <code>Point2D</code> being measured
813      * against this line
814      * @return a double value that is the square of the distance from a
815      * specified <code>Point2D</code> to the current
816      * line.
817      * @see #ptSegDistSq(Point2D)
818      */

819     public double ptLineDistSq(Point2D JavaDoc pt) {
820     return ptLineDistSq(getX1(), getY1(), getX2(), getY2(),
821                 pt.getX(), pt.getY());
822     }
823
824     /**
825      * Returns the distance from a point to this line.
826      * The distance measured is the distance between the specified
827      * point and the closest point on the infinitely-extended line
828      * defined by this <code>Line2D</code>. If the specified point
829      * intersects the line, this method returns 0.0.
830      * @param PX,&nbsp;PY the coordinates of the specified point being
831      * measured against this line
832      * @return a double value that is the distance from a specified point
833      * to the current line.
834      * @see #ptSegDist(double, double)
835      */

836     public double ptLineDist(double PX, double PY) {
837     return ptLineDist(getX1(), getY1(), getX2(), getY2(), PX, PY);
838     }
839
840     /**
841      * Returns the distance from a <code>Point2D</code> to this line.
842      * The distance measured is the distance between the specified
843      * point and the closest point on the infinitely-extended line
844      * defined by this <code>Line2D</code>. If the specified point
845      * intersects the line, this method returns 0.0.
846      * @param pt the specified <code>Point2D</code> being measured
847      * @return a double value that is the distance from a specified
848      * <code>Point2D</code> to the current line.
849      * @see #ptSegDist(Point2D)
850      */

851     public double ptLineDist(Point2D JavaDoc pt) {
852     return ptLineDist(getX1(), getY1(), getX2(), getY2(),
853              pt.getX(), pt.getY());
854     }
855
856     /**
857      * Tests if a specified coordinate is inside the boundary of this
858      * <code>Line2D</code>. This method is required to implement the
859      * {@link Shape} interface, but in the case of <code>Line2D</code>
860      * objects it always returns <code>false</code> since a line contains
861      * no area.
862      * @param x,&nbsp;y the coordinates of the specified point
863      * @return <code>false</code> because a <code>Line2D</code> contains
864      * no area.
865      */

866     public boolean contains(double x, double y) {
867     return false;
868     }
869
870     /**
871      * Tests if a given <code>Point2D</code> is inside the boundary of
872      * this <code>Line2D</code>.
873      * This method is required to implement the <code>Shape</code> interface,
874      * but in the case of <code>Line2D</code> objects it always returns
875      * <code>false</code> since a line contains no area.
876      * @param p the specified <code>Point2D</code> to be tested
877      * @return <code>false</code> because a <code>Line2D</code> contains
878      * no area.
879      */

880     public boolean contains(Point2D JavaDoc p) {
881     return false;
882     }
883
884     /**
885      * Tests if this <code>Line2D</code> intersects the interior of a
886      * specified set of rectangular coordinates.
887      * @param x,&nbsp;y the coordinates of the top-left corner of the
888      * specified rectangular area
889      * @param w the width of the specified rectangular area
890      * @param h the height of the specified rectangular area
891      * @return <code>true</code> if this <code>Line2D</code> intersects
892      * the interior of the specified set of rectangular
893      * coordinates; <code>false</code> otherwise.
894      */

895     public boolean intersects(double x, double y, double w, double h) {
896     return intersects(new Rectangle2D.Double JavaDoc(x, y, w, h));
897     }
898
899     /**
900      * Tests if this <code>Line2D</code> intersects the interior of a
901      * specified <code>Rectangle2D</code>.
902      * @param r the specified <code>Rectangle2D</code> to be tested
903      * @return <code>true</code> if this <code>Line2D</code> intersects
904      * the interior of the specified <code>Rectangle2D</code>;
905      * <code>false</code> otherwise.
906      */

907     public boolean intersects(Rectangle2D JavaDoc r) {
908     return r.intersectsLine(getX1(), getY1(), getX2(), getY2());
909     }
910
911     /**
912      * Tests if the interior of this <code>Line2D</code> entirely contains
913      * the specified set of rectangular coordinates.
914      * This method is required to implement the <code>Shape</code> interface,
915      * but in the case of <code>Line2D</code> objects it always returns
916      * false since a line contains no area.
917      * @param x,&nbsp;y the coordinates of the top-left corner of the
918      * specified rectangular area
919      * @param w the width of the specified rectangular area
920      * @param h the height of the specified rectangular area
921      * @return <code>false</code> because a <code>Line2D</code> contains
922      * no area.
923      */

924     public boolean contains(double x, double y, double w, double h) {
925     return false;
926     }
927
928     /**
929      * Tests if the interior of this <code>Line2D</code> entirely contains
930      * the specified <code>Rectangle2D</code>.
931      * This method is required to implement the <code>Shape</code> interface,
932      * but in the case of <code>Line2D</code> objects it always returns
933      * <code>false</code> since a line contains no area.
934      * @param r the specified <code>Rectangle2D</code> to be tested
935      * @return <code>false</code> because a <code>Line2D</code> contains
936      * no area.
937      */

938     public boolean contains(Rectangle2D JavaDoc r) {
939     return false;
940     }
941
942     /**
943      * Returns the bounding box of this <code>Line2D</code>.
944      * @return a {@link Rectangle} that is the bounding box of the
945      * <code>Line2D</code>.
946      */

947     public Rectangle JavaDoc getBounds() {
948     return getBounds2D().getBounds();
949     }
950
951     /**
952      * Returns an iteration object that defines the boundary of this
953      * <code>Line2D</code>.
954      * The iterator for this class is not multi-threaded safe,
955      * which means that this <code>Line2D</code> class does not
956      * guarantee that modifications to the geometry of this
957      * <code>Line2D</code> object do not affect any iterations of that
958      * geometry that are already in process.
959      * @param at the specified {@link AffineTransform}
960      * @return a {@link PathIterator} that defines the boundary of this
961      * <code>Line2D</code>.
962      */

963     public PathIterator JavaDoc getPathIterator(AffineTransform JavaDoc at) {
964     return new LineIterator JavaDoc(this, at);
965     }
966
967     /**
968      * Returns an iteration object that defines the boundary of this
969      * flattened <code>Line2D</code>.
970      * The iterator for this class is not multi-threaded safe,
971      * which means that this <code>Line2D</code> class does not
972      * guarantee that modifications to the geometry of this
973      * <code>Line2D</code> object do not affect any iterations of that
974      * geometry that are already in process.
975      * @param at the specified <code>AffineTransform</code>
976      * @param flatness the maximum amount that the control points for a
977      * given curve can vary from colinear before a subdivided
978      * curve is replaced by a straight line connecting the
979      * endpoints. Since a <code>Line2D</code> object is
980      * always flat, this parameter is ignored.
981      * @return a <code>PathIterator</code> that defines the boundary of the
982      * flattened <code>Line2D</code>
983      */

984     public PathIterator JavaDoc getPathIterator(AffineTransform JavaDoc at, double flatness) {
985     return new LineIterator JavaDoc(this, at);
986     }
987
988     /**
989      * Creates a new object of the same class as this object.
990      *
991      * @return a clone of this instance.
992      * @exception OutOfMemoryError if there is not enough memory.
993      * @see java.lang.Cloneable
994      * @since 1.2
995      */

996     public Object JavaDoc clone() {
997     try {
998         return super.clone();
999     } catch (CloneNotSupportedException JavaDoc e) {
1000        // this shouldn't happen, since we are Cloneable
1001
throw new InternalError JavaDoc();
1002    }
1003    }
1004}
1005
Popular Tags