2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / libjava / java / awt / geom / Arc2D.java
blob2eb9650cf884ab707f632c06a684ba74904fefae
1 /* Arc2D.java -- represents an arc in 2-D space
2 Copyright (C) 2002, 2003 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. */
39 package java.awt.geom;
41 import java.util.NoSuchElementException;
43 /**
44 * This class represents all arcs (segments of an ellipse in 2-D space). The
45 * arcs are defined by starting angle and extent (arc length) in degrees, as
46 * opposed to radians (like the rest of Java), and can be open, chorded, or
47 * wedge shaped. The angles are skewed according to the ellipse, so that 45
48 * degrees always points to the upper right corner (positive x, negative y)
49 * of the bounding rectangle. A positive extent draws a counterclockwise arc,
50 * and while the angle can be any value, the path iterator only traverses the
51 * first 360 degrees. Storage is up to the subclasses.
53 * @author Eric Blake <ebb9@email.byu.edu>
54 * @since 1.2
55 * @status updated to 1.4, but still missing functionality
57 public abstract class Arc2D extends RectangularShape
59 /**
60 * An open arc, with no segment connecting the endpoints. This type of
61 * arc still contains the same points as a chorded version.
63 public static final int OPEN = 0;
65 /**
66 * A closed arc with a single segment connecting the endpoints (a chord).
68 public static final int CHORD = 1;
70 /**
71 * A closed arc with two segments, one from each endpoint, meeting at the
72 * center of the ellipse.
74 public static final int PIE = 2;
76 /** The closure type of this arc. */
77 private int type;
79 /**
80 * Create a new arc, with the specified closure type.
82 * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}.
83 * @throws IllegalArgumentException if type is invalid
85 protected Arc2D(int type)
87 if (type < OPEN || type > PIE)
88 throw new IllegalArgumentException();
89 this.type = type;
92 /**
93 * Get the starting angle of the arc in degrees.
95 * @return the starting angle
96 * @see #setAngleStart(double)
98 public abstract double getAngleStart();
101 * Get the extent angle of the arc in degrees.
103 * @return the extent angle
104 * @see #setAngleExtent(double)
106 public abstract double getAngleExtent();
109 * Return the closure type of the arc.
111 * @return the closure type
112 * @see #OPEN
113 * @see #CHORD
114 * @see #PIE
115 * @see #setArcType(int)
117 public int getArcType()
119 return type;
123 * Returns the starting point of the arc.
125 * @return the start point
127 public Point2D getStartPoint()
129 double angle = Math.toRadians(getAngleStart());
130 double rx = getWidth() / 2;
131 double ry = getHeight() / 2;
132 double x = getX() + rx + rx * Math.cos(angle);
133 double y = getY() + ry - ry * Math.sin(angle);
134 return new Point2D.Double(x, y);
138 * Returns the ending point of the arc.
140 * @return the end point
142 public Point2D getEndPoint()
144 double angle = Math.toRadians(getAngleStart() + getAngleExtent());
145 double rx = getWidth() / 2;
146 double ry = getHeight() / 2;
147 double x = getX() + rx + rx * Math.cos(angle);
148 double y = getY() + ry - ry * Math.sin(angle);
149 return new Point2D.Double(x, y);
153 * Set the parameters of the arc. The angles are in degrees, and a positive
154 * extent sweeps counterclockwise (from the positive x-axis to the negative
155 * y-axis).
157 * @param x the new x coordinate of the lower left of the bounding box
158 * @param y the new y coordinate of the lower left of the bounding box
159 * @param w the new width of the bounding box
160 * @param h the new height of the bounding box
161 * @param start the start angle, in degrees
162 * @param extent the arc extent, in degrees
163 * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
164 * @throws IllegalArgumentException if type is invalid
166 public abstract void setArc(double x, double y, double w, double h,
167 double start, double extent, int type);
170 * Set the parameters of the arc. The angles are in degrees, and a positive
171 * extent sweeps counterclockwise (from the positive x-axis to the negative
172 * y-axis).
174 * @param p the lower left point of the bounding box
175 * @param d the dimensions of the bounding box
176 * @param start the start angle, in degrees
177 * @param extent the arc extent, in degrees
178 * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
179 * @throws IllegalArgumentException if type is invalid
180 * @throws NullPointerException if p or d is null
182 public void setArc(Point2D p, Dimension2D d,
183 double start, double extent, int type)
185 setArc(p.getX(), p.getY(), d.getWidth(), d.getHeight(),
186 start, extent, type);
190 * Set the parameters of the arc. The angles are in degrees, and a positive
191 * extent sweeps counterclockwise (from the positive x-axis to the negative
192 * y-axis).
194 * @param r the new bounding box
195 * @param start the start angle, in degrees
196 * @param extent the arc extent, in degrees
197 * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
198 * @throws IllegalArgumentException if type is invalid
199 * @throws NullPointerException if r is null
201 public void setArc(Rectangle2D r, double start, double extent, int type)
203 setArc(r.getX(), r.getY(), r.getWidth(), r.getHeight(),
204 start, extent, type);
208 * Set the parameters of the arc from the given one.
210 * @param a the arc to copy
211 * @throws NullPointerException if a is null
213 public void setArc(Arc2D a)
215 setArc(a.getX(), a.getY(), a.getWidth(), a.getHeight(),
216 a.getAngleStart(), a.getAngleExtent(), a.getArcType());
220 * Set the parameters of the arc. The angles are in degrees, and a positive
221 * extent sweeps counterclockwise (from the positive x-axis to the negative
222 * y-axis). This controls the center point and radius, so the arc will be
223 * circular.
225 * @param x the x coordinate of the center of the circle
226 * @param y the y coordinate of the center of the circle
227 * @param r the radius of the circle
228 * @param start the start angle, in degrees
229 * @param extent the arc extent, in degrees
230 * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
231 * @throws IllegalArgumentException if type is invalid
233 public void setArcByCenter(double x, double y, double r,
234 double start, double extent, int type)
236 setArc(x - r, y - r, r + r, r + r, start, extent, type);
240 * Sets the parameters of the arc by finding the tangents of two lines, and
241 * using the specified radius. The arc will be circular, will begin on the
242 * tangent point of the line extending from p1 to p2, and will end on the
243 * tangent point of the line extending from p2 to p3.
245 * XXX What happens if the points are colinear, or the radius negative?
247 * @param p1 the first point
248 * @param p2 the tangent line intersection point
249 * @param p3 the third point
250 * @param r the radius of the arc
251 * @throws NullPointerException if any point is null
253 public void setArcByTangent(Point2D p1, Point2D p2, Point2D p3, double r)
255 // XXX Implement.
256 throw new Error("not implemented");
260 * Set the start, in degrees.
262 * @param start the new start angle
263 * @see #getAngleStart()
265 public abstract void setAngleStart(double start);
268 * Set the extent, in degrees.
270 * @param extent the new extent angle
271 * @see #getAngleExtent()
273 public abstract void setAngleExtent(double extent);
276 * Sets the starting angle to the angle of the given point relative to
277 * the center of the arc. The extent remains constant; in other words,
278 * this rotates the arc.
280 * @param p the new start point
281 * @throws NullPointerException if p is null
282 * @see #getStartPoint()
283 * @see #getAngleStart()
285 public void setAngleStart(Point2D p)
287 // Normalize.
288 double x = p.getX() - (getX() + getWidth() / 2);
289 double y = p.getY() - (getY() + getHeight() / 2);
290 setAngleStart(Math.toDegrees(Math.atan2(y, x)));
294 * Sets the starting and extent angles to those of the given points
295 * relative to the center of the arc. The arc will be non-empty, and will
296 * extend counterclockwise.
298 * @param x1 the first x coordinate
299 * @param y1 the first y coordinate
300 * @param x2 the second x coordinate
301 * @param y2 the second y coordinate
302 * @see #setAngleStart(Point2D)
304 public void setAngles(double x1, double y1, double x2, double y2)
306 // Normalize the points.
307 double mx = getX();
308 double my = getY();
309 double mw = getWidth();
310 double mh = getHeight();
311 x1 = x1 - (mx + mw / 2);
312 y1 = y1 - (my + mh / 2);
313 x2 = x2 - (mx + mw / 2);
314 y2 = y2 - (my + mh / 2);
315 double start = Math.toDegrees(Math.atan2(y1, x1));
316 double extent = Math.toDegrees(Math.atan2(y2, x2)) - start;
317 if (extent < 0)
318 extent += 360;
319 setAngleStart(start);
320 setAngleExtent(extent);
324 * Sets the starting and extent angles to those of the given points
325 * relative to the center of the arc. The arc will be non-empty, and will
326 * extend counterclockwise.
328 * @param p1 the first point
329 * @param p2 the second point
330 * @throws NullPointerException if either point is null
331 * @see #setAngleStart(Point2D)
333 public void setAngles(Point2D p1, Point2D p2)
335 setAngles(p1.getX(), p1.getY(), p2.getX(), p2.getY());
339 * Set the closure type of this arc.
341 * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
342 * @throws IllegalArgumentException if type is invalid
343 * @see #getArcType()
345 public void setArcType(int type)
347 if (type < OPEN || type > PIE)
348 throw new IllegalArgumentException();
349 this.type = type;
353 * Sets the location and bounds of the ellipse of which this arc is a part.
355 * @param x the new x coordinate
356 * @param y the new y coordinate
357 * @param w the new width
358 * @param h the new height
359 * @see #getFrame()
361 public void setFrame(double x, double y, double w, double h)
363 setArc(x, y, w, h, getAngleStart(), getAngleExtent(), type);
367 * Gets the bounds of the arc. This is much tighter than
368 * <code>getBounds</code>, as it takes into consideration the start and
369 * end angles, and the center point of a pie wedge, rather than just the
370 * overall ellipse.
372 * @return the bounds of the arc
373 * @see #getBounds()
375 public Rectangle2D getBounds2D()
377 double extent = getAngleExtent();
378 if (Math.abs(extent) >= 360)
379 return makeBounds(getX(), getY(), getWidth(), getHeight());
381 // Find the minimal bounding box. This determined by its extrema,
382 // which are the center, the endpoints of the arc, and any local
383 // maximum contained by the arc.
384 double rX = getWidth() / 2;
385 double rY = getHeight() / 2;
386 double centerX = getX() + rX;
387 double centerY = getY() + rY;
389 Point2D p1 = getStartPoint();
390 Rectangle2D result = makeBounds(p1.getX(), p1.getY(), 0, 0);
391 result.add(getEndPoint());
393 if (type == PIE)
394 result.add(centerX, centerY);
395 if (containsAngle(0))
396 result.add(centerX + rX, centerY);
397 if (containsAngle(90))
398 result.add(centerX, centerY - rY);
399 if (containsAngle(180))
400 result.add(centerX - rX, centerY);
401 if (containsAngle(270))
402 result.add(centerX, centerY + rY);
404 return result;
408 * Construct a bounding box in a precision appropriate for the subclass.
410 * @param x the x coordinate
411 * @param y the y coordinate
412 * @param w the width
413 * @param h the height
414 * @return the rectangle for use in getBounds2D
416 protected abstract Rectangle2D makeBounds(double x, double y,
417 double w, double h);
420 * Tests if the given angle, in degrees, is included in the arc.
421 * All angles are normalized to be between 0 and 360 degrees.
423 * @param a the angle to test
424 * @return true if it is contained
426 public boolean containsAngle(double a)
428 double start = getAngleStart();
429 double end = start + getAngleExtent();
431 start %= 360;
432 if (start < 0)
433 start += 360;
435 end %= 360;
436 if (end < 0)
437 end += 360;
439 a %= 360;
440 if (a < 0)
441 a += 360;
443 return a >= start && a <= end;
447 * Determines if the arc contains the given point. If the bounding box
448 * is empty, then this will return false.
450 * @param x the x coordinate to test
451 * @param y the y coordinate to test
452 * @return true if the point is inside the arc
454 public boolean contains(double x, double y)
456 double w = getWidth();
457 double h = getHeight();
458 if (w <= 0 || h <= 0)
459 return false;
460 // XXX Finish implementing.
461 throw new Error("not implemented");
465 * Tests if a given rectangle intersects the area of the arc.
467 * @param x the x coordinate of the rectangle
468 * @param y the y coordinate of the rectangle
469 * @param w the width of the rectangle
470 * @param h the height of the rectangle
471 * @return true if the two shapes share common points
473 public boolean intersects(double x, double y, double w, double h)
475 double mw = getWidth();
476 double mh = getHeight();
477 if (mw <= 0 || mh <= 0 || w <= 0 || h <= 0)
478 return false;
479 // XXX Finish implementing.
480 throw new Error("not implemented");
484 * Tests if a given rectangle is contained in the area of the arc.
486 * @param x the x coordinate of the rectangle
487 * @param y the y coordinate of the rectangle
488 * @param w the width of the rectangle
489 * @param h the height of the rectangle
490 * @return true if the arc contains the rectangle
492 public boolean contains(double x, double y, double w, double h)
494 double mw = getWidth();
495 double mh = getHeight();
496 if (mw <= 0 || mh <= 0 || w <= 0 || h <= 0)
497 return false;
498 // XXX Finish implementing.
499 throw new Error("not implemented");
503 * Tests if a given rectangle is contained in the area of the arc.
505 * @param r the rectangle
506 * @return true if the arc contains the rectangle
508 public boolean contains(Rectangle2D r)
510 return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
514 * Returns an iterator over this arc, with an optional transformation.
515 * This iterator is threadsafe, so future modifications to the arc do not
516 * affect the iteration.
518 * @param at the transformation, or null
519 * @return a path iterator
521 public PathIterator getPathIterator(AffineTransform at)
523 return new ArcIterator(this, at);
527 * This class is used to iterate over an arc. Since ellipses are a subclass
528 * of arcs, this is used by Ellipse2D as well.
530 * @author Eric Blake <ebb9@email.byu.edu>
532 static final class ArcIterator implements PathIterator
534 /** The current iteration. */
535 private int current;
537 /** The last iteration. */
538 private final int limit;
540 /** The optional transformation. */
541 private final AffineTransform xform;
543 /** The x coordinate of the bounding box. */
544 private final double x;
546 /** The y coordinate of the bounding box. */
547 private final double y;
549 /** The width of the bounding box. */
550 private final double w;
552 /** The height of the bounding box. */
553 private final double h;
555 /** The start angle, in radians (not degrees). */
556 private final double start;
558 /** The extent angle, in radians (not degrees). */
559 private final double extent;
561 /** The arc closure type. */
562 private final int type;
565 * Construct a new iterator over an arc.
567 * @param a the arc
568 * @param xform the transform
570 ArcIterator(Arc2D a, AffineTransform xform)
572 this.xform = xform;
573 x = a.getX();
574 y = a.getY();
575 w = a.getWidth();
576 h = a.getHeight();
577 start = a.getAngleStart() * (Math.PI / 180);
578 extent = a.getAngleExtent() * (Math.PI / 180);
579 type = a.type;
580 double e = extent < 0 ? -extent : extent;
581 if (w < 0 || h < 0)
582 limit = -1;
583 else if (e == 0)
584 limit = type;
585 else if (e <= Math.PI / 2.0)
586 limit = type + 1;
587 else if (e <= Math.PI)
588 limit = type + 2;
589 else if (e <= 3.0 * (Math.PI / 2.0))
590 limit = type + 3;
591 else
592 limit = type + 4;
596 * Construct a new iterator over an ellipse.
598 * @param e the ellipse
599 * @param xform the transform
601 ArcIterator(Ellipse2D e, AffineTransform xform)
603 this.xform = xform;
604 x = e.getX();
605 y = e.getY();
606 w = e.getWidth();
607 h = e.getHeight();
608 start = 0;
609 extent = -2 * Math.PI;
610 type = CHORD;
611 limit = (w < 0 || h < 0) ? -1 : 5;
615 * Return the winding rule.
617 * @return {@link PathIterator#WIND_NON_ZERO}
619 public int getWindingRule()
621 return WIND_NON_ZERO;
625 * Test if the iteration is complete.
627 * @return true if more segments exist
629 public boolean isDone()
631 return current > limit;
635 * Advance the iterator.
637 public void next()
639 current++;
643 * Put the current segment into the array, and return the segment type.
645 * @param coords an array of 6 elements
646 * @return the segment type
647 * @throws NullPointerException if coords is null
648 * @throws ArrayIndexOutOfBoundsException if coords is too small
650 public int currentSegment(float[] coords)
652 double[] double_coords = new double[6];
653 int code = currentSegment (double_coords);
654 for (int i = 0; i < 6; ++i)
655 coords[i] = (float) double_coords[i];
656 return code;
660 * Put the current segment into the array, and return the segment type.
662 * @param coords an array of 6 elements
663 * @return the segment type
664 * @throws NullPointerException if coords is null
665 * @throws ArrayIndexOutOfBoundsException if coords is too small
667 public int currentSegment(double[] coords)
669 double rx = w/2;
670 double ry = h/2;
671 double xmid = x + rx;
672 double ymid = y + ry;
674 if (current > limit)
675 throw new NoSuchElementException("arc iterator out of bounds");
677 if (current == 0)
679 coords[0] = xmid + rx * Math.cos(start);
680 coords[1] = ymid - ry * Math.sin(start);
681 if (xform != null)
682 xform.transform(coords, 0, coords, 0, 1);
683 return SEG_MOVETO;
686 if (type != OPEN && current == limit)
687 return SEG_CLOSE;
689 if ((current == limit - 1) &&
690 (type == PIE) || (type == CHORD))
692 if (type == PIE)
694 coords[0] = xmid;
695 coords[1] = ymid;
697 else if (type == CHORD)
699 coords[0] = xmid + rx * Math.cos(start);
700 coords[1] = ymid - ry * Math.sin(start);
702 if (xform != null)
703 xform.transform(coords, 0, coords, 0, 1);
704 return SEG_LINETO;
707 // note that this produces a cubic approximation of the arc segment,
708 // not a true ellipsoid. there's no ellipsoid path segment code,
709 // unfortunately. the cubic approximation looks about right, though.
711 double kappa = (Math.sqrt(2.0) - 1.0) * (4.0 / 3.0);
712 double quad = (Math.PI / 2.0);
714 double curr_begin = start + (current - 1) * quad;
715 double curr_extent = Math.min((start + extent) - curr_begin, quad);
716 double portion_of_a_quadrant = curr_extent / quad;
718 double x0 = xmid + rx * Math.cos(curr_begin);
719 double y0 = ymid - ry * Math.sin(curr_begin);
721 double x1 = xmid + rx * Math.cos(curr_begin + curr_extent);
722 double y1 = ymid - ry * Math.sin(curr_begin + curr_extent);
724 AffineTransform trans = new AffineTransform ();
725 double [] cvec = new double[2];
726 double len = kappa * portion_of_a_quadrant;
727 double angle = curr_begin;
729 // in a hypothetical "first quadrant" setting, our first control
730 // vector would be sticking up, from [1,0] to [1,kappa].
732 // let us recall however that in java2d, y coords are upside down
733 // from what one would consider "normal" first quadrant rules, so we
734 // will *subtract* the y value of this control vector from our first
735 // point.
737 cvec[0] = 0;
738 cvec[1] = len;
739 trans.scale (rx, ry);
740 trans.rotate (angle);
741 trans.transform(cvec, 0, cvec, 0, 1);
742 coords[0] = x0 + cvec[0];
743 coords[1] = y0 - cvec[1];
745 // control vector #2 would, ideally, be sticking out and to the
746 // right, in a first quadrant arc segment. again, subtraction of y.
748 cvec[0] = 0;
749 cvec[1] = -len;
750 trans.rotate (curr_extent);
751 trans.transform(cvec, 0, cvec, 0, 1);
752 coords[2] = x1 + cvec[0];
753 coords[3] = y1 - cvec[1];
755 // end point
756 coords[4] = x1;
757 coords[5] = y1;
759 if (xform != null)
760 xform.transform(coords, 0, coords, 0, 3);
762 return SEG_CUBICTO;
764 } // class ArcIterator
767 * This class implements an arc in double precision.
769 * @author Eric Blake <ebb9@email.byu.edu
770 * @since 1.2
772 public static class Double extends Arc2D
774 /** The x coordinate of the box bounding the ellipse of this arc. */
775 public double x;
777 /** The y coordinate of the box bounding the ellipse of this arc. */
778 public double y;
780 /** The width of the box bounding the ellipse of this arc. */
781 public double width;
783 /** The height of the box bounding the ellipse of this arc. */
784 public double height;
786 /** The start angle of this arc, in degrees. */
787 public double start;
789 /** The extent angle of this arc, in degrees. */
790 public double extent;
793 * Create a new, open arc at (0,0) with 0 extent.
795 public Double()
797 super(OPEN);
801 * Create a new arc of the given type at (0,0) with 0 extent.
803 * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
804 * @throws IllegalArgumentException if type is invalid
806 public Double(int type)
808 super(type);
812 * Create a new arc with the given dimensions.
814 * @param x the x coordinate
815 * @param y the y coordinate
816 * @param w the width
817 * @param h the height
818 * @param start the start angle, in degrees
819 * @param extent the extent, in degrees
820 * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
821 * @throws IllegalArgumentException if type is invalid
823 public Double(double x, double y, double w, double h,
824 double start, double extent, int type)
826 super(type);
827 this.x = x;
828 this.y = y;
829 width = w;
830 height = h;
831 this.start = start;
832 this.extent = extent;
836 * Create a new arc with the given dimensions.
838 * @param r the bounding box
839 * @param start the start angle, in degrees
840 * @param extent the extent, in degrees
841 * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
842 * @throws IllegalArgumentException if type is invalid
843 * @throws NullPointerException if r is null
845 public Double(Rectangle2D r, double start, double extent, int type)
847 super(type);
848 x = r.getX();
849 y = r.getY();
850 width = r.getWidth();
851 height = r.getHeight();
852 this.start = start;
853 this.extent = extent;
857 * Return the x coordinate of the bounding box.
859 * @return the value of x
861 public double getX()
863 return x;
867 * Return the y coordinate of the bounding box.
869 * @return the value of y
871 public double getY()
873 return y;
877 * Return the width of the bounding box.
879 * @return the value of width
881 public double getWidth()
883 return width;
887 * Return the height of the bounding box.
889 * @return the value of height
891 public double getHeight()
893 return height;
897 * Return the start angle of the arc, in degrees.
899 * @return the value of start
901 public double getAngleStart()
903 return start;
907 * Return the extent of the arc, in degrees.
909 * @return the value of extent
911 public double getAngleExtent()
913 return extent;
917 * Tests if the arc contains points.
919 * @return true if the arc has no interior
921 public boolean isEmpty()
923 return width <= 0 || height <= 0;
927 * Sets the arc to the given dimensions.
929 * @param x the x coordinate
930 * @param y the y coordinate
931 * @param w the width
932 * @param h the height
933 * @param start the start angle, in degrees
934 * @param extent the extent, in degrees
935 * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
936 * @throws IllegalArgumentException if type is invalid
938 public void setArc(double x, double y, double w, double h,
939 double start, double extent, int type)
941 this.x = x;
942 this.y = y;
943 width = w;
944 height = h;
945 this.start = start;
946 this.extent = extent;
947 setArcType(type);
951 * Sets the start angle of the arc.
953 * @param start the new start angle
955 public void setAngleStart(double start)
957 this.start = start;
961 * Sets the extent angle of the arc.
963 * @param start the new extent angle
965 public void setAngleExtent(double extent)
967 this.extent = extent;
971 * Creates a tight bounding box given dimensions that more precise than
972 * the bounding box of the ellipse.
974 * @param x the x coordinate
975 * @param y the y coordinate
976 * @param w the width
977 * @param h the height
979 protected Rectangle2D makeBounds(double x, double y, double w, double h)
981 return new Rectangle2D.Double(x, y, w, h);
983 } // class Double
986 * This class implements an arc in float precision.
988 * @author Eric Blake <ebb9@email.byu.edu
989 * @since 1.2
991 public static class Float extends Arc2D
993 /** The x coordinate of the box bounding the ellipse of this arc. */
994 public float x;
996 /** The y coordinate of the box bounding the ellipse of this arc. */
997 public float y;
999 /** The width of the box bounding the ellipse of this arc. */
1000 public float width;
1002 /** The height of the box bounding the ellipse of this arc. */
1003 public float height;
1005 /** The start angle of this arc, in degrees. */
1006 public float start;
1008 /** The extent angle of this arc, in degrees. */
1009 public float extent;
1012 * Create a new, open arc at (0,0) with 0 extent.
1014 public Float()
1016 super(OPEN);
1020 * Create a new arc of the given type at (0,0) with 0 extent.
1022 * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
1023 * @throws IllegalArgumentException if type is invalid
1025 public Float(int type)
1027 super(type);
1031 * Create a new arc with the given dimensions.
1033 * @param x the x coordinate
1034 * @param y the y coordinate
1035 * @param w the width
1036 * @param h the height
1037 * @param start the start angle, in degrees
1038 * @param extent the extent, in degrees
1039 * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
1040 * @throws IllegalArgumentException if type is invalid
1042 public Float(float x, float y, float w, float h,
1043 float start, float extent, int type)
1045 super(type);
1046 this.x = x;
1047 this.y = y;
1048 width = w;
1049 height = h;
1050 this.start = start;
1051 this.extent = extent;
1055 * Create a new arc with the given dimensions.
1057 * @param r the bounding box
1058 * @param start the start angle, in degrees
1059 * @param extent the extent, in degrees
1060 * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
1061 * @throws IllegalArgumentException if type is invalid
1062 * @throws NullPointerException if r is null
1064 public Float(Rectangle2D r, float start, float extent, int type)
1066 super(type);
1067 x = (float) r.getX();
1068 y = (float) r.getY();
1069 width = (float) r.getWidth();
1070 height = (float) r.getHeight();
1071 this.start = start;
1072 this.extent = extent;
1076 * Return the x coordinate of the bounding box.
1078 * @return the value of x
1080 public double getX()
1082 return x;
1086 * Return the y coordinate of the bounding box.
1088 * @return the value of y
1090 public double getY()
1092 return y;
1096 * Return the width of the bounding box.
1098 * @return the value of width
1100 public double getWidth()
1102 return width;
1106 * Return the height of the bounding box.
1108 * @return the value of height
1110 public double getHeight()
1112 return height;
1116 * Return the start angle of the arc, in degrees.
1118 * @return the value of start
1120 public double getAngleStart()
1122 return start;
1126 * Return the extent of the arc, in degrees.
1128 * @return the value of extent
1130 public double getAngleExtent()
1132 return extent;
1136 * Tests if the arc contains points.
1138 * @return true if the arc has no interior
1140 public boolean isEmpty()
1142 return width <= 0 || height <= 0;
1146 * Sets the arc to the given dimensions.
1148 * @param x the x coordinate
1149 * @param y the y coordinate
1150 * @param w the width
1151 * @param h the height
1152 * @param start the start angle, in degrees
1153 * @param extent the extent, in degrees
1154 * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
1155 * @throws IllegalArgumentException if type is invalid
1157 public void setArc(double x, double y, double w, double h,
1158 double start, double extent, int type)
1160 this.x = (float) x;
1161 this.y = (float) y;
1162 width = (float) w;
1163 height = (float) h;
1164 this.start = (float) start;
1165 this.extent = (float) extent;
1166 setArcType(type);
1170 * Sets the start angle of the arc.
1172 * @param start the new start angle
1174 public void setAngleStart(double start)
1176 this.start = (float) start;
1180 * Sets the extent angle of the arc.
1182 * @param start the new extent angle
1184 public void setAngleExtent(double extent)
1186 this.extent = (float) extent;
1190 * Creates a tight bounding box given dimensions that more precise than
1191 * the bounding box of the ellipse.
1193 * @param x the x coordinate
1194 * @param y the y coordinate
1195 * @param w the width
1196 * @param h the height
1198 protected Rectangle2D makeBounds(double x, double y, double w, double h)
1200 return new Rectangle2D.Float((float) x, (float) y, (float) w, (float) h);
1202 } // class Float
1203 } // class Arc2D