OSDN Git Service

2003-01-14 Michael Koch <konqueror@gmx.de>
[pf3gnuchains/gcc-fork.git] / libjava / java / awt / geom / Line2D.java
1 /* Line2D.java -- represents a line in 2-D space, plus operations on a line
2    Copyright (C) 2000, 2001, 2002 Free Software Foundation
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38 package java.awt.geom;
39
40 import java.awt.Rectangle;
41 import java.awt.Shape;
42 import java.util.NoSuchElementException;
43
44 /**
45  * Represents a directed line bewteen two points in (x,y) Cartesian space.
46  * Remember, on-screen graphics have increasing x from left-to-right, and
47  * increasing y from top-to-bottom. The storage is left to subclasses.
48  *
49  * @author Tom Tromey <tromey@cygnus.com>
50  * @author Eric Blake <ebb9@email.byu.edu>
51  * @since 1.2
52  * @status updated to 1.4
53  */
54 public abstract class Line2D implements Shape, Cloneable
55 {
56   /**
57    * The default constructor.
58    */
59   protected Line2D()
60   {
61   }
62
63   /**
64    * Return the x coordinate of the first point.
65    *
66    * @return the starting x coordinate
67    */
68   public abstract double getX1();
69
70   /**
71    * Return the y coordinate of the first point.
72    *
73    * @return the starting y coordinate
74    */
75   public abstract double getY1();
76
77   /**
78    * Return the first point.
79    *
80    * @return the starting point
81    */
82   public abstract Point2D getP1();
83
84   /**
85    * Return the x coordinate of the second point.
86    *
87    * @return the ending x coordinate
88    */
89   public abstract double getX2();
90
91   /**
92    * Return the y coordinate of the second point.
93    *
94    * @return the ending y coordinate
95    */
96   public abstract double getY2();
97
98   /**
99    * Return the second point.
100    *
101    * @return the ending point
102    */
103   public abstract Point2D getP2();
104
105   /**
106    * Set the coordinates of the line to the given coordinates. Loss of
107    * precision may occur due to rounding issues.
108    *
109    * @param x1 the first x coordinate
110    * @param y1 the first y coordinate
111    * @param x2 the second x coordinate
112    * @param y2 the second y coordinate
113    */
114   public abstract void setLine(double x1, double y1, double x2, double y2);
115
116   /**
117    * Set the coordinates to the given points.
118    *
119    * @param p1 the first point
120    * @param p2 the second point
121    * @throws NullPointerException if either point is null
122    */
123   public void setLine(Point2D p1, Point2D p2)
124   {
125     setLine(p1.getX(), p1.getY(), p2.getX(), p2.getY());
126   }
127
128   /**
129    * Set the coordinates to those of the given line.
130    *
131    * @param l the line to copy
132    * @throws NullPointerException if l is null
133    */
134   public void setLine(Line2D l)
135   {
136     setLine(l.getX1(), l.getY1(), l.getX2(), l.getY2());
137   }
138
139   /**
140    * Computes the relative rotation direction needed to pivot the line about
141    * the first point in order to have the second point colinear with point p.
142    * Because of floating point rounding, don't expect this to be a perfect
143    * measure of colinearity. The answer is 1 if the line has a shorter rotation
144    * in the direction of the positive X axis to the negative Y axis
145    * (counter-clockwise in the default Java coordinate system), or -1 if the
146    * shortest rotation is in the opposite direction (clockwise). If p
147    * is already colinear, the return value is -1 if it lies beyond the first
148    * point, 0 if it lies in the segment, or 1 if it lies beyond the second
149    * point. If the first and second point are coincident, this returns 0.
150    *
151    * @param x1 the first x coordinate
152    * @param y1 the first y coordinate
153    * @param x2 the second x coordinate
154    * @param y2 the second y coordinate
155    * @param px the reference x coordinate
156    * @param py the reference y coordinate
157    * @return the relative rotation direction
158    */
159   public static int relativeCCW(double x1, double y1, double x2, double y2,
160                                 double px, double py)
161   {
162     if ((x1 == x2 && y1 == y2)
163         || (x1 == px && y1 == py))
164       return 0; // Coincident points.
165     // Translate to the origin.
166     x2 -= x1;
167     y2 -= y1;
168     px -= x1;
169     py -= y1;
170     double slope2 = y2 / x2;
171     double slopep = py / px;
172     if (slope2 == slopep || (x2 == 0 && px == 0))
173       return y2 > 0 // Colinear.
174         ? (py < 0 ? -1 : py > y2 ? 1 : 0)
175         : (py > 0 ? -1 : py < y2 ? 1 : 0);
176     if (x2 >= 0 && slope2 >= 0)
177       return px >= 0 // Quadrant 1.
178         ? (slope2 > slopep ? 1 : -1)
179         : (slope2 < slopep ? 1 : -1);
180     if (y2 > 0)
181       return px < 0 // Quadrant 2.
182         ? (slope2 > slopep ? 1 : -1)
183         : (slope2 < slopep ? 1 : -1);
184     if (slope2 >= 0.0)
185       return px >= 0 // Quadrant 3.
186         ? (slope2 < slopep ? 1 : -1)
187         : (slope2 > slopep ? 1 : -1);
188     return px < 0 // Quadrant 4.
189       ? (slope2 < slopep ? 1 : -1)
190       : (slope2 > slopep ? 1 : -1);
191   }
192
193   /**
194    * Computes the relative rotation direction needed to pivot this line about
195    * the first point in order to have the second point colinear with point p.
196    * Because of floating point rounding, don't expect this to be a perfect
197    * measure of colinearity. The answer is 1 if the line has a shorter rotation
198    * in the direction of the positive X axis to the negative Y axis
199    * (counter-clockwise in the default Java coordinate system), or -1 if the
200    * shortest rotation is in the opposite direction (clockwise). If p
201    * is already colinear, the return value is -1 if it lies beyond the first
202    * point, 0 if it lies in the segment, or 1 if it lies beyond the second
203    * point. If the first and second point are coincident, this returns 0.
204    *
205    * @param px the reference x coordinate
206    * @param py the reference y coordinate
207    * @return the relative rotation direction
208    * @see #relativeCCW(double, double, double, double, double, double)
209    */
210   public int relativeCCW(double px, double py)
211   {
212     return relativeCCW(getX1(), getY1(), getX2(), getY2(), px, py);
213   }
214
215   /**
216    * Computes the relative rotation direction needed to pivot this line about
217    * the first point in order to have the second point colinear with point p.
218    * Because of floating point rounding, don't expect this to be a perfect
219    * measure of colinearity. The answer is 1 if the line has a shorter rotation
220    * in the direction of the positive X axis to the negative Y axis
221    * (counter-clockwise in the default Java coordinate system), or -1 if the
222    * shortest rotation is in the opposite direction (clockwise). If p
223    * is already colinear, the return value is -1 if it lies beyond the first
224    * point, 0 if it lies in the segment, or 1 if it lies beyond the second
225    * point. If the first and second point are coincident, this returns 0.
226    *
227    * @param p the reference point
228    * @return the relative rotation direction
229    * @throws NullPointerException if p is null
230    * @see #relativeCCW(double, double, double, double, double, double)
231    */
232   public int relativeCCW(Point2D p)
233   {
234     return relativeCCW(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
235   }
236
237   /**
238    * Test if the line segment (x1,y1)-&gt;(x2,y2) intersects the line segment
239    * (x3,y3)-&gt;(x4,y4).
240    *
241    * @param x1 the first x coordinate of the first segment
242    * @param y1 the first y coordinate of the first segment
243    * @param x2 the second x coordinate of the first segment
244    * @param y2 the second y coordinate of the first segment
245    * @param x3 the first x coordinate of the second segment
246    * @param y3 the first y coordinate of the second segment
247    * @param x4 the second x coordinate of the second segment
248    * @param y4 the second y coordinate of the second segment
249    * @return true if the segments intersect
250    */
251   public static boolean linesIntersect(double x1, double y1,
252                                        double x2, double y2,
253                                        double x3, double y3,
254                                        double x4, double y4)
255   {
256     double beta = (((y1 - y3) * (x4 - x3) + (x1 - x3) * (y4 - y3))
257                    / ((y2 - y1) * (x4 - x3) + (x2 - x1) * (y4 - y3)));
258     if (beta < 0.0 || beta > 1.0)
259       return false;
260     double alpha = (x1 + beta * (x2 - x1) - x3) / (x4 - x3);
261     return alpha >= 0.0 && alpha <= 1.0;
262   }
263
264   /**
265    * Test if this line intersects the line given by (x1,y1)-&gt;(x2,y2).
266    *
267    * @param x1 the first x coordinate of the other segment
268    * @param y1 the first y coordinate of the other segment
269    * @param x2 the second x coordinate of the other segment
270    * @param y2 the second y coordinate of the other segment
271    * @return true if the segments intersect
272    * @see #linesIntersect(double, double, double, double,
273    *                      double, double, double, double)
274    */
275   public boolean intersectsLine(double x1, double y1, double x2, double y2)
276   {
277     return linesIntersect(getX1(), getY1(), getX2(), getY2(),
278                           x1, y1, x2, y2);
279   }
280
281   /**
282    * Test if this line intersects the given line.
283    *
284    * @param l the other segment
285    * @return true if the segments intersect
286    * @throws NullPointerException if l is null
287    * @see #linesIntersect(double, double, double, double,
288    *                      double, double, double, double)
289    */
290   public boolean intersectsLine(Line2D l)
291   {
292     return linesIntersect(getX1(), getY1(), getX2(), getY2(),
293                           l.getX1(), l.getY1(), l.getX2(), l.getY2());
294   }
295
296   /**
297    * Measures the square of the shortest distance from the reference point
298    * to a point on the line segment. If the point is on the segment, the
299    * result will be 0.
300    *
301    * @param x1 the first x coordinate of the segment
302    * @param y1 the first y coordinate of the segment
303    * @param x2 the second x coordinate of the segment
304    * @param y2 the second y coordinate of the segment
305    * @param px the x coordinate of the point
306    * @param py the y coordinate of the point
307    * @return the square of the distance from the point to the segment
308    * @see #ptSegDist(double, double, double, double, double, double)
309    * @see #ptLineDistSq(double, double, double, double, double, double)
310    */
311   public static double ptSegDistSq(double x1, double y1, double x2, double y2,
312                                    double px, double py)
313   {
314     double pd2 = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
315
316     double x, y;
317     if (pd2 == 0)
318       {
319         // Points are coincident.
320         x = x1;
321         y = y2;
322       }
323     else
324       {
325         double u = ((px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)) / pd2;
326
327         if (u < 0)
328           {
329             // "Off the end"
330             x = x1;
331             y = y1;
332           }
333         else if (u > 1.0)
334           {
335             x = x2;
336             y = y2;
337           }
338         else
339           {
340             x = x1 + u * (x2 - x1);
341             y = y1 + u * (y2 - y1);
342           }
343       }
344
345     return (x - px) * (x - px) + (y - py) * (y - py);
346   }
347
348   /**
349    * Measures the shortest distance from the reference point to a point on
350    * the line segment. If the point is on the segment, the result will be 0.
351    *
352    * @param x1 the first x coordinate of the segment
353    * @param y1 the first y coordinate of the segment
354    * @param x2 the second x coordinate of the segment
355    * @param y2 the second y coordinate of the segment
356    * @param px the x coordinate of the point
357    * @param py the y coordinate of the point
358    * @return the distance from the point to the segment
359    * @see #ptSegDistSq(double, double, double, double, double, double)
360    * @see #ptLineDist(double, double, double, double, double, double)
361    */
362   public static double ptSegDist(double x1, double y1, double x2, double y2,
363                                  double px, double py)
364   {
365     return Math.sqrt(ptSegDistSq(x1, y1, x2, y2, px, py));
366   }
367
368   /**
369    * Measures the square of the shortest distance from the reference point
370    * to a point on this line segment. If the point is on the segment, the
371    * result will be 0.
372    *
373    * @param px the x coordinate of the point
374    * @param py the y coordinate of the point
375    * @return the square of the distance from the point to the segment
376    * @see #ptSegDistSq(double, double, double, double, double, double)
377    */
378   public double ptSegDistSq(double px, double py)
379   {
380     return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), px, py);
381   }
382
383   /**
384    * Measures the square of the shortest distance from the reference point
385    * to a point on this line segment. If the point is on the segment, the
386    * result will be 0.
387    *
388    * @param p the point
389    * @return the square of the distance from the point to the segment
390    * @throws NullPointerException if p is null
391    * @see #ptSegDistSq(double, double, double, double, double, double)
392    */
393   public double ptSegDistSq(Point2D p)
394   {
395     return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
396   }
397
398   /**
399    * Measures the shortest distance from the reference point to a point on
400    * this line segment. If the point is on the segment, the result will be 0.
401    *
402    * @param px the x coordinate of the point
403    * @param py the y coordinate of the point
404    * @return the distance from the point to the segment
405    * @see #ptSegDist(double, double, double, double, double, double)
406    */
407   public double ptSegDist(double px, double py)
408   {
409     return ptSegDist(getX1(), getY1(), getX2(), getY2(), px, py);
410   }
411
412   /**
413    * Measures the shortest distance from the reference point to a point on
414    * this line segment. If the point is on the segment, the result will be 0.
415    *
416    * @param p the point
417    * @return the distance from the point to the segment
418    * @throws NullPointerException if p is null
419    * @see #ptSegDist(double, double, double, double, double, double)
420    */
421   public double ptSegDist(Point2D p)
422   {
423     return ptSegDist(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
424   }
425
426   /**
427    * Measures the square of the shortest distance from the reference point
428    * to a point on the infinite line extended from the segment. If the point
429    * is on the segment, the result will be 0. If the segment is length 0,
430    * the distance is to the common endpoint.
431    *
432    * @param x1 the first x coordinate of the segment
433    * @param y1 the first y coordinate of the segment
434    * @param x2 the second x coordinate of the segment
435    * @param y2 the second y coordinate of the segment
436    * @param px the x coordinate of the point
437    * @param py the y coordinate of the point
438    * @return the square of the distance from the point to the extended line
439    * @see #ptLineDist(double, double, double, double, double, double)
440    * @see #ptSegDistSq(double, double, double, double, double, double)
441    */
442   public static double ptLineDistSq(double x1, double y1, double x2, double y2,
443                                     double px, double py)
444   {
445     double pd2 = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
446
447     double x, y;
448     if (pd2 == 0)
449       {
450         // Points are coincident.
451         x = x1;
452         y = y2;
453       }
454     else
455       {
456         double u = ((px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)) / pd2;
457         x = x1 + u * (x2 - x1);
458         y = y1 + u * (y2 - y1);
459       }
460
461     return (x - px) * (x - px) + (y - py) * (y - py);
462   }
463
464   /**
465    * Measures the shortest distance from the reference point to a point on
466    * the infinite line extended from the segment. If the point is on the
467    * segment, the result will be 0. If the segment is length 0, the distance
468    * is to the common endpoint.
469    *
470    * @param x1 the first x coordinate of the segment
471    * @param y1 the first y coordinate of the segment
472    * @param x2 the second x coordinate of the segment
473    * @param y2 the second y coordinate of the segment
474    * @param px the x coordinate of the point
475    * @param py the y coordinate of the point
476    * @return the distance from the point to the extended line
477    * @see #ptLineDistSq(double, double, double, double, double, double)
478    * @see #ptSegDist(double, double, double, double, double, double)
479    */
480   public static double ptLineDist(double x1, double y1,
481                                    double x2, double y2,
482                                    double px, double py)
483   {
484     return Math.sqrt(ptLineDistSq(x1, y1, x2, y2, px, py));
485   }
486
487   /**
488    * Measures the square of the shortest distance from the reference point
489    * to a point on the infinite line extended from this segment. If the point
490    * is on the segment, the result will be 0. If the segment is length 0,
491    * the distance is to the common endpoint.
492    *
493    * @param px the x coordinate of the point
494    * @param py the y coordinate of the point
495    * @return the square of the distance from the point to the extended line
496    * @see #ptLineDistSq(double, double, double, double, double, double)
497    */
498   public double ptLineDistSq(double px, double py)
499   {
500     return ptLineDistSq(getX1(), getY1(), getX2(), getY2(), px, py);
501   }
502
503   /**
504    * Measures the square of the shortest distance from the reference point
505    * to a point on the infinite line extended from this segment. If the point
506    * is on the segment, the result will be 0. If the segment is length 0,
507    * the distance is to the common endpoint.
508    *
509    * @param p the point
510    * @return the square of the distance from the point to the extended line
511    * @throws NullPointerException if p is null
512    * @see #ptLineDistSq(double, double, double, double, double, double)
513    */
514   public double ptLineDistSq(Point2D p)
515   {
516     return ptLineDistSq(getX1(), getY1(), getX2(), getY2(),
517                         p.getX(), p.getY());
518   }
519
520   /**
521    * Measures the shortest distance from the reference point to a point on
522    * the infinite line extended from this segment. If the point is on the
523    * segment, the result will be 0. If the segment is length 0, the distance
524    * is to the common endpoint.
525    *
526    * @param px the x coordinate of the point
527    * @param py the y coordinate of the point
528    * @return the distance from the point to the extended line
529    * @see #ptLineDist(double, double, double, double, double, double)
530    */
531   public double ptLineDist(double px, double py)
532   {
533     return ptLineDist(getX1(), getY1(), getX2(), getY2(), px, py);
534   }
535
536   /**
537    * Measures the shortest distance from the reference point to a point on
538    * the infinite line extended from this segment. If the point is on the
539    * segment, the result will be 0. If the segment is length 0, the distance
540    * is to the common endpoint.
541    *
542    * @param p the point
543    * @return the distance from the point to the extended line
544    * @throws NullPointerException if p is null
545    * @see #ptLineDist(double, double, double, double, double, double)
546    */
547   public double ptLineDist(Point2D p)
548   {
549     return ptLineDist(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
550   }
551
552   /**
553    * Test if a point is contained inside the line. Since a line has no area,
554    * this returns false.
555    *
556    * @param x the x coordinate
557    * @param y the y coordinate
558    * @return false; the line does not contain points
559    */
560   public boolean contains(double x, double y)
561   {
562     return false;
563   }
564
565   /**
566    * Test if a point is contained inside the line. Since a line has no area,
567    * this returns false.
568    *
569    * @param p the point
570    * @return false; the line does not contain points
571    */
572   public boolean contains(Point2D p)
573   {
574     return false;
575   }
576
577   /**
578    * Tests if this line intersects the interior of the specified rectangle.
579    *
580    * @param x the x coordinate of the rectangle
581    * @param y the y coordinate of the rectangle
582    * @param w the width of the rectangle
583    * @param h the height of the rectangle
584    * @return true if the line intersects the rectangle
585    */
586   public boolean intersects(double x, double y, double w, double h)
587   {
588     if (w <= 0 || h <= 0)
589       return false;
590     double x1 = getX1();
591     double y1 = getY1();
592     double x2 = getX2();
593     double y2 = getY2();
594
595     if (x1 >= x && x1 <= x + w && y1 >= y && y1 <= y + h)
596       return true;
597     if (x2 >= x && x2 <= x + w && y2 >= y && y2 <= y + h)
598       return true;
599
600     double x3 = x + w;
601     double y3 = y + h;
602
603     return (linesIntersect(x1, y1, x2, y2, x, y, x, y3)
604             || linesIntersect(x1, y1, x2, y2, x, y3, x3, y3)
605             || linesIntersect(x1, y1, x2, y2, x3, y3, x3, y)
606             || linesIntersect(x1, y1, x2, y2, x3, y, x, y));
607   }
608
609   /**
610    * Tests if this line intersects the interior of the specified rectangle.
611    *
612    * @param r the rectangle
613    * @return true if the line intersects the rectangle
614    * @throws NullPointerException if r is null
615    */
616   public boolean intersects(Rectangle2D r)
617   {
618     return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
619   }
620
621   /**
622    * Tests if the line contains a rectangle. Since lines have no area, this
623    * always returns false.
624    *
625    * @param x the x coordinate of the rectangle
626    * @param y the y coordinate of the rectangle
627    * @param w the width of the rectangle
628    * @param h the height of the rectangle
629    * @return false; the line does not contain points
630    */
631   public boolean contains(double x, double y, double w, double h)
632   {
633     return false;
634   }
635
636   /**
637    * Tests if the line contains a rectangle. Since lines have no area, this
638    * always returns false.
639    *
640    * @param r the rectangle
641    * @return false; the line does not contain points
642    */
643   public boolean contains(Rectangle2D r)
644   {
645     return false;
646   }
647
648   /**
649    * Gets a bounding box (not necessarily minimal) for this line.
650    *
651    * @return the integer bounding box
652    * @see #getBounds2D()
653    */
654   public Rectangle getBounds()
655   {
656     return getBounds2D().getBounds();
657   }
658
659   /**
660    * Return a path iterator, possibly applying a transform on the result. This
661    * iterator is not threadsafe.
662    *
663    * @param at the transform, or null
664    * @return a new path iterator
665    */
666   public PathIterator getPathIterator(final AffineTransform at)
667   {
668     return new PathIterator()
669     {
670       /** Current coordinate. */
671       private int current;
672
673       public int getWindingRule()
674       {
675         return WIND_NON_ZERO;
676       }
677
678       public boolean isDone()
679       {
680         return current < 2;
681       }
682
683       public void next()
684       {
685         current++;
686       }
687
688       public int currentSegment(float[] coords)
689       {
690         int result;
691         switch (current)
692           {
693           case 0:
694             coords[0] = (float) getX1();
695             coords[1] = (float) getY1();
696             result = SEG_MOVETO;
697             break;
698           case 1:
699             coords[0] = (float) getX2();
700             coords[1] = (float) getY2();
701             result = SEG_LINETO;
702             break;
703           default:
704             throw new NoSuchElementException("line iterator out of bounds");
705           }
706         if (at != null)
707           at.transform(coords, 0, coords, 0, 1);
708         return result;
709       }
710
711       public int currentSegment(double[] coords)
712       {
713         int result;
714         switch (current)
715           {
716           case 0:
717             coords[0] = getX1();
718             coords[1] = getY1();
719             result = SEG_MOVETO;
720             break;
721           case 1:
722             coords[0] = getX2();
723             coords[1] = getY2();
724             result = SEG_LINETO;
725             break;
726           default:
727             throw new NoSuchElementException("line iterator out of bounds");
728           }
729         if (at != null)
730           at.transform(coords, 0, coords, 0, 1);
731         return result;
732       }
733     };
734   }
735
736   /**
737    * Return a flat path iterator, possibly applying a transform on the result.
738    * This iterator is not threadsafe.
739    *
740    * @param at the transform, or null
741    * @param flatness ignored, since lines are already flat
742    * @return a new path iterator
743    * @see #getPathIterator(AffineTransform)
744    */
745   public PathIterator getPathIterator(AffineTransform at, double flatness)
746   {
747     return getPathIterator(at);
748   }
749
750   /**
751    * Create a new line of the same run-time type with the same contents as
752    * this one.
753    *
754    * @return the clone
755    *
756    * @exception OutOfMemoryError If there is not enough memory available.
757    *
758    * @since 1.2
759    */
760   public Object clone()
761   {
762     try
763       {
764         return super.clone();
765       }
766     catch (CloneNotSupportedException e)
767       {
768         throw (Error) new InternalError().initCause(e); // Impossible
769       }
770   }
771
772   /**
773    * This class defines a point in <code>double</code> precision.
774    *
775    * @author Eric Blake <ebb9@email.byu.edu>
776    * @since 1.2
777    * @status updated to 1.4
778    */
779   public static class Double extends Line2D
780   {
781     /** The x coordinate of the first point. */
782     public double x1;
783
784     /** The y coordinate of the first point. */
785     public double y1;
786
787     /** The x coordinate of the second point. */
788     public double x2;
789
790     /** The y coordinate of the second point. */
791     public double y2;
792
793     /**
794      * Construct the line segment (0,0)-&gt;(0,0).
795      */
796     public Double()
797     {
798     }
799
800     /**
801      * Construct the line segment with the specified points.
802      *
803      * @param x1 the x coordinate of the first point
804      * @param y1 the y coordinate of the first point
805      * @param x2 the x coordinate of the second point
806      * @param y2 the y coordinate of the second point
807      */
808     public Double(double x1, double y1, double x2, double y2)
809     {
810       this.x1 = x1;
811       this.y1 = y1;
812       this.x2 = x2;
813       this.y2 = y2;
814     }
815
816     /**
817      * Construct the line segment with the specified points.
818      *
819      * @param p1 the first point
820      * @param p2 the second point
821      * @throws NullPointerException if either point is null
822      */
823     public Double(Point2D p1, Point2D p2)
824     {
825       x1 = p1.getX();
826       y1 = p1.getY();
827       x2 = p2.getX();
828       y2 = p2.getY();
829     }
830
831     /**
832      * Return the x coordinate of the first point.
833      *
834      * @return the value of x1
835      */
836     public double getX1()
837     {
838       return x1;
839     }
840
841     /**
842      * Return the y coordinate of the first point.
843      *
844      * @return the value of y1
845      */
846     public double getY1()
847     {
848       return y1;
849     }
850
851     /**
852      * Return the first point.
853      *
854      * @return the point (x1,y1)
855      */
856     public Point2D getP1()
857     {
858       return new Point2D.Double(x1, y1);
859     }
860
861     /**
862      * Return the x coordinate of the second point.
863      *
864      * @return the value of x2
865      */
866     public double getX2()
867     {
868       return x2;
869     }
870
871     /**
872      * Return the y coordinate of the second point.
873      *
874      * @return the value of y2
875      */
876     public double getY2()
877     {
878       return y2;
879     }
880
881     /**
882      * Return the second point.
883      *
884      * @return the point (x2,y2)
885      */
886     public Point2D getP2()
887     {
888       return new Point2D.Double(x2, y2);
889     }
890
891     /**
892      * Set this line to the given points.
893      *
894      * @param x1 the new x coordinate of the first point
895      * @param y1 the new y coordinate of the first point
896      * @param x2 the new x coordinate of the second point
897      * @param y2 the new y coordinate of the second point
898      */
899     public void setLine(double x1, double y1, double x2, double y2)
900     {
901       this.x1 = x1;
902       this.y1 = y1;
903       this.x2 = x2;
904       this.y2 = y2;
905     }
906
907     /**
908      * Return the exact bounds of this line segment.
909      *
910      * @return the bounding box
911      */
912     public Rectangle2D getBounds2D()
913     {
914       double x = Math.min(x1, x2);
915       double y = Math.min(y1, y2);
916       double w = Math.abs(x1 - x2);
917       double h = Math.abs(y1 - y2);
918       return new Rectangle2D.Double(x, y, w, h);
919     }
920   } // class Double
921
922   /**
923    * This class defines a point in <code>float</code> precision.
924    *
925    * @author Eric Blake <ebb9@email.byu.edu>
926    * @since 1.2
927    * @status updated to 1.4
928    */
929   public static class Float extends Line2D
930   {
931     /** The x coordinate of the first point. */
932     public float x1;
933
934     /** The y coordinate of the first point. */
935     public float y1;
936
937     /** The x coordinate of the second point. */
938     public float x2;
939
940     /** The y coordinate of the second point. */
941     public float y2;
942
943     /**
944      * Construct the line segment (0,0)-&gt;(0,0).
945      */
946     public Float()
947     {
948     }
949
950     /**
951      * Construct the line segment with the specified points.
952      *
953      * @param x1 the x coordinate of the first point
954      * @param y1 the y coordinate of the first point
955      * @param x2 the x coordinate of the second point
956      * @param y2 the y coordinate of the second point
957      */
958     public Float(float x1, float y1, float x2, float y2)
959     {
960       this.x1 = x1;
961       this.y1 = y1;
962       this.x2 = x2;
963       this.y2 = y2;
964     }
965
966     /**
967      * Construct the line segment with the specified points.
968      *
969      * @param p1 the first point
970      * @param p2 the second point
971      * @throws NullPointerException if either point is null
972      */
973     public Float(Point2D p1, Point2D p2)
974     {
975       x1 = (float) p1.getX();
976       y1 = (float) p1.getY();
977       x2 = (float) p2.getX();
978       y2 = (float) p2.getY();
979     }
980
981     /**
982      * Return the x coordinate of the first point.
983      *
984      * @return the value of x1
985      */
986     public double getX1()
987     {
988       return x1;
989     }
990
991     /**
992      * Return the y coordinate of the first point.
993      *
994      * @return the value of y1
995      */
996     public double getY1()
997     {
998       return y1;
999     }
1000
1001     /**
1002      * Return the first point.
1003      *
1004      * @return the point (x1,y1)
1005      */
1006     public Point2D getP1()
1007     {
1008       return new Point2D.Float(x1, y1);
1009     }
1010
1011     /**
1012      * Return the x coordinate of the second point.
1013      *
1014      * @return the value of x2
1015      */
1016     public double getX2()
1017     {
1018       return x2;
1019     }
1020
1021     /**
1022      * Return the y coordinate of the second point.
1023      *
1024      * @return the value of y2
1025      */
1026     public double getY2()
1027     {
1028       return y2;
1029     }
1030
1031     /**
1032      * Return the second point.
1033      *
1034      * @return the point (x2,y2)
1035      */
1036     public Point2D getP2()
1037     {
1038       return new Point2D.Float(x2, y2);
1039     }
1040
1041     /**
1042      * Set this line to the given points.
1043      *
1044      * @param x1 the new x coordinate of the first point
1045      * @param y1 the new y coordinate of the first point
1046      * @param x2 the new x coordinate of the second point
1047      * @param y2 the new y coordinate of the second point
1048      */
1049     public void setLine(double x1, double y1, double x2, double y2)
1050     {
1051       this.x1 = (float) x1;
1052       this.y1 = (float) y1;
1053       this.x2 = (float) x2;
1054       this.y2 = (float) y2;
1055     }
1056
1057     /**
1058      * Set this line to the given points.
1059      *
1060      * @param x1 the new x coordinate of the first point
1061      * @param y1 the new y coordinate of the first point
1062      * @param x2 the new x coordinate of the second point
1063      * @param y2 the new y coordinate of the second point
1064      */
1065     public void setLine(float x1, float y1, float x2, float y2)
1066     {
1067       this.x1 = x1;
1068       this.y1 = y1;
1069       this.x2 = x2;
1070       this.y2 = y2;
1071     }
1072
1073     /**
1074      * Return the exact bounds of this line segment.
1075      *
1076      * @return the bounding box
1077      */
1078     public Rectangle2D getBounds2D()
1079     {
1080       float x = Math.min(x1, x2);
1081       float y = Math.min(y1, y2);
1082       float w = Math.abs(x1 - x2);
1083       float h = Math.abs(y1 - y2);
1084       return new Rectangle2D.Float(x, y, w, h);
1085     }
1086   } // class Float
1087 } // class Line2D