mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			1414 lines
		
	
	
		
			39 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			1414 lines
		
	
	
		
			39 KiB
		
	
	
	
		
			Java
		
	
	
	
/* Arc2D.java -- represents an arc in 2-D space
 | 
						|
   Copyright (C) 2002, 2003, 2004 Free Software Foundation
 | 
						|
 | 
						|
This file is part of GNU Classpath.
 | 
						|
 | 
						|
GNU Classpath is free software; you can redistribute it and/or modify
 | 
						|
it under the terms of the GNU General Public License as published by
 | 
						|
the Free Software Foundation; either version 2, or (at your option)
 | 
						|
any later version.
 | 
						|
 | 
						|
GNU Classpath is distributed in the hope that it will be useful, but
 | 
						|
WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
						|
General Public License for more details.
 | 
						|
 | 
						|
You should have received a copy of the GNU General Public License
 | 
						|
along with GNU Classpath; see the file COPYING.  If not, write to the
 | 
						|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
						|
02110-1301 USA.
 | 
						|
 | 
						|
Linking this library statically or dynamically with other modules is
 | 
						|
making a combined work based on this library.  Thus, the terms and
 | 
						|
conditions of the GNU General Public License cover the whole
 | 
						|
combination.
 | 
						|
 | 
						|
As a special exception, the copyright holders of this library give you
 | 
						|
permission to link this library with independent modules to produce an
 | 
						|
executable, regardless of the license terms of these independent
 | 
						|
modules, and to copy and distribute the resulting executable under
 | 
						|
terms of your choice, provided that you also meet, for each linked
 | 
						|
independent module, the terms and conditions of the license of that
 | 
						|
module.  An independent module is a module which is not derived from
 | 
						|
or based on this library.  If you modify this library, you may extend
 | 
						|
this exception to your version of the library, but you are not
 | 
						|
obligated to do so.  If you do not wish to do so, delete this
 | 
						|
exception statement from your version. */
 | 
						|
 | 
						|
package java.awt.geom;
 | 
						|
 | 
						|
import java.util.NoSuchElementException;
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
 * This class represents all arcs (segments of an ellipse in 2-D space). The
 | 
						|
 * arcs are defined by starting angle and extent (arc length) in degrees, as
 | 
						|
 * opposed to radians (like the rest of Java), and can be open, chorded, or
 | 
						|
 * wedge shaped. The angles are skewed according to the ellipse, so that 45
 | 
						|
 * degrees always points to the upper right corner (positive x, negative y)
 | 
						|
 * of the bounding rectangle. A positive extent draws a counterclockwise arc,
 | 
						|
 * and while the angle can be any value, the path iterator only traverses the
 | 
						|
 * first 360 degrees. Storage is up to the subclasses.
 | 
						|
 *
 | 
						|
 * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
 * @author Sven de Marothy (sven@physto.se)
 | 
						|
 * @since 1.2
 | 
						|
 */
 | 
						|
public abstract class Arc2D extends RectangularShape
 | 
						|
{
 | 
						|
  /**
 | 
						|
   * An open arc, with no segment connecting the endpoints. This type of
 | 
						|
   * arc still contains the same points as a chorded version.
 | 
						|
   */
 | 
						|
  public static final int OPEN = 0;
 | 
						|
 | 
						|
  /**
 | 
						|
   * A closed arc with a single segment connecting the endpoints (a chord).
 | 
						|
   */
 | 
						|
  public static final int CHORD = 1;
 | 
						|
 | 
						|
  /**
 | 
						|
   * A closed arc with two segments, one from each endpoint, meeting at the
 | 
						|
   * center of the ellipse.
 | 
						|
   */
 | 
						|
  public static final int PIE = 2;
 | 
						|
 | 
						|
  /** The closure type of this arc.  This is package-private to avoid an
 | 
						|
   * accessor method.  */
 | 
						|
  int type;
 | 
						|
 | 
						|
  /**
 | 
						|
   * Create a new arc, with the specified closure type.
 | 
						|
   *
 | 
						|
   * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}.
 | 
						|
   * @throws IllegalArgumentException if type is invalid
 | 
						|
   */
 | 
						|
  protected Arc2D(int type)
 | 
						|
  {
 | 
						|
    if (type < OPEN || type > PIE)
 | 
						|
      throw new IllegalArgumentException();
 | 
						|
    this.type = type;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Get the starting angle of the arc in degrees.
 | 
						|
   *
 | 
						|
   * @return the starting angle
 | 
						|
   * @see #setAngleStart(double)
 | 
						|
   */
 | 
						|
  public abstract double getAngleStart();
 | 
						|
 | 
						|
  /**
 | 
						|
   * Get the extent angle of the arc in degrees.
 | 
						|
   *
 | 
						|
   * @return the extent angle
 | 
						|
   * @see #setAngleExtent(double)
 | 
						|
   */
 | 
						|
  public abstract double getAngleExtent();
 | 
						|
 | 
						|
  /**
 | 
						|
   * Return the closure type of the arc.
 | 
						|
   *
 | 
						|
   * @return the closure type
 | 
						|
   * @see #OPEN
 | 
						|
   * @see #CHORD
 | 
						|
   * @see #PIE
 | 
						|
   * @see #setArcType(int)
 | 
						|
   */
 | 
						|
  public int getArcType()
 | 
						|
  {
 | 
						|
    return type;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the starting point of the arc.
 | 
						|
   *
 | 
						|
   * @return the start point
 | 
						|
   */
 | 
						|
  public Point2D getStartPoint()
 | 
						|
  {
 | 
						|
    double angle = Math.toRadians(getAngleStart());
 | 
						|
    double rx = getWidth() / 2;
 | 
						|
    double ry = getHeight() / 2;
 | 
						|
    double x = getX() + rx + rx * Math.cos(angle);
 | 
						|
    double y = getY() + ry - ry * Math.sin(angle);
 | 
						|
    return new Point2D.Double(x, y);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns the ending point of the arc.
 | 
						|
   *
 | 
						|
   * @return the end point
 | 
						|
   */
 | 
						|
  public Point2D getEndPoint()
 | 
						|
  {
 | 
						|
    double angle = Math.toRadians(getAngleStart() + getAngleExtent());
 | 
						|
    double rx = getWidth() / 2;
 | 
						|
    double ry = getHeight() / 2;
 | 
						|
    double x = getX() + rx + rx * Math.cos(angle);
 | 
						|
    double y = getY() + ry - ry * Math.sin(angle);
 | 
						|
    return new Point2D.Double(x, y);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Set the parameters of the arc. The angles are in degrees, and a positive
 | 
						|
   * extent sweeps counterclockwise (from the positive x-axis to the negative
 | 
						|
   * y-axis).
 | 
						|
   *
 | 
						|
   * @param x the new x coordinate of the upper left of the bounding box
 | 
						|
   * @param y the new y coordinate of the upper left of the bounding box
 | 
						|
   * @param w the new width of the bounding box
 | 
						|
   * @param h the new height of the bounding box
 | 
						|
   * @param start the start angle, in degrees
 | 
						|
   * @param extent the arc extent, in degrees
 | 
						|
   * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
 | 
						|
   * @throws IllegalArgumentException if type is invalid
 | 
						|
   */
 | 
						|
  public abstract void setArc(double x, double y, double w, double h,
 | 
						|
                              double start, double extent, int type);
 | 
						|
 | 
						|
  /**
 | 
						|
   * Set the parameters of the arc. The angles are in degrees, and a positive
 | 
						|
   * extent sweeps counterclockwise (from the positive x-axis to the negative
 | 
						|
   * y-axis).
 | 
						|
   *
 | 
						|
   * @param p the upper left point of the bounding box
 | 
						|
   * @param d the dimensions of the bounding box
 | 
						|
   * @param start the start angle, in degrees
 | 
						|
   * @param extent the arc extent, in degrees
 | 
						|
   * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
 | 
						|
   * @throws IllegalArgumentException if type is invalid
 | 
						|
   * @throws NullPointerException if p or d is null
 | 
						|
   */
 | 
						|
  public void setArc(Point2D p, Dimension2D d, double start, double extent,
 | 
						|
                     int type)
 | 
						|
  {
 | 
						|
    setArc(p.getX(), p.getY(), d.getWidth(), d.getHeight(), start, extent, type);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Set the parameters of the arc. The angles are in degrees, and a positive
 | 
						|
   * extent sweeps counterclockwise (from the positive x-axis to the negative
 | 
						|
   * y-axis).
 | 
						|
   *
 | 
						|
   * @param r the new bounding box
 | 
						|
   * @param start the start angle, in degrees
 | 
						|
   * @param extent the arc extent, in degrees
 | 
						|
   * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
 | 
						|
   * @throws IllegalArgumentException if type is invalid
 | 
						|
   * @throws NullPointerException if r is null
 | 
						|
   */
 | 
						|
  public void setArc(Rectangle2D r, double start, double extent, int type)
 | 
						|
  {
 | 
						|
    setArc(r.getX(), r.getY(), r.getWidth(), r.getHeight(), start, extent, type);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Set the parameters of the arc from the given one.
 | 
						|
   *
 | 
						|
   * @param a the arc to copy
 | 
						|
   * @throws NullPointerException if a is null
 | 
						|
   */
 | 
						|
  public void setArc(Arc2D a)
 | 
						|
  {
 | 
						|
    setArc(a.getX(), a.getY(), a.getWidth(), a.getHeight(), a.getAngleStart(),
 | 
						|
           a.getAngleExtent(), a.getArcType());
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Set the parameters of the arc. The angles are in degrees, and a positive
 | 
						|
   * extent sweeps counterclockwise (from the positive x-axis to the negative
 | 
						|
   * y-axis). This controls the center point and radius, so the arc will be
 | 
						|
   * circular.
 | 
						|
   *
 | 
						|
   * @param x the x coordinate of the center of the circle
 | 
						|
   * @param y the y coordinate of the center of the circle
 | 
						|
   * @param r the radius of the circle
 | 
						|
   * @param start the start angle, in degrees
 | 
						|
   * @param extent the arc extent, in degrees
 | 
						|
   * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
 | 
						|
   * @throws IllegalArgumentException if type is invalid
 | 
						|
   */
 | 
						|
  public void setArcByCenter(double x, double y, double r, double start,
 | 
						|
                             double extent, int type)
 | 
						|
  {
 | 
						|
    setArc(x - r, y - r, r + r, r + r, start, extent, type);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the parameters of the arc by finding the tangents of two lines, and
 | 
						|
   * using the specified radius. The arc will be circular, will begin on the
 | 
						|
   * tangent point of the line extending from p1 to p2, and will end on the
 | 
						|
   * tangent point of the line extending from p2 to p3.
 | 
						|
   *
 | 
						|
   * XXX What happens if the points are colinear, or the radius negative?
 | 
						|
   *
 | 
						|
   * @param p1 the first point
 | 
						|
   * @param p2 the tangent line intersection point
 | 
						|
   * @param p3 the third point
 | 
						|
   * @param r the radius of the arc
 | 
						|
   * @throws NullPointerException if any point is null
 | 
						|
   */
 | 
						|
  public void setArcByTangent(Point2D p1, Point2D p2, Point2D p3, double r)
 | 
						|
  {
 | 
						|
    if ((p2.getX() - p1.getX()) * (p3.getY() - p1.getY())
 | 
						|
        - (p3.getX() - p1.getX()) * (p2.getY() - p1.getY()) > 0)
 | 
						|
      {
 | 
						|
	Point2D p = p3;
 | 
						|
	p3 = p1;
 | 
						|
	p1 = p;
 | 
						|
      }
 | 
						|
 | 
						|
    // normalized tangent vectors
 | 
						|
    double dx1 = (p1.getX() - p2.getX()) / p1.distance(p2);
 | 
						|
    double dy1 = (p1.getY() - p2.getY()) / p1.distance(p2);
 | 
						|
    double dx2 = (p2.getX() - p3.getX()) / p3.distance(p2);
 | 
						|
    double dy2 = (p2.getY() - p3.getY()) / p3.distance(p2);
 | 
						|
    double theta1 = Math.atan2(dx1, dy1);
 | 
						|
    double theta2 = Math.atan2(dx2, dy2);
 | 
						|
 | 
						|
    double dx = r * Math.cos(theta2) - r * Math.cos(theta1);
 | 
						|
    double dy = -r * Math.sin(theta2) + r * Math.sin(theta1);
 | 
						|
 | 
						|
    if (theta1 < 0)
 | 
						|
      theta1 += 2 * Math.PI;
 | 
						|
    if (theta2 < 0)
 | 
						|
      theta2 += 2 * Math.PI;
 | 
						|
    if (theta2 < theta1)
 | 
						|
      theta2 += 2 * Math.PI;
 | 
						|
 | 
						|
    // Vectors of the lines, not normalized, note we change 
 | 
						|
    // the direction of line 2.
 | 
						|
    dx1 = p1.getX() - p2.getX();
 | 
						|
    dy1 = p1.getY() - p2.getY();
 | 
						|
    dx2 = p3.getX() - p2.getX();
 | 
						|
    dy2 = p3.getY() - p2.getY();
 | 
						|
 | 
						|
    // Calculate the tangent point to the second line
 | 
						|
    double t2 = -(dx1 * dy - dy1 * dx) / (dx2 * dy1 - dx1 * dy2);
 | 
						|
    double x2 = t2 * (p3.getX() - p2.getX()) + p2.getX();
 | 
						|
    double y2 = t2 * (p3.getY() - p2.getY()) + p2.getY();
 | 
						|
 | 
						|
    // calculate the center point
 | 
						|
    double x = x2 - r * Math.cos(theta2);
 | 
						|
    double y = y2 + r * Math.sin(theta2);
 | 
						|
 | 
						|
    setArc(x - r, y - r, 2 * r, 2 * r, Math.toDegrees(theta1),
 | 
						|
           Math.toDegrees(theta2 - theta1), getArcType());
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Set the start, in degrees.
 | 
						|
   *
 | 
						|
   * @param start the new start angle
 | 
						|
   * @see #getAngleStart()
 | 
						|
   */
 | 
						|
  public abstract void setAngleStart(double start);
 | 
						|
 | 
						|
  /**
 | 
						|
   * Set the extent, in degrees.
 | 
						|
   *
 | 
						|
   * @param extent the new extent angle
 | 
						|
   * @see #getAngleExtent()
 | 
						|
   */
 | 
						|
  public abstract void setAngleExtent(double extent);
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the starting angle to the angle of the given point relative to
 | 
						|
   * the center of the arc. The extent remains constant; in other words,
 | 
						|
   * this rotates the arc.
 | 
						|
   *
 | 
						|
   * @param p the new start point
 | 
						|
   * @throws NullPointerException if p is null
 | 
						|
   * @see #getStartPoint()
 | 
						|
   * @see #getAngleStart()
 | 
						|
   */
 | 
						|
  public void setAngleStart(Point2D p)
 | 
						|
  {
 | 
						|
    // Normalize.
 | 
						|
    double x = p.getX() - (getX() + getWidth() / 2);
 | 
						|
    double y = p.getY() - (getY() + getHeight() / 2);
 | 
						|
    setAngleStart(Math.toDegrees(Math.atan2(-y, x)));
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the starting and extent angles to those of the given points
 | 
						|
   * relative to the center of the arc. The arc will be non-empty, and will
 | 
						|
   * extend counterclockwise.
 | 
						|
   *
 | 
						|
   * @param x1 the first x coordinate
 | 
						|
   * @param y1 the first y coordinate
 | 
						|
   * @param x2 the second x coordinate
 | 
						|
   * @param y2 the second y coordinate
 | 
						|
   * @see #setAngleStart(Point2D)
 | 
						|
   */
 | 
						|
  public void setAngles(double x1, double y1, double x2, double y2)
 | 
						|
  {
 | 
						|
    // Normalize the points.
 | 
						|
    double mx = getX();
 | 
						|
    double my = getY();
 | 
						|
    double mw = getWidth();
 | 
						|
    double mh = getHeight();
 | 
						|
    x1 = x1 - (mx + mw / 2);
 | 
						|
    y1 = y1 - (my + mh / 2);
 | 
						|
    x2 = x2 - (mx + mw / 2);
 | 
						|
    y2 = y2 - (my + mh / 2);
 | 
						|
    double start = Math.toDegrees(Math.atan2(-y1, x1));
 | 
						|
    double extent = Math.toDegrees(Math.atan2(-y2, x2)) - start;
 | 
						|
    if (extent < 0)
 | 
						|
      extent += 360;
 | 
						|
    setAngleStart(start);
 | 
						|
    setAngleExtent(extent);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the starting and extent angles to those of the given points
 | 
						|
   * relative to the center of the arc. The arc will be non-empty, and will
 | 
						|
   * extend counterclockwise.
 | 
						|
   *
 | 
						|
   * @param p1 the first point
 | 
						|
   * @param p2 the second point
 | 
						|
   * @throws NullPointerException if either point is null
 | 
						|
   * @see #setAngleStart(Point2D)
 | 
						|
   */
 | 
						|
  public void setAngles(Point2D p1, Point2D p2)
 | 
						|
  {
 | 
						|
    setAngles(p1.getX(), p1.getY(), p2.getX(), p2.getY());
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Set the closure type of this arc.
 | 
						|
   *
 | 
						|
   * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
 | 
						|
   * @throws IllegalArgumentException if type is invalid
 | 
						|
   * @see #getArcType()
 | 
						|
   */
 | 
						|
  public void setArcType(int type)
 | 
						|
  {
 | 
						|
    if (type < OPEN || type > PIE)
 | 
						|
      throw new IllegalArgumentException();
 | 
						|
    this.type = type;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Sets the location and bounds of the ellipse of which this arc is a part.
 | 
						|
   *
 | 
						|
   * @param x the new x coordinate
 | 
						|
   * @param y the new y coordinate
 | 
						|
   * @param w the new width
 | 
						|
   * @param h the new height
 | 
						|
   * @see #getFrame()
 | 
						|
   */
 | 
						|
  public void setFrame(double x, double y, double w, double h)
 | 
						|
  {
 | 
						|
    setArc(x, y, w, h, getAngleStart(), getAngleExtent(), type);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Gets the bounds of the arc. This is much tighter than
 | 
						|
   * <code>getBounds</code>, as it takes into consideration the start and
 | 
						|
   * end angles, and the center point of a pie wedge, rather than just the
 | 
						|
   * overall ellipse.
 | 
						|
   *
 | 
						|
   * @return the bounds of the arc
 | 
						|
   * @see #getBounds()
 | 
						|
   */
 | 
						|
  public Rectangle2D getBounds2D()
 | 
						|
  {
 | 
						|
    double extent = getAngleExtent();
 | 
						|
    if (Math.abs(extent) >= 360)
 | 
						|
      return makeBounds(getX(), getY(), getWidth(), getHeight());
 | 
						|
 | 
						|
    // Find the minimal bounding box.  This determined by its extrema,
 | 
						|
    // which are the center, the endpoints of the arc, and any local
 | 
						|
    // maximum contained by the arc.
 | 
						|
    double rX = getWidth() / 2;
 | 
						|
    double rY = getHeight() / 2;
 | 
						|
    double centerX = getX() + rX;
 | 
						|
    double centerY = getY() + rY;
 | 
						|
 | 
						|
    Point2D p1 = getStartPoint();
 | 
						|
    Rectangle2D result = makeBounds(p1.getX(), p1.getY(), 0, 0);
 | 
						|
    result.add(getEndPoint());
 | 
						|
 | 
						|
    if (type == PIE)
 | 
						|
      result.add(centerX, centerY);
 | 
						|
    if (containsAngle(0))
 | 
						|
      result.add(centerX + rX, centerY);
 | 
						|
    if (containsAngle(90))
 | 
						|
      result.add(centerX, centerY - rY);
 | 
						|
    if (containsAngle(180))
 | 
						|
      result.add(centerX - rX, centerY);
 | 
						|
    if (containsAngle(270))
 | 
						|
      result.add(centerX, centerY + rY);
 | 
						|
 | 
						|
    return result;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Construct a bounding box in a precision appropriate for the subclass.
 | 
						|
   *
 | 
						|
   * @param x the x coordinate
 | 
						|
   * @param y the y coordinate
 | 
						|
   * @param w the width
 | 
						|
   * @param h the height
 | 
						|
   * @return the rectangle for use in getBounds2D
 | 
						|
   */
 | 
						|
  protected abstract Rectangle2D makeBounds(double x, double y, double w,
 | 
						|
                                            double h);
 | 
						|
 | 
						|
  /**
 | 
						|
   * Tests if the given angle, in degrees, is included in the arc.
 | 
						|
   * All angles are normalized to be between 0 and 360 degrees.
 | 
						|
   *
 | 
						|
   * @param a the angle to test
 | 
						|
   * @return true if it is contained
 | 
						|
   */
 | 
						|
  public boolean containsAngle(double a)
 | 
						|
  {
 | 
						|
    double start = getAngleStart();
 | 
						|
    double extent = getAngleExtent();
 | 
						|
    double end = start + extent;
 | 
						|
 | 
						|
    if (extent == 0)
 | 
						|
      return false;
 | 
						|
 | 
						|
    if (extent >= 360 || extent <= -360)
 | 
						|
      return true;
 | 
						|
 | 
						|
    if (extent < 0)
 | 
						|
      {
 | 
						|
	end = start;
 | 
						|
	start += extent;
 | 
						|
      }
 | 
						|
 | 
						|
    start %= 360;
 | 
						|
    while (start < 0)
 | 
						|
      start += 360;
 | 
						|
 | 
						|
    end %= 360;
 | 
						|
    while (end < start)
 | 
						|
      end += 360;
 | 
						|
 | 
						|
    a %= 360;
 | 
						|
    while (a < start)
 | 
						|
      a += 360;
 | 
						|
 | 
						|
    return a >= start && a < end; // starting angle included, ending angle not
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Determines if the arc contains the given point. If the bounding box
 | 
						|
   * is empty, then this will return false.
 | 
						|
   *
 | 
						|
   * The area considered 'inside' an arc of type OPEN is the same as the
 | 
						|
   * area inside an equivalent filled CHORD-type arc. The area considered
 | 
						|
   * 'inside' a CHORD-type arc is the same as the filled area.
 | 
						|
   *
 | 
						|
   * @param x the x coordinate to test
 | 
						|
   * @param y the y coordinate to test
 | 
						|
   * @return true if the point is inside the arc
 | 
						|
   */
 | 
						|
  public boolean contains(double x, double y)
 | 
						|
  {
 | 
						|
    double w = getWidth();
 | 
						|
    double h = getHeight();
 | 
						|
    double extent = getAngleExtent();
 | 
						|
    if (w <= 0 || h <= 0 || extent == 0)
 | 
						|
      return false;
 | 
						|
 | 
						|
    double mx = getX() + w / 2;
 | 
						|
    double my = getY() + h / 2;
 | 
						|
    double dx = (x - mx) * 2 / w;
 | 
						|
    double dy = (y - my) * 2 / h;
 | 
						|
    if ((dx * dx + dy * dy) >= 1.0)
 | 
						|
      return false;
 | 
						|
 | 
						|
    double angle = Math.toDegrees(Math.atan2(-dy, dx));
 | 
						|
    if (getArcType() == PIE)
 | 
						|
      return containsAngle(angle);
 | 
						|
 | 
						|
    double a1 = Math.toRadians(getAngleStart());
 | 
						|
    double a2 = Math.toRadians(getAngleStart() + extent);
 | 
						|
    double x1 = mx + getWidth() * Math.cos(a1) / 2;
 | 
						|
    double y1 = my - getHeight() * Math.sin(a1) / 2;
 | 
						|
    double x2 = mx + getWidth() * Math.cos(a2) / 2;
 | 
						|
    double y2 = my - getHeight() * Math.sin(a2) / 2;
 | 
						|
    double sgn = ((x2 - x1) * (my - y1) - (mx - x1) * (y2 - y1)) * ((x2 - x1) * (y
 | 
						|
                 - y1) - (x - x1) * (y2 - y1));
 | 
						|
 | 
						|
    if (Math.abs(extent) > 180)
 | 
						|
      {
 | 
						|
	if (containsAngle(angle))
 | 
						|
	  return true;
 | 
						|
	return sgn > 0;
 | 
						|
      }
 | 
						|
    else
 | 
						|
      {
 | 
						|
	if (! containsAngle(angle))
 | 
						|
	  return false;
 | 
						|
	return sgn < 0;
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Tests if a given rectangle intersects the area of the arc.
 | 
						|
   *
 | 
						|
   * For a definition of the 'inside' area, see the contains() method.
 | 
						|
   * @see #contains(double, double)
 | 
						|
   *
 | 
						|
   * @param x the x coordinate of the rectangle
 | 
						|
   * @param y the y coordinate of the rectangle
 | 
						|
   * @param w the width of the rectangle
 | 
						|
   * @param h the height of the rectangle
 | 
						|
   * @return true if the two shapes share common points
 | 
						|
   */
 | 
						|
  public boolean intersects(double x, double y, double w, double h)
 | 
						|
  {
 | 
						|
    double extent = getAngleExtent();
 | 
						|
    if (extent == 0)
 | 
						|
      return false;
 | 
						|
 | 
						|
    if (contains(x, y) || contains(x, y + h) || contains(x + w, y)
 | 
						|
        || contains(x + w, y + h))
 | 
						|
      return true;
 | 
						|
 | 
						|
    Rectangle2D rect = new Rectangle2D.Double(x, y, w, h);
 | 
						|
 | 
						|
    double a = getWidth() / 2.0;
 | 
						|
    double b = getHeight() / 2.0;
 | 
						|
 | 
						|
    double mx = getX() + a;
 | 
						|
    double my = getY() + b;
 | 
						|
    double x1 = mx + a * Math.cos(Math.toRadians(getAngleStart()));
 | 
						|
    double y1 = my - b * Math.sin(Math.toRadians(getAngleStart()));
 | 
						|
    double x2 = mx + a * Math.cos(Math.toRadians(getAngleStart() + extent));
 | 
						|
    double y2 = my - b * Math.sin(Math.toRadians(getAngleStart() + extent));
 | 
						|
 | 
						|
    if (getArcType() != CHORD)
 | 
						|
      {
 | 
						|
	// check intersections against the pie radii
 | 
						|
	if (rect.intersectsLine(mx, my, x1, y1))
 | 
						|
	  return true;
 | 
						|
	if (rect.intersectsLine(mx, my, x2, y2))
 | 
						|
	  return true;
 | 
						|
      }
 | 
						|
    else// check the chord
 | 
						|
    if (rect.intersectsLine(x1, y1, x2, y2))
 | 
						|
      return true;
 | 
						|
 | 
						|
    // Check the Arc segment against the four edges
 | 
						|
    double dx;
 | 
						|
 | 
						|
    // Check the Arc segment against the four edges
 | 
						|
    double dy;
 | 
						|
    dy = y - my;
 | 
						|
    dx = a * Math.sqrt(1 - ((dy * dy) / (b * b)));
 | 
						|
    if (! java.lang.Double.isNaN(dx))
 | 
						|
      {
 | 
						|
	if (mx + dx >= x && mx + dx <= x + w
 | 
						|
	    && containsAngle(Math.toDegrees(Math.atan2(-dy, dx))))
 | 
						|
	  return true;
 | 
						|
	if (mx - dx >= x && mx - dx <= x + w
 | 
						|
	    && containsAngle(Math.toDegrees(Math.atan2(-dy, -dx))))
 | 
						|
	  return true;
 | 
						|
      }
 | 
						|
    dy = (y + h) - my;
 | 
						|
    dx = a * Math.sqrt(1 - ((dy * dy) / (b * b)));
 | 
						|
    if (! java.lang.Double.isNaN(dx))
 | 
						|
      {
 | 
						|
	if (mx + dx >= x && mx + dx <= x + w
 | 
						|
	    && containsAngle(Math.toDegrees(Math.atan2(-dy, dx))))
 | 
						|
	  return true;
 | 
						|
	if (mx - dx >= x && mx - dx <= x + w
 | 
						|
	    && containsAngle(Math.toDegrees(Math.atan2(-dy, -dx))))
 | 
						|
	  return true;
 | 
						|
      }
 | 
						|
    dx = x - mx;
 | 
						|
    dy = b * Math.sqrt(1 - ((dx * dx) / (a * a)));
 | 
						|
    if (! java.lang.Double.isNaN(dy))
 | 
						|
      {
 | 
						|
	if (my + dy >= y && my + dy <= y + h
 | 
						|
	    && containsAngle(Math.toDegrees(Math.atan2(-dy, dx))))
 | 
						|
	  return true;
 | 
						|
	if (my - dy >= y && my - dy <= y + h
 | 
						|
	    && containsAngle(Math.toDegrees(Math.atan2(dy, dx))))
 | 
						|
	  return true;
 | 
						|
      }
 | 
						|
 | 
						|
    dx = (x + w) - mx;
 | 
						|
    dy = b * Math.sqrt(1 - ((dx * dx) / (a * a)));
 | 
						|
    if (! java.lang.Double.isNaN(dy))
 | 
						|
      {
 | 
						|
	if (my + dy >= y && my + dy <= y + h
 | 
						|
	    && containsAngle(Math.toDegrees(Math.atan2(-dy, dx))))
 | 
						|
	  return true;
 | 
						|
	if (my - dy >= y && my - dy <= y + h
 | 
						|
	    && containsAngle(Math.toDegrees(Math.atan2(dy, dx))))
 | 
						|
	  return true;
 | 
						|
      }
 | 
						|
 | 
						|
    // Check whether the arc is contained within the box
 | 
						|
    if (rect.contains(mx, my))
 | 
						|
      return true;
 | 
						|
 | 
						|
    return false;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Tests if a given rectangle is contained in the area of the arc.
 | 
						|
   *
 | 
						|
   * @param x the x coordinate of the rectangle
 | 
						|
   * @param y the y coordinate of the rectangle
 | 
						|
   * @param w the width of the rectangle
 | 
						|
   * @param h the height of the rectangle
 | 
						|
   * @return true if the arc contains the rectangle
 | 
						|
   */
 | 
						|
  public boolean contains(double x, double y, double w, double h)
 | 
						|
  {
 | 
						|
    double extent = getAngleExtent();
 | 
						|
    if (extent == 0)
 | 
						|
      return false;
 | 
						|
 | 
						|
    if (! (contains(x, y) && contains(x, y + h) && contains(x + w, y)
 | 
						|
        && contains(x + w, y + h)))
 | 
						|
      return false;
 | 
						|
 | 
						|
    Rectangle2D rect = new Rectangle2D.Double(x, y, w, h);
 | 
						|
 | 
						|
    double a = getWidth() / 2.0;
 | 
						|
    double b = getHeight() / 2.0;
 | 
						|
 | 
						|
    double mx = getX() + a;
 | 
						|
    double my = getY() + b;
 | 
						|
    double x1 = mx + a * Math.cos(Math.toRadians(getAngleStart()));
 | 
						|
    double y1 = my - b * Math.sin(Math.toRadians(getAngleStart()));
 | 
						|
    double x2 = mx + a * Math.cos(Math.toRadians(getAngleStart() + extent));
 | 
						|
    double y2 = my - b * Math.sin(Math.toRadians(getAngleStart() + extent));
 | 
						|
    if (getArcType() != CHORD)
 | 
						|
      {
 | 
						|
	// check intersections against the pie radii
 | 
						|
	if (rect.intersectsLine(mx, my, x1, y1))
 | 
						|
	  return false;
 | 
						|
 | 
						|
	if (rect.intersectsLine(mx, my, x2, y2))
 | 
						|
	  return false;
 | 
						|
      }
 | 
						|
    else if (rect.intersectsLine(x1, y1, x2, y2))
 | 
						|
      return false;
 | 
						|
    return true;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Tests if a given rectangle is contained in the area of the arc.
 | 
						|
   *
 | 
						|
   * @param r the rectangle
 | 
						|
   * @return true if the arc contains the rectangle
 | 
						|
   */
 | 
						|
  public boolean contains(Rectangle2D r)
 | 
						|
  {
 | 
						|
    return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns an iterator over this arc, with an optional transformation.
 | 
						|
   * This iterator is threadsafe, so future modifications to the arc do not
 | 
						|
   * affect the iteration.
 | 
						|
   *
 | 
						|
   * @param at the transformation, or null
 | 
						|
   * @return a path iterator
 | 
						|
   */
 | 
						|
  public PathIterator getPathIterator(AffineTransform at)
 | 
						|
  {
 | 
						|
    return new ArcIterator(this, at);
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * This class is used to iterate over an arc. Since ellipses are a subclass
 | 
						|
   * of arcs, this is used by Ellipse2D as well.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   */
 | 
						|
  static final class ArcIterator implements PathIterator
 | 
						|
  {
 | 
						|
    /** The current iteration. */
 | 
						|
    private int current;
 | 
						|
 | 
						|
    /** The last iteration. */
 | 
						|
    private final int limit;
 | 
						|
 | 
						|
    /** The optional transformation. */
 | 
						|
    private final AffineTransform xform;
 | 
						|
 | 
						|
    /** The x coordinate of the bounding box. */
 | 
						|
    private final double x;
 | 
						|
 | 
						|
    /** The y coordinate of the bounding box. */
 | 
						|
    private final double y;
 | 
						|
 | 
						|
    /** The width of the bounding box. */
 | 
						|
    private final double w;
 | 
						|
 | 
						|
    /** The height of the bounding box. */
 | 
						|
    private final double h;
 | 
						|
 | 
						|
    /** The start angle, in radians (not degrees). */
 | 
						|
    private final double start;
 | 
						|
 | 
						|
    /** The extent angle, in radians (not degrees). */
 | 
						|
    private final double extent;
 | 
						|
 | 
						|
    /** The arc closure type. */
 | 
						|
    private final int type;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Construct a new iterator over an arc.
 | 
						|
     *
 | 
						|
     * @param a the arc
 | 
						|
     * @param xform the transform
 | 
						|
     */
 | 
						|
    public ArcIterator(Arc2D a, AffineTransform xform)
 | 
						|
    {
 | 
						|
      this.xform = xform;
 | 
						|
      x = a.getX();
 | 
						|
      y = a.getY();
 | 
						|
      w = a.getWidth();
 | 
						|
      h = a.getHeight();
 | 
						|
      double start = Math.toRadians(a.getAngleStart());
 | 
						|
      double extent = Math.toRadians(a.getAngleExtent());
 | 
						|
 | 
						|
      this.start = start;
 | 
						|
      this.extent = extent;
 | 
						|
 | 
						|
      type = a.type;
 | 
						|
      if (w < 0 || h < 0)
 | 
						|
	limit = -1;
 | 
						|
      else if (extent == 0)
 | 
						|
	limit = type;
 | 
						|
      else if (Math.abs(extent) <= Math.PI / 2.0)
 | 
						|
	limit = type + 1;
 | 
						|
      else if (Math.abs(extent) <= Math.PI)
 | 
						|
	limit = type + 2;
 | 
						|
      else if (Math.abs(extent) <= 3.0 * (Math.PI / 2.0))
 | 
						|
	limit = type + 3;
 | 
						|
      else
 | 
						|
	limit = type + 4;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Construct a new iterator over an ellipse.
 | 
						|
     *
 | 
						|
     * @param e the ellipse
 | 
						|
     * @param xform the transform
 | 
						|
     */
 | 
						|
    public ArcIterator(Ellipse2D e, AffineTransform xform)
 | 
						|
    {
 | 
						|
      this.xform = xform;
 | 
						|
      x = e.getX();
 | 
						|
      y = e.getY();
 | 
						|
      w = e.getWidth();
 | 
						|
      h = e.getHeight();
 | 
						|
      start = 0;
 | 
						|
      extent = 2 * Math.PI;
 | 
						|
      type = CHORD;
 | 
						|
      limit = (w < 0 || h < 0) ? -1 : 5;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the winding rule.
 | 
						|
     *
 | 
						|
     * @return {@link PathIterator#WIND_NON_ZERO}
 | 
						|
     */
 | 
						|
    public int getWindingRule()
 | 
						|
    {
 | 
						|
      return WIND_NON_ZERO;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Test if the iteration is complete.
 | 
						|
     *
 | 
						|
     * @return true if more segments exist
 | 
						|
     */
 | 
						|
    public boolean isDone()
 | 
						|
    {
 | 
						|
      return current > limit;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Advance the iterator.
 | 
						|
     */
 | 
						|
    public void next()
 | 
						|
    {
 | 
						|
      current++;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Put the current segment into the array, and return the segment type.
 | 
						|
     *
 | 
						|
     * @param coords an array of 6 elements
 | 
						|
     * @return the segment type
 | 
						|
     * @throws NullPointerException if coords is null
 | 
						|
     * @throws ArrayIndexOutOfBoundsException if coords is too small
 | 
						|
     */
 | 
						|
    public int currentSegment(float[] coords)
 | 
						|
    {
 | 
						|
      double[] double_coords = new double[6];
 | 
						|
      int code = currentSegment(double_coords);
 | 
						|
      for (int i = 0; i < 6; ++i)
 | 
						|
	coords[i] = (float) double_coords[i];
 | 
						|
      return code;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Put the current segment into the array, and return the segment type.
 | 
						|
     *
 | 
						|
     * @param coords an array of 6 elements
 | 
						|
     * @return the segment type
 | 
						|
     * @throws NullPointerException if coords is null
 | 
						|
     * @throws ArrayIndexOutOfBoundsException if coords is too small
 | 
						|
     */
 | 
						|
    public int currentSegment(double[] coords)
 | 
						|
    {
 | 
						|
      double rx = w / 2;
 | 
						|
      double ry = h / 2;
 | 
						|
      double xmid = x + rx;
 | 
						|
      double ymid = y + ry;
 | 
						|
 | 
						|
      if (current > limit)
 | 
						|
	throw new NoSuchElementException("arc iterator out of bounds");
 | 
						|
 | 
						|
      if (current == 0)
 | 
						|
        {
 | 
						|
	  coords[0] = xmid + rx * Math.cos(start);
 | 
						|
	  coords[1] = ymid - ry * Math.sin(start);
 | 
						|
	  if (xform != null)
 | 
						|
	    xform.transform(coords, 0, coords, 0, 1);
 | 
						|
	  return SEG_MOVETO;
 | 
						|
        }
 | 
						|
 | 
						|
      if (type != OPEN && current == limit)
 | 
						|
	return SEG_CLOSE;
 | 
						|
 | 
						|
      if ((current == limit - 1) && (type == PIE))
 | 
						|
        {
 | 
						|
	  coords[0] = xmid;
 | 
						|
	  coords[1] = ymid;
 | 
						|
	  if (xform != null)
 | 
						|
	    xform.transform(coords, 0, coords, 0, 1);
 | 
						|
	  return SEG_LINETO;
 | 
						|
        }
 | 
						|
 | 
						|
      // note that this produces a cubic approximation of the arc segment,
 | 
						|
      // not a true ellipsoid. there's no ellipsoid path segment code,
 | 
						|
      // unfortunately. the cubic approximation looks about right, though.
 | 
						|
      double kappa = (Math.sqrt(2.0) - 1.0) * (4.0 / 3.0);
 | 
						|
      double quad = (Math.PI / 2.0);
 | 
						|
 | 
						|
      double curr_begin;
 | 
						|
      double curr_extent;
 | 
						|
      if (extent > 0)
 | 
						|
        {
 | 
						|
          curr_begin = start + (current - 1) * quad;
 | 
						|
          curr_extent = Math.min((start + extent) - curr_begin, quad);
 | 
						|
        }
 | 
						|
      else
 | 
						|
        {
 | 
						|
          curr_begin = start - (current - 1) * quad;
 | 
						|
          curr_extent = Math.max((start + extent) - curr_begin, -quad);
 | 
						|
        }
 | 
						|
      
 | 
						|
      double portion_of_a_quadrant = Math.abs(curr_extent / quad);
 | 
						|
 | 
						|
      double x0 = xmid + rx * Math.cos(curr_begin);
 | 
						|
      double y0 = ymid - ry * Math.sin(curr_begin);
 | 
						|
 | 
						|
      double x1 = xmid + rx * Math.cos(curr_begin + curr_extent);
 | 
						|
      double y1 = ymid - ry * Math.sin(curr_begin + curr_extent);
 | 
						|
 | 
						|
      AffineTransform trans = new AffineTransform();
 | 
						|
      double[] cvec = new double[2];
 | 
						|
      double len = kappa * portion_of_a_quadrant;
 | 
						|
      double angle = curr_begin;
 | 
						|
 | 
						|
      // in a hypothetical "first quadrant" setting, our first control
 | 
						|
      // vector would be sticking up, from [1,0] to [1,kappa].
 | 
						|
      //
 | 
						|
      // let us recall however that in java2d, y coords are upside down
 | 
						|
      // from what one would consider "normal" first quadrant rules, so we
 | 
						|
      // will *subtract* the y value of this control vector from our first
 | 
						|
      // point.
 | 
						|
      cvec[0] = 0;
 | 
						|
      if (extent > 0)
 | 
						|
        cvec[1] = len;
 | 
						|
      else
 | 
						|
        cvec[1] = -len;
 | 
						|
      
 | 
						|
      trans.scale(rx, ry);
 | 
						|
      trans.rotate(angle);
 | 
						|
      trans.transform(cvec, 0, cvec, 0, 1);
 | 
						|
      coords[0] = x0 + cvec[0];
 | 
						|
      coords[1] = y0 - cvec[1];
 | 
						|
 | 
						|
      // control vector #2 would, ideally, be sticking out and to the
 | 
						|
      // right, in a first quadrant arc segment. again, subtraction of y.
 | 
						|
      cvec[0] = 0;
 | 
						|
      if (extent > 0)
 | 
						|
        cvec[1] = -len;
 | 
						|
      else
 | 
						|
        cvec[1] = len;
 | 
						|
      
 | 
						|
      trans.rotate(curr_extent);
 | 
						|
      trans.transform(cvec, 0, cvec, 0, 1);
 | 
						|
      coords[2] = x1 + cvec[0];
 | 
						|
      coords[3] = y1 - cvec[1];
 | 
						|
 | 
						|
      // end point
 | 
						|
      coords[4] = x1;
 | 
						|
      coords[5] = y1;
 | 
						|
 | 
						|
      if (xform != null)
 | 
						|
	xform.transform(coords, 0, coords, 0, 3);
 | 
						|
 | 
						|
      return SEG_CUBICTO;
 | 
						|
    }
 | 
						|
  } // class ArcIterator
 | 
						|
 | 
						|
  /**
 | 
						|
   * This class implements an arc in double precision.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   * @since 1.2
 | 
						|
   */
 | 
						|
  public static class Double extends Arc2D
 | 
						|
  {
 | 
						|
    /** The x coordinate of the box bounding the ellipse of this arc. */
 | 
						|
    public double x;
 | 
						|
 | 
						|
    /** The y coordinate of the box bounding the ellipse of this arc. */
 | 
						|
    public double y;
 | 
						|
 | 
						|
    /** The width of the box bounding the ellipse of this arc. */
 | 
						|
    public double width;
 | 
						|
 | 
						|
    /** The height of the box bounding the ellipse of this arc. */
 | 
						|
    public double height;
 | 
						|
 | 
						|
    /** The start angle of this arc, in degrees. */
 | 
						|
    public double start;
 | 
						|
 | 
						|
    /** The extent angle of this arc, in degrees. */
 | 
						|
    public double extent;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Create a new, open arc at (0,0) with 0 extent.
 | 
						|
     */
 | 
						|
    public Double()
 | 
						|
    {
 | 
						|
      super(OPEN);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Create a new arc of the given type at (0,0) with 0 extent.
 | 
						|
     *
 | 
						|
     * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
 | 
						|
     * @throws IllegalArgumentException if type is invalid
 | 
						|
     */
 | 
						|
    public Double(int type)
 | 
						|
    {
 | 
						|
      super(type);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Create a new arc with the given dimensions.
 | 
						|
     *
 | 
						|
     * @param x the x coordinate
 | 
						|
     * @param y the y coordinate
 | 
						|
     * @param w the width
 | 
						|
     * @param h the height
 | 
						|
     * @param start the start angle, in degrees
 | 
						|
     * @param extent the extent, in degrees
 | 
						|
     * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
 | 
						|
     * @throws IllegalArgumentException if type is invalid
 | 
						|
     */
 | 
						|
    public Double(double x, double y, double w, double h, double start,
 | 
						|
                  double extent, int type)
 | 
						|
    {
 | 
						|
      super(type);
 | 
						|
      this.x = x;
 | 
						|
      this.y = y;
 | 
						|
      width = w;
 | 
						|
      height = h;
 | 
						|
      this.start = start;
 | 
						|
      this.extent = extent;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Create a new arc with the given dimensions.
 | 
						|
     *
 | 
						|
     * @param r the bounding box
 | 
						|
     * @param start the start angle, in degrees
 | 
						|
     * @param extent the extent, in degrees
 | 
						|
     * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
 | 
						|
     * @throws IllegalArgumentException if type is invalid
 | 
						|
     * @throws NullPointerException if r is null
 | 
						|
     */
 | 
						|
    public Double(Rectangle2D r, double start, double extent, int type)
 | 
						|
    {
 | 
						|
      super(type);
 | 
						|
      x = r.getX();
 | 
						|
      y = r.getY();
 | 
						|
      width = r.getWidth();
 | 
						|
      height = r.getHeight();
 | 
						|
      this.start = start;
 | 
						|
      this.extent = extent;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the x coordinate of the bounding box.
 | 
						|
     *
 | 
						|
     * @return the value of x
 | 
						|
     */
 | 
						|
    public double getX()
 | 
						|
    {
 | 
						|
      return x;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the y coordinate of the bounding box.
 | 
						|
     *
 | 
						|
     * @return the value of y
 | 
						|
     */
 | 
						|
    public double getY()
 | 
						|
    {
 | 
						|
      return y;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the width of the bounding box.
 | 
						|
     *
 | 
						|
     * @return the value of width
 | 
						|
     */
 | 
						|
    public double getWidth()
 | 
						|
    {
 | 
						|
      return width;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the height of the bounding box.
 | 
						|
     *
 | 
						|
     * @return the value of height
 | 
						|
     */
 | 
						|
    public double getHeight()
 | 
						|
    {
 | 
						|
      return height;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the start angle of the arc, in degrees.
 | 
						|
     *
 | 
						|
     * @return the value of start
 | 
						|
     */
 | 
						|
    public double getAngleStart()
 | 
						|
    {
 | 
						|
      return start;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the extent of the arc, in degrees.
 | 
						|
     *
 | 
						|
     * @return the value of extent
 | 
						|
     */
 | 
						|
    public double getAngleExtent()
 | 
						|
    {
 | 
						|
      return extent;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Tests if the arc contains points.
 | 
						|
     *
 | 
						|
     * @return true if the arc has no interior
 | 
						|
     */
 | 
						|
    public boolean isEmpty()
 | 
						|
    {
 | 
						|
      return width <= 0 || height <= 0;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Sets the arc to the given dimensions.
 | 
						|
     *
 | 
						|
     * @param x the x coordinate
 | 
						|
     * @param y the y coordinate
 | 
						|
     * @param w the width
 | 
						|
     * @param h the height
 | 
						|
     * @param start the start angle, in degrees
 | 
						|
     * @param extent the extent, in degrees
 | 
						|
     * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
 | 
						|
     * @throws IllegalArgumentException if type is invalid
 | 
						|
     */
 | 
						|
    public void setArc(double x, double y, double w, double h, double start,
 | 
						|
                       double extent, int type)
 | 
						|
    {
 | 
						|
      this.x = x;
 | 
						|
      this.y = y;
 | 
						|
      width = w;
 | 
						|
      height = h;
 | 
						|
      this.start = start;
 | 
						|
      this.extent = extent;
 | 
						|
      setArcType(type);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Sets the start angle of the arc.
 | 
						|
     *
 | 
						|
     * @param start the new start angle
 | 
						|
     */
 | 
						|
    public void setAngleStart(double start)
 | 
						|
    {
 | 
						|
      this.start = start;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Sets the extent angle of the arc.
 | 
						|
     *
 | 
						|
     * @param extent the new extent angle
 | 
						|
     */
 | 
						|
    public void setAngleExtent(double extent)
 | 
						|
    {
 | 
						|
      this.extent = extent;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Creates a tight bounding box given dimensions that more precise than
 | 
						|
     * the bounding box of the ellipse.
 | 
						|
     *
 | 
						|
     * @param x the x coordinate
 | 
						|
     * @param y the y coordinate
 | 
						|
     * @param w the width
 | 
						|
     * @param h the height
 | 
						|
     */
 | 
						|
    protected Rectangle2D makeBounds(double x, double y, double w, double h)
 | 
						|
    {
 | 
						|
      return new Rectangle2D.Double(x, y, w, h);
 | 
						|
    }
 | 
						|
  } // class Double
 | 
						|
 | 
						|
  /**
 | 
						|
   * This class implements an arc in float precision.
 | 
						|
   *
 | 
						|
   * @author Eric Blake (ebb9@email.byu.edu)
 | 
						|
   * @since 1.2
 | 
						|
   */
 | 
						|
  public static class Float extends Arc2D
 | 
						|
  {
 | 
						|
    /** The x coordinate of the box bounding the ellipse of this arc. */
 | 
						|
    public float x;
 | 
						|
 | 
						|
    /** The y coordinate of the box bounding the ellipse of this arc. */
 | 
						|
    public float y;
 | 
						|
 | 
						|
    /** The width of the box bounding the ellipse of this arc. */
 | 
						|
    public float width;
 | 
						|
 | 
						|
    /** The height of the box bounding the ellipse of this arc. */
 | 
						|
    public float height;
 | 
						|
 | 
						|
    /** The start angle of this arc, in degrees. */
 | 
						|
    public float start;
 | 
						|
 | 
						|
    /** The extent angle of this arc, in degrees. */
 | 
						|
    public float extent;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Create a new, open arc at (0,0) with 0 extent.
 | 
						|
     */
 | 
						|
    public Float()
 | 
						|
    {
 | 
						|
      super(OPEN);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Create a new arc of the given type at (0,0) with 0 extent.
 | 
						|
     *
 | 
						|
     * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
 | 
						|
     * @throws IllegalArgumentException if type is invalid
 | 
						|
     */
 | 
						|
    public Float(int type)
 | 
						|
    {
 | 
						|
      super(type);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Create a new arc with the given dimensions.
 | 
						|
     *
 | 
						|
     * @param x the x coordinate
 | 
						|
     * @param y the y coordinate
 | 
						|
     * @param w the width
 | 
						|
     * @param h the height
 | 
						|
     * @param start the start angle, in degrees
 | 
						|
     * @param extent the extent, in degrees
 | 
						|
     * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
 | 
						|
     * @throws IllegalArgumentException if type is invalid
 | 
						|
     */
 | 
						|
    public Float(float x, float y, float w, float h, float start,
 | 
						|
                 float extent, int type)
 | 
						|
    {
 | 
						|
      super(type);
 | 
						|
      this.x = x;
 | 
						|
      this.y = y;
 | 
						|
      width = w;
 | 
						|
      height = h;
 | 
						|
      this.start = start;
 | 
						|
      this.extent = extent;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Create a new arc with the given dimensions.
 | 
						|
     *
 | 
						|
     * @param r the bounding box
 | 
						|
     * @param start the start angle, in degrees
 | 
						|
     * @param extent the extent, in degrees
 | 
						|
     * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
 | 
						|
     * @throws IllegalArgumentException if type is invalid
 | 
						|
     * @throws NullPointerException if r is null
 | 
						|
     */
 | 
						|
    public Float(Rectangle2D r, float start, float extent, int type)
 | 
						|
    {
 | 
						|
      super(type);
 | 
						|
      x = (float) r.getX();
 | 
						|
      y = (float) r.getY();
 | 
						|
      width = (float) r.getWidth();
 | 
						|
      height = (float) r.getHeight();
 | 
						|
      this.start = start;
 | 
						|
      this.extent = (float) extent;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the x coordinate of the bounding box.
 | 
						|
     *
 | 
						|
     * @return the value of x
 | 
						|
     */
 | 
						|
    public double getX()
 | 
						|
    {
 | 
						|
      return x;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the y coordinate of the bounding box.
 | 
						|
     *
 | 
						|
     * @return the value of y
 | 
						|
     */
 | 
						|
    public double getY()
 | 
						|
    {
 | 
						|
      return y;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the width of the bounding box.
 | 
						|
     *
 | 
						|
     * @return the value of width
 | 
						|
     */
 | 
						|
    public double getWidth()
 | 
						|
    {
 | 
						|
      return width;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the height of the bounding box.
 | 
						|
     *
 | 
						|
     * @return the value of height
 | 
						|
     */
 | 
						|
    public double getHeight()
 | 
						|
    {
 | 
						|
      return height;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the start angle of the arc, in degrees.
 | 
						|
     *
 | 
						|
     * @return the value of start
 | 
						|
     */
 | 
						|
    public double getAngleStart()
 | 
						|
    {
 | 
						|
      return start;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Return the extent of the arc, in degrees.
 | 
						|
     *
 | 
						|
     * @return the value of extent
 | 
						|
     */
 | 
						|
    public double getAngleExtent()
 | 
						|
    {
 | 
						|
      return extent;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Tests if the arc contains points.
 | 
						|
     *
 | 
						|
     * @return true if the arc has no interior
 | 
						|
     */
 | 
						|
    public boolean isEmpty()
 | 
						|
    {
 | 
						|
      return width <= 0 || height <= 0;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Sets the arc to the given dimensions.
 | 
						|
     *
 | 
						|
     * @param x the x coordinate
 | 
						|
     * @param y the y coordinate
 | 
						|
     * @param w the width
 | 
						|
     * @param h the height
 | 
						|
     * @param start the start angle, in degrees
 | 
						|
     * @param extent the extent, in degrees
 | 
						|
     * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
 | 
						|
     * @throws IllegalArgumentException if type is invalid
 | 
						|
     */
 | 
						|
    public void setArc(double x, double y, double w, double h, double start,
 | 
						|
                       double extent, int type)
 | 
						|
    {
 | 
						|
      this.x = (float) x;
 | 
						|
      this.y = (float) y;
 | 
						|
      width = (float) w;
 | 
						|
      height = (float) h;
 | 
						|
      this.start = (float) start;
 | 
						|
      this.extent = (float) extent;
 | 
						|
      setArcType(type);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Sets the start angle of the arc.
 | 
						|
     *
 | 
						|
     * @param start the new start angle
 | 
						|
     */
 | 
						|
    public void setAngleStart(double start)
 | 
						|
    {
 | 
						|
      this.start = (float) start;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Sets the extent angle of the arc.
 | 
						|
     *
 | 
						|
     * @param extent the new extent angle
 | 
						|
     */
 | 
						|
    public void setAngleExtent(double extent)
 | 
						|
    {
 | 
						|
      this.extent = (float) extent;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Creates a tight bounding box given dimensions that more precise than
 | 
						|
     * the bounding box of the ellipse.
 | 
						|
     *
 | 
						|
     * @param x the x coordinate
 | 
						|
     * @param y the y coordinate
 | 
						|
     * @param w the width
 | 
						|
     * @param h the height
 | 
						|
     */
 | 
						|
    protected Rectangle2D makeBounds(double x, double y, double w, double h)
 | 
						|
    {
 | 
						|
      return new Rectangle2D.Float((float) x, (float) y, (float) w, (float) h);
 | 
						|
    }
 | 
						|
  } // class Float
 | 
						|
} // class Arc2D
 |