Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / libjava / java / awt / geom / Line2D.java
blob3b64f45572708b1b3953c7d859c51fe00003d5d0
1 /* Line2D.java -- represents a line in 2-D space, plus operations on a line
2 Copyright (C) 2000, 2001, 2002 Free Software Foundation
4 This file is part of GNU Classpath.
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.
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.
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.
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.
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. */
38 package java.awt.geom;
40 import java.awt.Rectangle;
41 import java.awt.Shape;
42 import java.util.NoSuchElementException;
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.
49 * @author Tom Tromey (tromey@cygnus.com)
50 * @author Eric Blake (ebb9@email.byu.edu)
51 * @author David Gilbert
52 * @since 1.2
53 * @status updated to 1.4
55 public abstract class Line2D implements Shape, Cloneable
57 /**
58 * The default constructor.
60 protected Line2D()
64 /**
65 * Return the x coordinate of the first point.
67 * @return the starting x coordinate
69 public abstract double getX1();
71 /**
72 * Return the y coordinate of the first point.
74 * @return the starting y coordinate
76 public abstract double getY1();
78 /**
79 * Return the first point.
81 * @return the starting point
83 public abstract Point2D getP1();
85 /**
86 * Return the x coordinate of the second point.
88 * @return the ending x coordinate
90 public abstract double getX2();
92 /**
93 * Return the y coordinate of the second point.
95 * @return the ending y coordinate
97 public abstract double getY2();
99 /**
100 * Return the second point.
102 * @return the ending point
104 public abstract Point2D getP2();
107 * Set the coordinates of the line to the given coordinates. Loss of
108 * precision may occur due to rounding issues.
110 * @param x1 the first x coordinate
111 * @param y1 the first y coordinate
112 * @param x2 the second x coordinate
113 * @param y2 the second y coordinate
115 public abstract void setLine(double x1, double y1, double x2, double y2);
118 * Set the coordinates to the given points.
120 * @param p1 the first point
121 * @param p2 the second point
122 * @throws NullPointerException if either point is null
124 public void setLine(Point2D p1, Point2D p2)
126 setLine(p1.getX(), p1.getY(), p2.getX(), p2.getY());
130 * Set the coordinates to those of the given line.
132 * @param l the line to copy
133 * @throws NullPointerException if l is null
135 public void setLine(Line2D l)
137 setLine(l.getX1(), l.getY1(), l.getX2(), l.getY2());
141 * Computes the relative rotation direction needed to pivot the line about
142 * the first point in order to have the second point colinear with point p.
143 * Because of floating point rounding, don't expect this to be a perfect
144 * measure of colinearity. The answer is 1 if the line has a shorter rotation
145 * in the direction of the positive X axis to the negative Y axis
146 * (counter-clockwise in the default Java coordinate system), or -1 if the
147 * shortest rotation is in the opposite direction (clockwise). If p
148 * is already colinear, the return value is -1 if it lies beyond the first
149 * point, 0 if it lies in the segment, or 1 if it lies beyond the second
150 * point. If the first and second point are coincident, this returns 0.
152 * @param x1 the first x coordinate
153 * @param y1 the first y coordinate
154 * @param x2 the second x coordinate
155 * @param y2 the second y coordinate
156 * @param px the reference x coordinate
157 * @param py the reference y coordinate
158 * @return the relative rotation direction
160 public static int relativeCCW(double x1, double y1, double x2, double y2,
161 double px, double py)
163 if ((x1 == x2 && y1 == y2)
164 || (x1 == px && y1 == py))
165 return 0; // Coincident points.
166 // Translate to the origin.
167 x2 -= x1;
168 y2 -= y1;
169 px -= x1;
170 py -= y1;
171 double slope2 = y2 / x2;
172 double slopep = py / px;
173 if (slope2 == slopep || (x2 == 0 && px == 0))
174 return y2 > 0 // Colinear.
175 ? (py < 0 ? -1 : py > y2 ? 1 : 0)
176 : (py > 0 ? -1 : py < y2 ? 1 : 0);
177 if (x2 >= 0 && slope2 >= 0)
178 return px >= 0 // Quadrant 1.
179 ? (slope2 > slopep ? 1 : -1)
180 : (slope2 < slopep ? 1 : -1);
181 if (y2 > 0)
182 return px < 0 // Quadrant 2.
183 ? (slope2 > slopep ? 1 : -1)
184 : (slope2 < slopep ? 1 : -1);
185 if (slope2 >= 0.0)
186 return px >= 0 // Quadrant 3.
187 ? (slope2 < slopep ? 1 : -1)
188 : (slope2 > slopep ? 1 : -1);
189 return px < 0 // Quadrant 4.
190 ? (slope2 < slopep ? 1 : -1)
191 : (slope2 > slopep ? 1 : -1);
195 * Computes the relative rotation direction needed to pivot this line about
196 * the first point in order to have the second point colinear with point p.
197 * Because of floating point rounding, don't expect this to be a perfect
198 * measure of colinearity. The answer is 1 if the line has a shorter rotation
199 * in the direction of the positive X axis to the negative Y axis
200 * (counter-clockwise in the default Java coordinate system), or -1 if the
201 * shortest rotation is in the opposite direction (clockwise). If p
202 * is already colinear, the return value is -1 if it lies beyond the first
203 * point, 0 if it lies in the segment, or 1 if it lies beyond the second
204 * point. If the first and second point are coincident, this returns 0.
206 * @param px the reference x coordinate
207 * @param py the reference y coordinate
208 * @return the relative rotation direction
209 * @see #relativeCCW(double, double, double, double, double, double)
211 public int relativeCCW(double px, double py)
213 return relativeCCW(getX1(), getY1(), getX2(), getY2(), px, py);
217 * Computes the relative rotation direction needed to pivot this line about
218 * the first point in order to have the second point colinear with point p.
219 * Because of floating point rounding, don't expect this to be a perfect
220 * measure of colinearity. The answer is 1 if the line has a shorter rotation
221 * in the direction of the positive X axis to the negative Y axis
222 * (counter-clockwise in the default Java coordinate system), or -1 if the
223 * shortest rotation is in the opposite direction (clockwise). If p
224 * is already colinear, the return value is -1 if it lies beyond the first
225 * point, 0 if it lies in the segment, or 1 if it lies beyond the second
226 * point. If the first and second point are coincident, this returns 0.
228 * @param p the reference point
229 * @return the relative rotation direction
230 * @throws NullPointerException if p is null
231 * @see #relativeCCW(double, double, double, double, double, double)
233 public int relativeCCW(Point2D p)
235 return relativeCCW(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
239 * Computes twice the (signed) area of the triangle defined by the three
240 * points. This method is used for intersection testing.
242 * @param x1 the x-coordinate of the first point.
243 * @param y1 the y-coordinate of the first point.
244 * @param x2 the x-coordinate of the second point.
245 * @param y2 the y-coordinate of the second point.
246 * @param x3 the x-coordinate of the third point.
247 * @param y3 the y-coordinate of the third point.
249 * @return Twice the area.
251 private static double area2(double x1, double y1,
252 double x2, double y2,
253 double x3, double y3)
255 return (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1);
259 * Returns <code>true</code> if (x3, y3) lies between (x1, y1) and (x2, y2),
260 * and false otherwise, This test assumes that the three points are
261 * collinear, and is used for intersection testing.
263 * @param x1 the x-coordinate of the first point.
264 * @param y1 the y-coordinate of the first point.
265 * @param x2 the x-coordinate of the second point.
266 * @param y2 the y-coordinate of the second point.
267 * @param x3 the x-coordinate of the third point.
268 * @param y3 the y-coordinate of the third point.
270 * @return A boolean.
272 private static boolean between(double x1, double y1,
273 double x2, double y2,
274 double x3, double y3)
276 if (x1 != x2) {
277 return (x1 <= x3 && x3 <= x2) || (x1 >= x3 && x3 >= x2);
279 else {
280 return (y1 <= y3 && y3 <= y2) || (y1 >= y3 && y3 >= y2);
285 * Test if the line segment (x1,y1)-&gt;(x2,y2) intersects the line segment
286 * (x3,y3)-&gt;(x4,y4).
288 * @param x1 the first x coordinate of the first segment
289 * @param y1 the first y coordinate of the first segment
290 * @param x2 the second x coordinate of the first segment
291 * @param y2 the second y coordinate of the first segment
292 * @param x3 the first x coordinate of the second segment
293 * @param y3 the first y coordinate of the second segment
294 * @param x4 the second x coordinate of the second segment
295 * @param y4 the second y coordinate of the second segment
296 * @return true if the segments intersect
298 public static boolean linesIntersect(double x1, double y1,
299 double x2, double y2,
300 double x3, double y3,
301 double x4, double y4)
303 double a1, a2, a3, a4;
305 // deal with special cases
306 if ((a1 = area2(x1, y1, x2, y2, x3, y3)) == 0.0)
308 // check if p3 is between p1 and p2 OR
309 // p4 is collinear also AND either between p1 and p2 OR at opposite ends
310 if (between(x1, y1, x2, y2, x3, y3))
312 return true;
314 else
316 if (area2(x1, y1, x2, y2, x4, y4) == 0.0)
318 return between(x3, y3, x4, y4, x1, y1)
319 || between (x3, y3, x4, y4, x2, y2);
321 else {
322 return false;
326 else if ((a2 = area2(x1, y1, x2, y2, x4, y4)) == 0.0)
328 // check if p4 is between p1 and p2 (we already know p3 is not
329 // collinear)
330 return between(x1, y1, x2, y2, x4, y4);
333 if ((a3 = area2(x3, y3, x4, y4, x1, y1)) == 0.0) {
334 // check if p1 is between p3 and p4 OR
335 // p2 is collinear also AND either between p1 and p2 OR at opposite ends
336 if (between(x3, y3, x4, y4, x1, y1)) {
337 return true;
339 else {
340 if (area2(x3, y3, x4, y4, x2, y2) == 0.0) {
341 return between(x1, y1, x2, y2, x3, y3)
342 || between (x1, y1, x2, y2, x4, y4);
344 else {
345 return false;
349 else if ((a4 = area2(x3, y3, x4, y4, x2, y2)) == 0.0) {
350 // check if p2 is between p3 and p4 (we already know p1 is not
351 // collinear)
352 return between(x3, y3, x4, y4, x2, y2);
354 else { // test for regular intersection
355 return ((a1 > 0.0) ^ (a2 > 0.0)) && ((a3 > 0.0) ^ (a4 > 0.0));
360 * Test if this line intersects the line given by (x1,y1)-&gt;(x2,y2).
362 * @param x1 the first x coordinate of the other segment
363 * @param y1 the first y coordinate of the other segment
364 * @param x2 the second x coordinate of the other segment
365 * @param y2 the second y coordinate of the other segment
366 * @return true if the segments intersect
367 * @see #linesIntersect(double, double, double, double,
368 * double, double, double, double)
370 public boolean intersectsLine(double x1, double y1, double x2, double y2)
372 return linesIntersect(getX1(), getY1(), getX2(), getY2(),
373 x1, y1, x2, y2);
377 * Test if this line intersects the given line.
379 * @param l the other segment
380 * @return true if the segments intersect
381 * @throws NullPointerException if l is null
382 * @see #linesIntersect(double, double, double, double,
383 * double, double, double, double)
385 public boolean intersectsLine(Line2D l)
387 return linesIntersect(getX1(), getY1(), getX2(), getY2(),
388 l.getX1(), l.getY1(), l.getX2(), l.getY2());
392 * Measures the square of the shortest distance from the reference point
393 * to a point on the line segment. If the point is on the segment, the
394 * result will be 0.
396 * @param x1 the first x coordinate of the segment
397 * @param y1 the first y coordinate of the segment
398 * @param x2 the second x coordinate of the segment
399 * @param y2 the second y coordinate of the segment
400 * @param px the x coordinate of the point
401 * @param py the y coordinate of the point
402 * @return the square of the distance from the point to the segment
403 * @see #ptSegDist(double, double, double, double, double, double)
404 * @see #ptLineDistSq(double, double, double, double, double, double)
406 public static double ptSegDistSq(double x1, double y1, double x2, double y2,
407 double px, double py)
409 double pd2 = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
411 double x, y;
412 if (pd2 == 0)
414 // Points are coincident.
415 x = x1;
416 y = y2;
418 else
420 double u = ((px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)) / pd2;
422 if (u < 0)
424 // "Off the end"
425 x = x1;
426 y = y1;
428 else if (u > 1.0)
430 x = x2;
431 y = y2;
433 else
435 x = x1 + u * (x2 - x1);
436 y = y1 + u * (y2 - y1);
440 return (x - px) * (x - px) + (y - py) * (y - py);
444 * Measures the shortest distance from the reference point to a point on
445 * the line segment. If the point is on the segment, the result will be 0.
447 * @param x1 the first x coordinate of the segment
448 * @param y1 the first y coordinate of the segment
449 * @param x2 the second x coordinate of the segment
450 * @param y2 the second y coordinate of the segment
451 * @param px the x coordinate of the point
452 * @param py the y coordinate of the point
453 * @return the distance from the point to the segment
454 * @see #ptSegDistSq(double, double, double, double, double, double)
455 * @see #ptLineDist(double, double, double, double, double, double)
457 public static double ptSegDist(double x1, double y1, double x2, double y2,
458 double px, double py)
460 return Math.sqrt(ptSegDistSq(x1, y1, x2, y2, px, py));
464 * Measures the square of the shortest distance from the reference point
465 * to a point on this line segment. If the point is on the segment, the
466 * result will be 0.
468 * @param px the x coordinate of the point
469 * @param py the y coordinate of the point
470 * @return the square of the distance from the point to the segment
471 * @see #ptSegDistSq(double, double, double, double, double, double)
473 public double ptSegDistSq(double px, double py)
475 return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), px, py);
479 * Measures the square of the shortest distance from the reference point
480 * to a point on this line segment. If the point is on the segment, the
481 * result will be 0.
483 * @param p the point
484 * @return the square of the distance from the point to the segment
485 * @throws NullPointerException if p is null
486 * @see #ptSegDistSq(double, double, double, double, double, double)
488 public double ptSegDistSq(Point2D p)
490 return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
494 * Measures the shortest distance from the reference point to a point on
495 * this line segment. If the point is on the segment, the result will be 0.
497 * @param px the x coordinate of the point
498 * @param py the y coordinate of the point
499 * @return the distance from the point to the segment
500 * @see #ptSegDist(double, double, double, double, double, double)
502 public double ptSegDist(double px, double py)
504 return ptSegDist(getX1(), getY1(), getX2(), getY2(), px, py);
508 * Measures the shortest distance from the reference point to a point on
509 * this line segment. If the point is on the segment, the result will be 0.
511 * @param p the point
512 * @return the distance from the point to the segment
513 * @throws NullPointerException if p is null
514 * @see #ptSegDist(double, double, double, double, double, double)
516 public double ptSegDist(Point2D p)
518 return ptSegDist(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
522 * Measures the square of the shortest distance from the reference point
523 * to a point on the infinite line extended from the segment. If the point
524 * is on the segment, the result will be 0. If the segment is length 0,
525 * the distance is to the common endpoint.
527 * @param x1 the first x coordinate of the segment
528 * @param y1 the first y coordinate of the segment
529 * @param x2 the second x coordinate of the segment
530 * @param y2 the second y coordinate of the segment
531 * @param px the x coordinate of the point
532 * @param py the y coordinate of the point
533 * @return the square of the distance from the point to the extended line
534 * @see #ptLineDist(double, double, double, double, double, double)
535 * @see #ptSegDistSq(double, double, double, double, double, double)
537 public static double ptLineDistSq(double x1, double y1, double x2, double y2,
538 double px, double py)
540 double pd2 = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
542 double x, y;
543 if (pd2 == 0)
545 // Points are coincident.
546 x = x1;
547 y = y2;
549 else
551 double u = ((px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)) / pd2;
552 x = x1 + u * (x2 - x1);
553 y = y1 + u * (y2 - y1);
556 return (x - px) * (x - px) + (y - py) * (y - py);
560 * Measures the shortest distance from the reference point to a point on
561 * the infinite line extended from the segment. If the point is on the
562 * segment, the result will be 0. If the segment is length 0, the distance
563 * is to the common endpoint.
565 * @param x1 the first x coordinate of the segment
566 * @param y1 the first y coordinate of the segment
567 * @param x2 the second x coordinate of the segment
568 * @param y2 the second y coordinate of the segment
569 * @param px the x coordinate of the point
570 * @param py the y coordinate of the point
571 * @return the distance from the point to the extended line
572 * @see #ptLineDistSq(double, double, double, double, double, double)
573 * @see #ptSegDist(double, double, double, double, double, double)
575 public static double ptLineDist(double x1, double y1,
576 double x2, double y2,
577 double px, double py)
579 return Math.sqrt(ptLineDistSq(x1, y1, x2, y2, px, py));
583 * Measures the square of the shortest distance from the reference point
584 * to a point on the infinite line extended from this segment. If the point
585 * is on the segment, the result will be 0. If the segment is length 0,
586 * the distance is to the common endpoint.
588 * @param px the x coordinate of the point
589 * @param py the y coordinate of the point
590 * @return the square of the distance from the point to the extended line
591 * @see #ptLineDistSq(double, double, double, double, double, double)
593 public double ptLineDistSq(double px, double py)
595 return ptLineDistSq(getX1(), getY1(), getX2(), getY2(), px, py);
599 * Measures the square of the shortest distance from the reference point
600 * to a point on the infinite line extended from this segment. If the point
601 * is on the segment, the result will be 0. If the segment is length 0,
602 * the distance is to the common endpoint.
604 * @param p the point
605 * @return the square of the distance from the point to the extended line
606 * @throws NullPointerException if p is null
607 * @see #ptLineDistSq(double, double, double, double, double, double)
609 public double ptLineDistSq(Point2D p)
611 return ptLineDistSq(getX1(), getY1(), getX2(), getY2(),
612 p.getX(), p.getY());
616 * Measures the shortest distance from the reference point to a point on
617 * the infinite line extended from this segment. If the point is on the
618 * segment, the result will be 0. If the segment is length 0, the distance
619 * is to the common endpoint.
621 * @param px the x coordinate of the point
622 * @param py the y coordinate of the point
623 * @return the distance from the point to the extended line
624 * @see #ptLineDist(double, double, double, double, double, double)
626 public double ptLineDist(double px, double py)
628 return ptLineDist(getX1(), getY1(), getX2(), getY2(), px, py);
632 * Measures the shortest distance from the reference point to a point on
633 * the infinite line extended from this segment. If the point is on the
634 * segment, the result will be 0. If the segment is length 0, the distance
635 * is to the common endpoint.
637 * @param p the point
638 * @return the distance from the point to the extended line
639 * @throws NullPointerException if p is null
640 * @see #ptLineDist(double, double, double, double, double, double)
642 public double ptLineDist(Point2D p)
644 return ptLineDist(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
648 * Test if a point is contained inside the line. Since a line has no area,
649 * this returns false.
651 * @param x the x coordinate
652 * @param y the y coordinate
653 * @return false; the line does not contain points
655 public boolean contains(double x, double y)
657 return false;
661 * Test if a point is contained inside the line. Since a line has no area,
662 * this returns false.
664 * @param p the point
665 * @return false; the line does not contain points
667 public boolean contains(Point2D p)
669 return false;
673 * Tests if this line intersects the interior of the specified rectangle.
675 * @param x the x coordinate of the rectangle
676 * @param y the y coordinate of the rectangle
677 * @param w the width of the rectangle
678 * @param h the height of the rectangle
679 * @return true if the line intersects the rectangle
681 public boolean intersects(double x, double y, double w, double h)
683 if (w <= 0 || h <= 0)
684 return false;
685 double x1 = getX1();
686 double y1 = getY1();
687 double x2 = getX2();
688 double y2 = getY2();
690 if (x1 >= x && x1 <= x + w && y1 >= y && y1 <= y + h)
691 return true;
692 if (x2 >= x && x2 <= x + w && y2 >= y && y2 <= y + h)
693 return true;
695 double x3 = x + w;
696 double y3 = y + h;
698 return (linesIntersect(x1, y1, x2, y2, x, y, x, y3)
699 || linesIntersect(x1, y1, x2, y2, x, y3, x3, y3)
700 || linesIntersect(x1, y1, x2, y2, x3, y3, x3, y)
701 || linesIntersect(x1, y1, x2, y2, x3, y, x, y));
705 * Tests if this line intersects the interior of the specified rectangle.
707 * @param r the rectangle
708 * @return true if the line intersects the rectangle
709 * @throws NullPointerException if r is null
711 public boolean intersects(Rectangle2D r)
713 return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
717 * Tests if the line contains a rectangle. Since lines have no area, this
718 * always returns false.
720 * @param x the x coordinate of the rectangle
721 * @param y the y coordinate of the rectangle
722 * @param w the width of the rectangle
723 * @param h the height of the rectangle
724 * @return false; the line does not contain points
726 public boolean contains(double x, double y, double w, double h)
728 return false;
732 * Tests if the line contains a rectangle. Since lines have no area, this
733 * always returns false.
735 * @param r the rectangle
736 * @return false; the line does not contain points
738 public boolean contains(Rectangle2D r)
740 return false;
744 * Gets a bounding box (not necessarily minimal) for this line.
746 * @return the integer bounding box
747 * @see #getBounds2D()
749 public Rectangle getBounds()
751 return getBounds2D().getBounds();
755 * Return a path iterator, possibly applying a transform on the result. This
756 * iterator is not threadsafe.
758 * @param at the transform, or null
759 * @return a new path iterator
761 public PathIterator getPathIterator(final AffineTransform at)
763 return new PathIterator()
765 /** Current coordinate. */
766 private int current = 0;
768 public int getWindingRule()
770 return WIND_NON_ZERO;
773 public boolean isDone()
775 return current >= 2;
778 public void next()
780 current++;
783 public int currentSegment(float[] coords)
785 int result;
786 switch (current)
788 case 0:
789 coords[0] = (float) getX1();
790 coords[1] = (float) getY1();
791 result = SEG_MOVETO;
792 break;
793 case 1:
794 coords[0] = (float) getX2();
795 coords[1] = (float) getY2();
796 result = SEG_LINETO;
797 break;
798 default:
799 throw new NoSuchElementException("line iterator out of bounds");
801 if (at != null)
802 at.transform(coords, 0, coords, 0, 1);
803 return result;
806 public int currentSegment(double[] coords)
808 int result;
809 switch (current)
811 case 0:
812 coords[0] = getX1();
813 coords[1] = getY1();
814 result = SEG_MOVETO;
815 break;
816 case 1:
817 coords[0] = getX2();
818 coords[1] = getY2();
819 result = SEG_LINETO;
820 break;
821 default:
822 throw new NoSuchElementException("line iterator out of bounds");
824 if (at != null)
825 at.transform(coords, 0, coords, 0, 1);
826 return result;
832 * Return a flat path iterator, possibly applying a transform on the result.
833 * This iterator is not threadsafe.
835 * @param at the transform, or null
836 * @param flatness ignored, since lines are already flat
837 * @return a new path iterator
838 * @see #getPathIterator(AffineTransform)
840 public PathIterator getPathIterator(AffineTransform at, double flatness)
842 return getPathIterator(at);
846 * Create a new line of the same run-time type with the same contents as
847 * this one.
849 * @return the clone
851 * @exception OutOfMemoryError If there is not enough memory available.
853 * @since 1.2
855 public Object clone()
859 return super.clone();
861 catch (CloneNotSupportedException e)
863 throw (Error) new InternalError().initCause(e); // Impossible
868 * This class defines a point in <code>double</code> precision.
870 * @author Eric Blake (ebb9@email.byu.edu)
871 * @since 1.2
872 * @status updated to 1.4
874 public static class Double extends Line2D
876 /** The x coordinate of the first point. */
877 public double x1;
879 /** The y coordinate of the first point. */
880 public double y1;
882 /** The x coordinate of the second point. */
883 public double x2;
885 /** The y coordinate of the second point. */
886 public double y2;
889 * Construct the line segment (0,0)-&gt;(0,0).
891 public Double()
896 * Construct the line segment with the specified points.
898 * @param x1 the x coordinate of the first point
899 * @param y1 the y coordinate of the first point
900 * @param x2 the x coordinate of the second point
901 * @param y2 the y coordinate of the second point
903 public Double(double x1, double y1, double x2, double y2)
905 this.x1 = x1;
906 this.y1 = y1;
907 this.x2 = x2;
908 this.y2 = y2;
912 * Construct the line segment with the specified points.
914 * @param p1 the first point
915 * @param p2 the second point
916 * @throws NullPointerException if either point is null
918 public Double(Point2D p1, Point2D p2)
920 x1 = p1.getX();
921 y1 = p1.getY();
922 x2 = p2.getX();
923 y2 = p2.getY();
927 * Return the x coordinate of the first point.
929 * @return the value of x1
931 public double getX1()
933 return x1;
937 * Return the y coordinate of the first point.
939 * @return the value of y1
941 public double getY1()
943 return y1;
947 * Return the first point.
949 * @return the point (x1,y1)
951 public Point2D getP1()
953 return new Point2D.Double(x1, y1);
957 * Return the x coordinate of the second point.
959 * @return the value of x2
961 public double getX2()
963 return x2;
967 * Return the y coordinate of the second point.
969 * @return the value of y2
971 public double getY2()
973 return y2;
977 * Return the second point.
979 * @return the point (x2,y2)
981 public Point2D getP2()
983 return new Point2D.Double(x2, y2);
987 * Set this line to the given points.
989 * @param x1 the new x coordinate of the first point
990 * @param y1 the new y coordinate of the first point
991 * @param x2 the new x coordinate of the second point
992 * @param y2 the new y coordinate of the second point
994 public void setLine(double x1, double y1, double x2, double y2)
996 this.x1 = x1;
997 this.y1 = y1;
998 this.x2 = x2;
999 this.y2 = y2;
1003 * Return the exact bounds of this line segment.
1005 * @return the bounding box
1007 public Rectangle2D getBounds2D()
1009 double x = Math.min(x1, x2);
1010 double y = Math.min(y1, y2);
1011 double w = Math.abs(x1 - x2);
1012 double h = Math.abs(y1 - y2);
1013 return new Rectangle2D.Double(x, y, w, h);
1015 } // class Double
1018 * This class defines a point in <code>float</code> precision.
1020 * @author Eric Blake (ebb9@email.byu.edu)
1021 * @since 1.2
1022 * @status updated to 1.4
1024 public static class Float extends Line2D
1026 /** The x coordinate of the first point. */
1027 public float x1;
1029 /** The y coordinate of the first point. */
1030 public float y1;
1032 /** The x coordinate of the second point. */
1033 public float x2;
1035 /** The y coordinate of the second point. */
1036 public float y2;
1039 * Construct the line segment (0,0)-&gt;(0,0).
1041 public Float()
1046 * Construct the line segment with the specified points.
1048 * @param x1 the x coordinate of the first point
1049 * @param y1 the y coordinate of the first point
1050 * @param x2 the x coordinate of the second point
1051 * @param y2 the y coordinate of the second point
1053 public Float(float x1, float y1, float x2, float y2)
1055 this.x1 = x1;
1056 this.y1 = y1;
1057 this.x2 = x2;
1058 this.y2 = y2;
1062 * Construct the line segment with the specified points.
1064 * @param p1 the first point
1065 * @param p2 the second point
1066 * @throws NullPointerException if either point is null
1068 public Float(Point2D p1, Point2D p2)
1070 x1 = (float) p1.getX();
1071 y1 = (float) p1.getY();
1072 x2 = (float) p2.getX();
1073 y2 = (float) p2.getY();
1077 * Return the x coordinate of the first point.
1079 * @return the value of x1
1081 public double getX1()
1083 return x1;
1087 * Return the y coordinate of the first point.
1089 * @return the value of y1
1091 public double getY1()
1093 return y1;
1097 * Return the first point.
1099 * @return the point (x1,y1)
1101 public Point2D getP1()
1103 return new Point2D.Float(x1, y1);
1107 * Return the x coordinate of the second point.
1109 * @return the value of x2
1111 public double getX2()
1113 return x2;
1117 * Return the y coordinate of the second point.
1119 * @return the value of y2
1121 public double getY2()
1123 return y2;
1127 * Return the second point.
1129 * @return the point (x2,y2)
1131 public Point2D getP2()
1133 return new Point2D.Float(x2, y2);
1137 * Set this line to the given points.
1139 * @param x1 the new x coordinate of the first point
1140 * @param y1 the new y coordinate of the first point
1141 * @param x2 the new x coordinate of the second point
1142 * @param y2 the new y coordinate of the second point
1144 public void setLine(double x1, double y1, double x2, double y2)
1146 this.x1 = (float) x1;
1147 this.y1 = (float) y1;
1148 this.x2 = (float) x2;
1149 this.y2 = (float) y2;
1153 * Set this line to the given points.
1155 * @param x1 the new x coordinate of the first point
1156 * @param y1 the new y coordinate of the first point
1157 * @param x2 the new x coordinate of the second point
1158 * @param y2 the new y coordinate of the second point
1160 public void setLine(float x1, float y1, float x2, float y2)
1162 this.x1 = x1;
1163 this.y1 = y1;
1164 this.x2 = x2;
1165 this.y2 = y2;
1169 * Return the exact bounds of this line segment.
1171 * @return the bounding box
1173 public Rectangle2D getBounds2D()
1175 float x = Math.min(x1, x2);
1176 float y = Math.min(y1, y2);
1177 float w = Math.abs(x1 - x2);
1178 float h = Math.abs(y1 - y2);
1179 return new Rectangle2D.Float(x, y, w, h);
1181 } // class Float
1182 } // class Line2D