source: trunk/gcc/libjava/java/awt/geom/Arc2D.java

Last change on this file was 1389, checked in by bird, 21 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 30.6 KB
Line 
1/* Arc2D.java -- represents an arc in 2-D space
2 Copyright (C) 2002 Free Software Foundation
3
4This file is part of GNU Classpath.
5
6GNU Classpath is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Classpath is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Classpath; see the file COPYING. If not, write to the
18Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1902111-1307 USA.
20
21Linking this library statically or dynamically with other modules is
22making a combined work based on this library. Thus, the terms and
23conditions of the GNU General Public License cover the whole
24combination.
25
26As a special exception, the copyright holders of this library give you
27permission to link this library with independent modules to produce an
28executable, regardless of the license terms of these independent
29modules, and to copy and distribute the resulting executable under
30terms of your choice, provided that you also meet, for each linked
31independent module, the terms and conditions of the license of that
32module. An independent module is a module which is not derived from
33or based on this library. If you modify this library, you may extend
34this exception to your version of the library, but you are not
35obligated to do so. If you do not wish to do so, delete this
36exception statement from your version. */
37
38
39package java.awt.geom;
40
41import java.util.NoSuchElementException;
42
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.
52 *
53 * @author Eric Blake <ebb9@email.byu.edu>
54 * @since 1.2
55 * @status updated to 1.4, but still missing functionality
56 */
57public abstract class Arc2D extends RectangularShape
58{
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.
62 */
63 public static final int OPEN = 0;
64
65 /**
66 * A closed arc with a single segment connecting the endpoints (a chord).
67 */
68 public static final int CHORD = 1;
69
70 /**
71 * A closed arc with two segments, one from each endpoint, meeting at the
72 * center of the ellipse.
73 */
74 public static final int PIE = 2;
75
76 /** The closure type of this arc. */
77 private int type;
78
79 /**
80 * Create a new arc, with the specified closure type.
81 *
82 * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}.
83 * @throws IllegalArgumentException if type is invalid
84 */
85 protected Arc2D(int type)
86 {
87 if (type < OPEN || type > PIE)
88 throw new IllegalArgumentException();
89 this.type = type;
90 }
91
92 /**
93 * Get the starting angle of the arc in degrees.
94 *
95 * @return the starting angle
96 * @see #setAngleStart(double)
97 */
98 public abstract double getAngleStart();
99
100 /**
101 * Get the extent angle of the arc in degrees.
102 *
103 * @return the extent angle
104 * @see #setAngleExtent(double)
105 */
106 public abstract double getAngleExtent();
107
108 /**
109 * Return the closure type of the arc.
110 *
111 * @return the closure type
112 * @see #OPEN
113 * @see #CHORD
114 * @see #PIE
115 * @see #setArcType(int)
116 */
117 public int getArcType()
118 {
119 return type;
120 }
121
122 /**
123 * Returns the starting point of the arc.
124 *
125 * @return the start point
126 */
127 public Point2D getStartPoint()
128 {
129 double angle = getAngleStart() * (-180 / Math.PI);
130 double x = (Math.cos(angle) * getWidth() + getX()) / 2;
131 double y = (Math.sin(angle) * getHeight() + getY()) / 2;
132 return new Point2D.Double(x, y);
133 }
134
135 /**
136 * Returns the ending point of the arc.
137 *
138 * @return the end point
139 */
140 public Point2D getEndPoint()
141 {
142 double angle = (getAngleStart() + getAngleExtent()) * (-180 / Math.PI);
143 double x = (Math.cos(angle) * getWidth() + getX()) / 2;
144 double y = (Math.sin(angle) * getHeight() + getY()) / 2;
145 return new Point2D.Double(x, y);
146 }
147
148 /**
149 * Set the parameters of the arc. The angles are in degrees, and a positive
150 * extent sweeps counterclockwise (from the positive x-axis to the negative
151 * y-axis).
152 *
153 * @param x the new x coordinate of the lower left of the bounding box
154 * @param y the new y coordinate of the lower left of the bounding box
155 * @param w the new width of the bounding box
156 * @param h the new height of the bounding box
157 * @param start the start angle, in degrees
158 * @param extent the arc extent, in degrees
159 * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
160 * @throws IllegalArgumentException if type is invalid
161 */
162 public abstract void setArc(double x, double y, double w, double h,
163 double start, double extent, int type);
164
165 /**
166 * Set the parameters of the arc. The angles are in degrees, and a positive
167 * extent sweeps counterclockwise (from the positive x-axis to the negative
168 * y-axis).
169 *
170 * @param p the lower left point of the bounding box
171 * @param d the dimensions of the bounding box
172 * @param start the start angle, in degrees
173 * @param extent the arc extent, in degrees
174 * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
175 * @throws IllegalArgumentException if type is invalid
176 * @throws NullPointerException if p or d is null
177 */
178 public void setArc(Point2D p, Dimension2D d,
179 double start, double extent, int type)
180 {
181 setArc(p.getX(), p.getY(), d.getWidth(), d.getHeight(),
182 start, extent, type);
183 }
184
185 /**
186 * Set the parameters of the arc. The angles are in degrees, and a positive
187 * extent sweeps counterclockwise (from the positive x-axis to the negative
188 * y-axis).
189 *
190 * @param r the new bounding box
191 * @param start the start angle, in degrees
192 * @param extent the arc extent, in degrees
193 * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
194 * @throws IllegalArgumentException if type is invalid
195 * @throws NullPointerException if r is null
196 */
197 public void setArc(Rectangle2D r, double start, double extent, int type)
198 {
199 setArc(r.getX(), r.getY(), r.getWidth(), r.getHeight(),
200 start, extent, type);
201 }
202
203 /**
204 * Set the parameters of the arc from the given one.
205 *
206 * @param a the arc to copy
207 * @throws NullPointerException if a is null
208 */
209 public void setArc(Arc2D a)
210 {
211 setArc(a.getX(), a.getY(), a.getWidth(), a.getHeight(),
212 a.getAngleStart(), a.getAngleExtent(), a.getArcType());
213 }
214
215 /**
216 * Set the parameters of the arc. The angles are in degrees, and a positive
217 * extent sweeps counterclockwise (from the positive x-axis to the negative
218 * y-axis). This controls the center point and radius, so the arc will be
219 * circular.
220 *
221 * @param x the x coordinate of the center of the circle
222 * @param y the y coordinate of the center of the circle
223 * @param r the radius of the circle
224 * @param start the start angle, in degrees
225 * @param extent the arc extent, in degrees
226 * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
227 * @throws IllegalArgumentException if type is invalid
228 */
229 public void setArcByCenter(double x, double y, double r,
230 double start, double extent, int type)
231 {
232 setArc(x - r, y - r, r + r, r + r, start, extent, type);
233 }
234
235 /**
236 * Sets the parameters of the arc by finding the tangents of two lines, and
237 * using the specified radius. The arc will be circular, will begin on the
238 * tangent point of the line extending from p1 to p2, and will end on the
239 * tangent point of the line extending from p2 to p3.
240 *
241 * XXX What happens if the points are colinear, or the radius negative?
242 *
243 * @param p1 the first point
244 * @param p2 the tangent line intersection point
245 * @param p3 the third point
246 * @param r the radius of the arc
247 * @throws NullPointerException if any point is null
248 */
249 public void setArcByTangent(Point2D p1, Point2D p2, Point2D p3, double r)
250 {
251 // XXX Implement.
252 throw new Error("not implemented");
253 }
254
255 /**
256 * Set the start, in degrees.
257 *
258 * @param start the new start angle
259 * @see #getAngleStart()
260 */
261 public abstract void setAngleStart(double start);
262
263 /**
264 * Set the extent, in degrees.
265 *
266 * @param extent the new extent angle
267 * @see #getAngleExtent()
268 */
269 public abstract void setAngleExtent(double extent);
270
271 /**
272 * Sets the starting angle to the angle of the given point relative to
273 * the center of the arc. The extent remains constant; in other words,
274 * this rotates the arc.
275 *
276 * @param p the new start point
277 * @throws NullPointerException if p is null
278 * @see #getStartPoint()
279 * @see #getAngleStart()
280 */
281 public void setAngleStart(Point2D p)
282 {
283 double x = ((p.getX() * 2) - getX()) / getWidth();
284 double y = ((p.getY() * 2) - getY()) / getHeight();
285 setAngleStart(Math.atan2(y, x) * (-180 / Math.PI));
286 }
287
288 /**
289 * Sets the starting and extent angles to those of the given points
290 * relative to the center of the arc. The arc will be non-empty, and will
291 * extend counterclockwise.
292 *
293 * @param x1 the first x coordinate
294 * @param y1 the first y coordinate
295 * @param x2 the second x coordinate
296 * @param y2 the second y coordinate
297 * @see #setAngleStart(Point2D)
298 */
299 public void setAngles(double x1, double y1, double x2, double y2)
300 {
301 // Normalize the points.
302 double mx = getX();
303 double my = getY();
304 double mw = getWidth();
305 double mh = getHeight();
306 x1 = ((x1 * 2) - mx) / mw;
307 y1 = ((y1 * 2) - my) / mh;
308 x2 = ((x2 * 2) - mx) / mw;
309 y2 = ((y2 * 2) - my) / mh;
310 double start = Math.atan2(y1, x1) * (-180 / Math.PI);
311 double extent = Math.atan2(y2, x2) * (-180 / Math.PI) - start;
312 if (extent < 0)
313 extent += 360;
314 setAngleStart(start);
315 setAngleExtent(extent);
316 }
317
318 /**
319 * Sets the starting and extent angles to those of the given points
320 * relative to the center of the arc. The arc will be non-empty, and will
321 * extend counterclockwise.
322 *
323 * @param p1 the first point
324 * @param p2 the second point
325 * @throws NullPointerException if either point is null
326 * @see #setAngleStart(Point2D)
327 */
328 public void setAngles(Point2D p1, Point2D p2)
329 {
330 setAngles(p1.getX(), p1.getY(), p2.getX(), p2.getY());
331 }
332
333 /**
334 * Set the closure type of this arc.
335 *
336 * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
337 * @throws IllegalArgumentException if type is invalid
338 * @see #getArcType()
339 */
340 public void setArcType(int type)
341 {
342 if (type < OPEN || type > PIE)
343 throw new IllegalArgumentException();
344 this.type = type;
345 }
346
347 /**
348 * Sets the location and bounds of the ellipse of which this arc is a part.
349 *
350 * @param x the new x coordinate
351 * @param y the new y coordinate
352 * @param w the new width
353 * @param h the new height
354 * @see #getFrame()
355 */
356 public void setFrame(double x, double y, double w, double h)
357 {
358 setArc(x, y, w, h, getAngleStart(), getAngleExtent(), type);
359 }
360
361 /**
362 * Gets the bounds of the arc. This is much tighter than
363 * <code>getBounds</code>, as it takes into consideration the start and
364 * end angles, and the center point of a pie wedge, rather than just the
365 * overall ellipse.
366 *
367 * @return the bounds of the arc
368 * @see #getBounds()
369 */
370 public Rectangle2D getBounds2D()
371 {
372 double extent = getAngleExtent();
373 if (Math.abs(extent) >= 360)
374 return makeBounds(getX(), getY(), getWidth(), getHeight());
375 // XXX Finish implementing.
376 throw new Error("not implemented");
377 }
378
379 /**
380 * Construct a bounding box in a precision appropriate for the subclass.
381 *
382 * @param x the x coordinate
383 * @param y the y coordinate
384 * @param w the width
385 * @param h the height
386 * @return the rectangle for use in getBounds2D
387 */
388 protected abstract Rectangle2D makeBounds(double x, double y,
389 double w, double h);
390
391 /**
392 * Tests if the given angle, in degrees, is included in the arc.
393 *
394 * XXX Does this normalize all angles to -180 - 180 first?
395 *
396 * @param a the angle to test
397 * @return true if it is contained
398 */
399 public boolean containsAngle(double a)
400 {
401 // XXX Implement.
402 throw new Error("not implemented");
403 }
404
405 /**
406 * Determines if the arc contains the given point. If the bounding box
407 * is empty, then this will return false.
408 *
409 * @param x the x coordinate to test
410 * @param y the y coordinate to test
411 * @return true if the point is inside the arc
412 */
413 public boolean contains(double x, double y)
414 {
415 double w = getWidth();
416 double h = getHeight();
417 if (w <= 0 || h <= 0)
418 return false;
419 // XXX Finish implementing.
420 throw new Error("not implemented");
421 }
422
423 /**
424 * Tests if a given rectangle intersects the area of the arc.
425 *
426 * @param x the x coordinate of the rectangle
427 * @param y the y coordinate of the rectangle
428 * @param w the width of the rectangle
429 * @param h the height of the rectangle
430 * @return true if the two shapes share common points
431 */
432 public boolean intersects(double x, double y, double w, double h)
433 {
434 double mw = getWidth();
435 double mh = getHeight();
436 if (mw <= 0 || mh <= 0 || w <= 0 || h <= 0)
437 return false;
438 // XXX Finish implementing.
439 throw new Error("not implemented");
440 }
441
442 /**
443 * Tests if a given rectangle is contained in the area of the arc.
444 *
445 * @param x the x coordinate of the rectangle
446 * @param y the y coordinate of the rectangle
447 * @param w the width of the rectangle
448 * @param h the height of the rectangle
449 * @return true if the arc contains the rectangle
450 */
451 public boolean contains(double x, double y, double w, double h)
452 {
453 double mw = getWidth();
454 double mh = getHeight();
455 if (mw <= 0 || mh <= 0 || w <= 0 || h <= 0)
456 return false;
457 // XXX Finish implementing.
458 throw new Error("not implemented");
459 }
460
461 /**
462 * Tests if a given rectangle is contained in the area of the arc.
463 *
464 * @param r the rectangle
465 * @return true if the arc contains the rectangle
466 */
467 public boolean contains(Rectangle2D r)
468 {
469 return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
470 }
471
472 /**
473 * Returns an iterator over this arc, with an optional transformation.
474 * This iterator is threadsafe, so future modifications to the arc do not
475 * affect the iteration.
476 *
477 * @param at the transformation, or null
478 * @return a path iterator
479 */
480 public PathIterator getPathIterator(AffineTransform at)
481 {
482 return new ArcIterator(this, at);
483 }
484
485 /**
486 * This class is used to iterate over an arc. Since ellipses are a subclass
487 * of arcs, this is used by Ellipse2D as well.
488 *
489 * @author Eric Blake <ebb9@email.byu.edu>
490 */
491 static final class ArcIterator implements PathIterator
492 {
493 /** The current iteration. */
494 private int current;
495
496 /** The last iteration. */
497 private final int limit;
498
499 /** The optional transformation. */
500 private final AffineTransform xform;
501
502 /** The x coordinate of the bounding box. */
503 private final double x;
504
505 /** The y coordinate of the bounding box. */
506 private final double y;
507
508 /** The width of the bounding box. */
509 private final double w;
510
511 /** The height of the bounding box. */
512 private final double h;
513
514 /** The start angle, in radians (not degrees). */
515 private final double start;
516
517 /** The extent angle, in radians (not degrees). */
518 private final double extent;
519
520 /** The arc closure type. */
521 private final int type;
522
523 /**
524 * Construct a new iterator over an arc.
525 *
526 * @param a the arc
527 * @param xform the transform
528 */
529 ArcIterator(Arc2D a, AffineTransform xform)
530 {
531 this.xform = xform;
532 x = a.getX();
533 y = a.getY();
534 w = a.getWidth();
535 h = a.getHeight();
536 start = a.getAngleStart() * (Math.PI / 180);
537 extent = a.getAngleExtent() * (Math.PI / 180);
538 type = a.type;
539 double e = extent < 0 ? -extent : extent;
540 if (w < 0 || h < 0)
541 limit = -1;
542 else if (e == 0)
543 limit = type;
544 else if (e <= 90)
545 limit = type + 1;
546 else if (e <= 180)
547 limit = type + 2;
548 else if (e <= 270)
549 limit = type + 3;
550 else
551 limit = type + 4;
552 }
553
554 /**
555 * Construct a new iterator over an ellipse.
556 *
557 * @param e the ellipse
558 * @param xform the transform
559 */
560 ArcIterator(Ellipse2D e, AffineTransform xform)
561 {
562 this.xform = xform;
563 x = e.getX();
564 y = e.getY();
565 w = e.getWidth();
566 h = e.getHeight();
567 start = 0;
568 extent = -2 * Math.PI;
569 type = CHORD;
570 limit = (w < 0 || h < 0) ? -1 : 5;
571 }
572
573 /**
574 * Return the winding rule.
575 *
576 * @return {@link PathIterator#WIND_NON_ZERO}
577 */
578 public int getWindingRule()
579 {
580 return WIND_NON_ZERO;
581 }
582
583 /**
584 * Test if the iteration is complete.
585 *
586 * @return true if more segments exist
587 */
588 public boolean isDone()
589 {
590 return current > limit;
591 }
592
593 /**
594 * Advance the iterator.
595 */
596 public void next()
597 {
598 current++;
599 }
600
601 /**
602 * Put the current segment into the array, and return the segment type.
603 *
604 * @param coords an array of 6 elements
605 * @return the segment type
606 * @throws NullPointerException if coords is null
607 * @throws ArrayIndexOutOfBoundsException if coords is too small
608 */
609 public int currentSegment(float[] coords)
610 {
611 if (current > limit)
612 throw new NoSuchElementException("arc iterator out of bounds");
613 if (current == 0)
614 {
615 coords[0] = (float) (Math.cos(start) * w + x) / 2;
616 coords[1] = (float) (Math.sin(start) * h + y) / 2;
617 if (xform != null)
618 xform.transform(coords, 0, coords, 0, 1);
619 return SEG_MOVETO;
620 }
621 if (type != OPEN && current == limit)
622 return SEG_CLOSE;
623 if (type == PIE && current == limit - 1)
624 {
625 coords[0] = (float) (x + w / 2);
626 coords[1] = (float) (y + h / 2);
627 if (xform != null)
628 xform.transform(coords, 0, coords, 0, 1);
629 return SEG_LINETO;
630 }
631 // XXX Fill coords with 2 control points and next quarter point
632 coords[0] = (float) 0;
633 coords[1] = (float) 0;
634 coords[2] = (float) 0;
635 coords[3] = (float) 0;
636 coords[4] = (float) 0;
637 coords[5] = (float) 0;
638 if (xform != null)
639 xform.transform(coords, 0, coords, 0, 3);
640 return SEG_CUBICTO;
641 }
642
643 /**
644 * Put the current segment into the array, and return the segment type.
645 *
646 * @param coords an array of 6 elements
647 * @return the segment type
648 * @throws NullPointerException if coords is null
649 * @throws ArrayIndexOutOfBoundsException if coords is too small
650 */
651 public int currentSegment(double[] coords)
652 {
653 if (current > limit)
654 throw new NoSuchElementException("arc iterator out of bounds");
655 if (current == 0)
656 {
657 coords[0] = (Math.cos(start) * w + x) / 2;
658 coords[1] = (Math.sin(start) * h + y) / 2;
659 if (xform != null)
660 xform.transform(coords, 0, coords, 0, 1);
661 return SEG_MOVETO;
662 }
663 if (type != OPEN && current == limit)
664 return SEG_CLOSE;
665 if (type == PIE && current == limit - 1)
666 {
667 coords[0] = (float) (x + w / 2);
668 coords[1] = (float) (y + h / 2);
669 if (xform != null)
670 xform.transform(coords, 0, coords, 0, 1);
671 return SEG_LINETO;
672 }
673 // XXX Fill coords with 2 control points and next quarter point
674 coords[0] = 0;
675 coords[1] = 0;
676 coords[2] = 0;
677 coords[3] = 0;
678 coords[4] = 0;
679 coords[5] = 0;
680 if (xform != null)
681 xform.transform(coords, 0, coords, 0, 3);
682 return SEG_CUBICTO;
683 }
684 } // class ArcIterator
685
686 /**
687 * This class implements an arc in double precision.
688 *
689 * @author Eric Blake <ebb9@email.byu.edu
690 * @since 1.2
691 */
692 public static class Double extends Arc2D
693 {
694 /** The x coordinate of the box bounding the ellipse of this arc. */
695 public double x;
696
697 /** The y coordinate of the box bounding the ellipse of this arc. */
698 public double y;
699
700 /** The width of the box bounding the ellipse of this arc. */
701 public double width;
702
703 /** The height of the box bounding the ellipse of this arc. */
704 public double height;
705
706 /** The start angle of this arc, in degrees. */
707 public double start;
708
709 /** The extent angle of this arc, in degrees. */
710 public double extent;
711
712 /**
713 * Create a new, open arc at (0,0) with 0 extent.
714 */
715 public Double()
716 {
717 super(OPEN);
718 }
719
720 /**
721 * Create a new arc of the given type at (0,0) with 0 extent.
722 *
723 * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
724 * @throws IllegalArgumentException if type is invalid
725 */
726 public Double(int type)
727 {
728 super(type);
729 }
730
731 /**
732 * Create a new arc with the given dimensions.
733 *
734 * @param x the x coordinate
735 * @param y the y coordinate
736 * @param w the width
737 * @param h the height
738 * @param start the start angle, in degrees
739 * @param extent the extent, in degrees
740 * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
741 * @throws IllegalArgumentException if type is invalid
742 */
743 public Double(double x, double y, double w, double h,
744 double start, double extent, int type)
745 {
746 super(type);
747 this.x = x;
748 this.y = y;
749 width = w;
750 height = h;
751 this.start = start;
752 this.extent = extent;
753 }
754
755 /**
756 * Create a new arc with the given dimensions.
757 *
758 * @param r the bounding box
759 * @param start the start angle, in degrees
760 * @param extent the extent, in degrees
761 * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
762 * @throws IllegalArgumentException if type is invalid
763 * @throws NullPointerException if r is null
764 */
765 public Double(Rectangle2D r, double start, double extent, int type)
766 {
767 super(type);
768 x = r.getX();
769 y = r.getY();
770 width = r.getWidth();
771 height = r.getHeight();
772 this.start = start;
773 this.extent = extent;
774 }
775
776 /**
777 * Return the x coordinate of the bounding box.
778 *
779 * @return the value of x
780 */
781 public double getX()
782 {
783 return x;
784 }
785
786 /**
787 * Return the y coordinate of the bounding box.
788 *
789 * @return the value of y
790 */
791 public double getY()
792 {
793 return y;
794 }
795
796 /**
797 * Return the width of the bounding box.
798 *
799 * @return the value of width
800 */
801 public double getWidth()
802 {
803 return width;
804 }
805
806 /**
807 * Return the height of the bounding box.
808 *
809 * @return the value of height
810 */
811 public double getHeight()
812 {
813 return height;
814 }
815
816 /**
817 * Return the start angle of the arc, in degrees.
818 *
819 * @return the value of start
820 */
821 public double getAngleStart()
822 {
823 return start;
824 }
825
826 /**
827 * Return the extent of the arc, in degrees.
828 *
829 * @return the value of extent
830 */
831 public double getAngleExtent()
832 {
833 return extent;
834 }
835
836 /**
837 * Tests if the arc contains points.
838 *
839 * @return true if the arc has no interior
840 */
841 public boolean isEmpty()
842 {
843 return width <= 0 || height <= 0;
844 }
845
846 /**
847 * Sets the arc to the given dimensions.
848 *
849 * @param x the x coordinate
850 * @param y the y coordinate
851 * @param w the width
852 * @param h the height
853 * @param start the start angle, in degrees
854 * @param extent the extent, in degrees
855 * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
856 * @throws IllegalArgumentException if type is invalid
857 */
858 public void setArc(double x, double y, double w, double h,
859 double start, double extent, int type)
860 {
861 this.x = x;
862 this.y = y;
863 width = w;
864 height = h;
865 this.start = start;
866 this.extent = extent;
867 setArcType(type);
868 }
869
870 /**
871 * Sets the start angle of the arc.
872 *
873 * @param start the new start angle
874 */
875 public void setAngleStart(double start)
876 {
877 this.start = start;
878 }
879
880 /**
881 * Sets the extent angle of the arc.
882 *
883 * @param start the new extent angle
884 */
885 public void setAngleExtent(double extent)
886 {
887 this.extent = extent;
888 }
889
890 /**
891 * Creates a tight bounding box given dimensions that more precise than
892 * the bounding box of the ellipse.
893 *
894 * @param x the x coordinate
895 * @param y the y coordinate
896 * @param w the width
897 * @param h the height
898 */
899 protected Rectangle2D makeBounds(double x, double y, double w, double h)
900 {
901 return new Rectangle2D.Double(x, y, w, h);
902 }
903 } // class Double
904
905 /**
906 * This class implements an arc in float precision.
907 *
908 * @author Eric Blake <ebb9@email.byu.edu
909 * @since 1.2
910 */
911 public static class Float extends Arc2D
912 {
913 /** The x coordinate of the box bounding the ellipse of this arc. */
914 public float x;
915
916 /** The y coordinate of the box bounding the ellipse of this arc. */
917 public float y;
918
919 /** The width of the box bounding the ellipse of this arc. */
920 public float width;
921
922 /** The height of the box bounding the ellipse of this arc. */
923 public float height;
924
925 /** The start angle of this arc, in degrees. */
926 public float start;
927
928 /** The extent angle of this arc, in degrees. */
929 public float extent;
930
931 /**
932 * Create a new, open arc at (0,0) with 0 extent.
933 */
934 public Float()
935 {
936 super(OPEN);
937 }
938
939 /**
940 * Create a new arc of the given type at (0,0) with 0 extent.
941 *
942 * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
943 * @throws IllegalArgumentException if type is invalid
944 */
945 public Float(int type)
946 {
947 super(type);
948 }
949
950 /**
951 * Create a new arc with the given dimensions.
952 *
953 * @param x the x coordinate
954 * @param y the y coordinate
955 * @param w the width
956 * @param h the height
957 * @param start the start angle, in degrees
958 * @param extent the extent, in degrees
959 * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
960 * @throws IllegalArgumentException if type is invalid
961 */
962 public Float(float x, float y, float w, float h,
963 float start, float extent, int type)
964 {
965 super(type);
966 this.x = x;
967 this.y = y;
968 width = w;
969 height = h;
970 this.start = start;
971 this.extent = extent;
972 }
973
974 /**
975 * Create a new arc with the given dimensions.
976 *
977 * @param r the bounding box
978 * @param start the start angle, in degrees
979 * @param extent the extent, in degrees
980 * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
981 * @throws IllegalArgumentException if type is invalid
982 * @throws NullPointerException if r is null
983 */
984 public Float(Rectangle2D r, float start, float extent, int type)
985 {
986 super(type);
987 x = (float) r.getX();
988 y = (float) r.getY();
989 width = (float) r.getWidth();
990 height = (float) r.getHeight();
991 this.start = start;
992 this.extent = extent;
993 }
994
995 /**
996 * Return the x coordinate of the bounding box.
997 *
998 * @return the value of x
999 */
1000 public double getX()
1001 {
1002 return x;
1003 }
1004
1005 /**
1006 * Return the y coordinate of the bounding box.
1007 *
1008 * @return the value of y
1009 */
1010 public double getY()
1011 {
1012 return y;
1013 }
1014
1015 /**
1016 * Return the width of the bounding box.
1017 *
1018 * @return the value of width
1019 */
1020 public double getWidth()
1021 {
1022 return width;
1023 }
1024
1025 /**
1026 * Return the height of the bounding box.
1027 *
1028 * @return the value of height
1029 */
1030 public double getHeight()
1031 {
1032 return height;
1033 }
1034
1035 /**
1036 * Return the start angle of the arc, in degrees.
1037 *
1038 * @return the value of start
1039 */
1040 public double getAngleStart()
1041 {
1042 return start;
1043 }
1044
1045 /**
1046 * Return the extent of the arc, in degrees.
1047 *
1048 * @return the value of extent
1049 */
1050 public double getAngleExtent()
1051 {
1052 return extent;
1053 }
1054
1055 /**
1056 * Tests if the arc contains points.
1057 *
1058 * @return true if the arc has no interior
1059 */
1060 public boolean isEmpty()
1061 {
1062 return width <= 0 || height <= 0;
1063 }
1064
1065 /**
1066 * Sets the arc to the given dimensions.
1067 *
1068 * @param x the x coordinate
1069 * @param y the y coordinate
1070 * @param w the width
1071 * @param h the height
1072 * @param start the start angle, in degrees
1073 * @param extent the extent, in degrees
1074 * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
1075 * @throws IllegalArgumentException if type is invalid
1076 */
1077 public void setArc(double x, double y, double w, double h,
1078 double start, double extent, int type)
1079 {
1080 this.x = (float) x;
1081 this.y = (float) y;
1082 width = (float) w;
1083 height = (float) h;
1084 this.start = (float) start;
1085 this.extent = (float) extent;
1086 setArcType(type);
1087 }
1088
1089 /**
1090 * Sets the start angle of the arc.
1091 *
1092 * @param start the new start angle
1093 */
1094 public void setAngleStart(double start)
1095 {
1096 this.start = (float) start;
1097 }
1098
1099 /**
1100 * Sets the extent angle of the arc.
1101 *
1102 * @param start the new extent angle
1103 */
1104 public void setAngleExtent(double extent)
1105 {
1106 this.extent = (float) extent;
1107 }
1108
1109 /**
1110 * Creates a tight bounding box given dimensions that more precise than
1111 * the bounding box of the ellipse.
1112 *
1113 * @param x the x coordinate
1114 * @param y the y coordinate
1115 * @param w the width
1116 * @param h the height
1117 */
1118 protected Rectangle2D makeBounds(double x, double y, double w, double h)
1119 {
1120 return new Rectangle2D.Float((float) x, (float) y, (float) w, (float) h);
1121 }
1122 } // class Float
1123} // class Arc2D
Note: See TracBrowser for help on using the repository browser.