/* 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 = a.getAngleStart() * (Math.PI / 180);
      double extent = a.getAngleExtent() * (Math.PI / 180);

      if (extent < 0)
        {
	  extent = -extent;
	  start = 2 * Math.PI - extent + start;
        }
      this.start = start;
      this.extent = extent;

      type = a.type;
      if (w < 0 || h < 0)
	limit = -1;
      else if (extent == 0)
	limit = type;
      else if (extent <= Math.PI / 2.0)
	limit = type + 1;
      else if (extent <= Math.PI)
	limit = type + 2;
      else if (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 = start + (current - 1) * quad;
      double curr_extent = Math.min((start + extent) - curr_begin, quad);
      double portion_of_a_quadrant = 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;
      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;
      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
