/* QuadCurve2D.java -- represents a parameterized quadratic curve 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.awt.Rectangle;
import java.awt.Shape;
import java.util.NoSuchElementException;

/**
 * A two-dimensional curve that is parameterized with a quadratic
 * function.
 *
 * <p><img src="doc-files/QuadCurve2D-1.png" width="350" height="180"
 * alt="A drawing of a QuadCurve2D" />
 *
 * @author Eric Blake (ebb9@email.byu.edu)
 * @author Graydon Hoare (graydon@redhat.com)
 * @author Sascha Brawer (brawer@dandelis.ch)
 * @author Sven de Marothy (sven@physto.se)
 *
 * @since 1.2
 */
public abstract class QuadCurve2D implements Shape, Cloneable
{
  private static final double BIG_VALUE = java.lang.Double.MAX_VALUE / 10.0;
  private static final double EPSILON = 1E-10;

  /**
   * Constructs a new QuadCurve2D. Typical users will want to
   * construct instances of a subclass, such as {@link
   * QuadCurve2D.Float} or {@link QuadCurve2D.Double}.
   */
  protected QuadCurve2D()
  {
  }

  /**
   * Returns the <i>x</i> coordinate of the curve&#x2019;s start
   * point.
   */
  public abstract double getX1();

  /**
   * Returns the <i>y</i> coordinate of the curve&#x2019;s start
   * point.
   */
  public abstract double getY1();

  /**
   * Returns the curve&#x2019;s start point.
   */
  public abstract Point2D getP1();

  /**
   * Returns the <i>x</i> coordinate of the curve&#x2019;s control
   * point.
   */
  public abstract double getCtrlX();

  /**
   * Returns the <i>y</i> coordinate of the curve&#x2019;s control
   * point.
   */
  public abstract double getCtrlY();

  /**
   * Returns the curve&#x2019;s control point.
   */
  public abstract Point2D getCtrlPt();

  /**
   * Returns the <i>x</i> coordinate of the curve&#x2019;s end
   * point.
   */
  public abstract double getX2();

  /**
   * Returns the <i>y</i> coordinate of the curve&#x2019;s end
   * point.
   */
  public abstract double getY2();

  /**
   * Returns the curve&#x2019;s end point.
   */
  public abstract Point2D getP2();

  /**
   * Changes the curve geometry, separately specifying each coordinate
   * value.
   *
   * @param x1 the <i>x</i> coordinate of the curve&#x2019;s new start
   * point.
   *
   * @param y1 the <i>y</i> coordinate of the curve&#x2019;s new start
   * point.
   *
   * @param cx the <i>x</i> coordinate of the curve&#x2019;s new
   * control point.
   *
   * @param cy the <i>y</i> coordinate of the curve&#x2019;s new
   * control point.
   *
   * @param x2 the <i>x</i> coordinate of the curve&#x2019;s new end
   * point.
   *
   * @param y2 the <i>y</i> coordinate of the curve&#x2019;s new end
   * point.
   */
  public abstract void setCurve(double x1, double y1, double cx, double cy,
                                double x2, double y2);

  /**
   * Changes the curve geometry, passing coordinate values in an
   * array.
   *
   * @param coords an array containing the new coordinate values.  The
   * <i>x</i> coordinate of the new start point is located at
   * <code>coords[offset]</code>, its <i>y</i> coordinate at
   * <code>coords[offset + 1]</code>.  The <i>x</i> coordinate of the
   * new control point is located at <code>coords[offset + 2]</code>,
   * its <i>y</i> coordinate at <code>coords[offset + 3]</code>. The
   * <i>x</i> coordinate of the new end point is located at
   * <code>coords[offset + 4]</code>, its <i>y</i> coordinate at
   * <code>coords[offset + 5]</code>.
   *
   * @param offset the offset of the first coordinate value in
   * <code>coords</code>.
   */
  public void setCurve(double[] coords, int offset)
  {
    setCurve(coords[offset++], coords[offset++], coords[offset++],
             coords[offset++], coords[offset++], coords[offset++]);
  }

  /**
   * Changes the curve geometry, specifying coordinate values in
   * separate Point objects.
   *
   * <p><img src="doc-files/QuadCurve2D-1.png" width="350" height="180"
   * alt="A drawing of a QuadCurve2D" />
   *
   * <p>The curve does not keep any reference to the passed point
   * objects. Therefore, a later change to <code>p1</code>,
   * <code>c</code> <code>p2</code> will not affect the curve
   * geometry.
   *
   * @param p1 the new start point.
   * @param c the new control point.
   * @param p2 the new end point.
   */
  public void setCurve(Point2D p1, Point2D c, Point2D p2)
  {
    setCurve(p1.getX(), p1.getY(), c.getX(), c.getY(), p2.getX(), p2.getY());
  }

  /**
   * Changes the curve geometry, specifying coordinate values in an
   * array of Point objects.
   *
   * <p><img src="doc-files/QuadCurve2D-1.png" width="350" height="180"
   * alt="A drawing of a QuadCurve2D" />
   *
   * <p>The curve does not keep references to the passed point
   * objects. Therefore, a later change to the <code>pts</code> array
   * or any of its elements will not affect the curve geometry.
   *
   * @param pts an array containing the points. The new start point
   * is located at <code>pts[offset]</code>, the new control
   * point at <code>pts[offset + 1]</code>, and the new end point
   * at <code>pts[offset + 2]</code>.
   *
   * @param offset the offset of the start point in <code>pts</code>.
   */
  public void setCurve(Point2D[] pts, int offset)
  {
    setCurve(pts[offset].getX(), pts[offset].getY(), pts[offset + 1].getX(),
             pts[offset + 1].getY(), pts[offset + 2].getX(),
             pts[offset + 2].getY());
  }

  /**
   * Changes the geometry of the curve to that of another curve.
   *
   * @param c the curve whose coordinates will be copied.
   */
  public void setCurve(QuadCurve2D c)
  {
    setCurve(c.getX1(), c.getY1(), c.getCtrlX(), c.getCtrlY(), c.getX2(),
             c.getY2());
  }

  /**
   * Calculates the squared flatness of a quadratic curve, directly
   * specifying each coordinate value. The flatness is the distance of
   * the control point to the line between start and end point.
   *
   * <p><img src="doc-files/QuadCurve2D-4.png" width="350" height="180"
   * alt="A drawing that illustrates the flatness" />
   *
   * <p>In the above drawing, the straight line connecting start point
   * P1 and end point P2 is depicted in gray.  The result will be the
   * the square of the distance between C and the gray line, i.e.
   * the squared length of the red line.
   *
   * @param x1 the <i>x</i> coordinate of the start point P1.
   * @param y1 the <i>y</i> coordinate of the start point P1.
   * @param cx the <i>x</i> coordinate of the control point C.
   * @param cy the <i>y</i> coordinate of the control point C.
   * @param x2 the <i>x</i> coordinate of the end point P2.
   * @param y2 the <i>y</i> coordinate of the end point P2.
   */
  public static double getFlatnessSq(double x1, double y1, double cx,
                                     double cy, double x2, double y2)
  {
    return Line2D.ptSegDistSq(x1, y1, x2, y2, cx, cy);
  }

  /**
   * Calculates the flatness of a quadratic curve, directly specifying
   * each coordinate value. The flatness is the distance of the
   * control point to the line between start and end point.
   *
   * <p><img src="doc-files/QuadCurve2D-4.png" width="350" height="180"
   * alt="A drawing that illustrates the flatness" />
   *
   * <p>In the above drawing, the straight line connecting start point
   * P1 and end point P2 is depicted in gray.  The result will be the
   * the distance between C and the gray line, i.e. the length of
   * the red line.
   *
   * @param x1 the <i>x</i> coordinate of the start point P1.
   * @param y1 the <i>y</i> coordinate of the start point P1.
   * @param cx the <i>x</i> coordinate of the control point C.
   * @param cy the <i>y</i> coordinate of the control point C.
   * @param x2 the <i>x</i> coordinate of the end point P2.
   * @param y2 the <i>y</i> coordinate of the end point P2.
   */
  public static double getFlatness(double x1, double y1, double cx, double cy,
                                   double x2, double y2)
  {
    return Line2D.ptSegDist(x1, y1, x2, y2, cx, cy);
  }

  /**
   * Calculates the squared flatness of a quadratic curve, specifying
   * the coordinate values in an array. The flatness is the distance
   * of the control point to the line between start and end point.
   *
   * <p><img src="doc-files/QuadCurve2D-4.png" width="350" height="180"
   * alt="A drawing that illustrates the flatness" />
   *
   * <p>In the above drawing, the straight line connecting start point
   * P1 and end point P2 is depicted in gray.  The result will be the
   * the square of the distance between C and the gray line, i.e.
   * the squared length of the red line.
   *
   * @param coords an array containing the coordinate values.  The
   * <i>x</i> coordinate of the start point P1 is located at
   * <code>coords[offset]</code>, its <i>y</i> coordinate at
   * <code>coords[offset + 1]</code>.  The <i>x</i> coordinate of the
   * control point C is located at <code>coords[offset + 2]</code>,
   * its <i>y</i> coordinate at <code>coords[offset + 3]</code>. The
   * <i>x</i> coordinate of the end point P2 is located at
   * <code>coords[offset + 4]</code>, its <i>y</i> coordinate at
   * <code>coords[offset + 5]</code>.
   *
   * @param offset the offset of the first coordinate value in
   * <code>coords</code>.
   */
  public static double getFlatnessSq(double[] coords, int offset)
  {
    return Line2D.ptSegDistSq(coords[offset], coords[offset + 1],
                              coords[offset + 4], coords[offset + 5],
                              coords[offset + 2], coords[offset + 3]);
  }

  /**
   * Calculates the flatness of a quadratic curve, specifying the
   * coordinate values in an array. The flatness is the distance of
   * the control point to the line between start and end point.
   *
   * <p><img src="doc-files/QuadCurve2D-4.png" width="350" height="180"
   * alt="A drawing that illustrates the flatness" />
   *
   * <p>In the above drawing, the straight line connecting start point
   * P1 and end point P2 is depicted in gray.  The result will be the
   * the the distance between C and the gray line, i.e.  the length of
   * the red line.
   *
   * @param coords an array containing the coordinate values.  The
   * <i>x</i> coordinate of the start point P1 is located at
   * <code>coords[offset]</code>, its <i>y</i> coordinate at
   * <code>coords[offset + 1]</code>.  The <i>x</i> coordinate of the
   * control point C is located at <code>coords[offset + 2]</code>,
   * its <i>y</i> coordinate at <code>coords[offset + 3]</code>. The
   * <i>x</i> coordinate of the end point P2 is located at
   * <code>coords[offset + 4]</code>, its <i>y</i> coordinate at
   * <code>coords[offset + 5]</code>.
   *
   * @param offset the offset of the first coordinate value in
   * <code>coords</code>.
   */
  public static double getFlatness(double[] coords, int offset)
  {
    return Line2D.ptSegDist(coords[offset], coords[offset + 1],
                            coords[offset + 4], coords[offset + 5],
                            coords[offset + 2], coords[offset + 3]);
  }

  /**
   * Calculates the squared flatness of this curve. The flatness is
   * the distance of the control point to the line between start and
   * end point.
   *
   * <p><img src="doc-files/QuadCurve2D-4.png" width="350" height="180"
   * alt="A drawing that illustrates the flatness" />
   *
   * <p>In the above drawing, the straight line connecting start point
   * P1 and end point P2 is depicted in gray.  The result will be the
   * the square of the distance between C and the gray line, i.e. the
   * squared length of the red line.
   */
  public double getFlatnessSq()
  {
    return Line2D.ptSegDistSq(getX1(), getY1(), getX2(), getY2(), getCtrlX(),
                              getCtrlY());
  }

  /**
   * Calculates the flatness of this curve. The flatness is the
   * distance of the control point to the line between start and end
   * point.
   *
   * <p><img src="doc-files/QuadCurve2D-4.png" width="350" height="180"
   * alt="A drawing that illustrates the flatness" />
   *
   * <p>In the above drawing, the straight line connecting start point
   * P1 and end point P2 is depicted in gray.  The result will be the
   * the distance between C and the gray line, i.e.  the length of the
   * red line.
   */
  public double getFlatness()
  {
    return Line2D.ptSegDist(getX1(), getY1(), getX2(), getY2(), getCtrlX(),
                            getCtrlY());
  }

  /**
   * Subdivides this curve into two halves.
   *
   * <p><img src="doc-files/QuadCurve2D-3.png" width="700"
   * height="180" alt="A drawing that illustrates the effects of
   * subdividing a QuadCurve2D" />
   *
   * @param left a curve whose geometry will be set to the left half
   * of this curve, or <code>null</code> if the caller is not
   * interested in the left half.
   *
   * @param right a curve whose geometry will be set to the right half
   * of this curve, or <code>null</code> if the caller is not
   * interested in the right half.
   */
  public void subdivide(QuadCurve2D left, QuadCurve2D right)
  {
    // Use empty slots at end to share single array.
    double[] d = new double[]
                 {
                   getX1(), getY1(), getCtrlX(), getCtrlY(), getX2(), getY2(),
                   0, 0, 0, 0
                 };
    subdivide(d, 0, d, 0, d, 4);
    if (left != null)
      left.setCurve(d, 0);
    if (right != null)
      right.setCurve(d, 4);
  }

  /**
   * Subdivides a quadratic curve into two halves.
   *
   * <p><img src="doc-files/QuadCurve2D-3.png" width="700"
   * height="180" alt="A drawing that illustrates the effects of
   * subdividing a QuadCurve2D" />
   *
   * @param src the curve to be subdivided.
   *
   * @param left a curve whose geometry will be set to the left half
   * of <code>src</code>, or <code>null</code> if the caller is not
   * interested in the left half.
   *
   * @param right a curve whose geometry will be set to the right half
   * of <code>src</code>, or <code>null</code> if the caller is not
   * interested in the right half.
   */
  public static void subdivide(QuadCurve2D src, QuadCurve2D left,
                               QuadCurve2D right)
  {
    src.subdivide(left, right);
  }

  /**
   * Subdivides a quadratic curve into two halves, passing all
   * coordinates in an array.
   *
   * <p><img src="doc-files/QuadCurve2D-3.png" width="700"
   * height="180" alt="A drawing that illustrates the effects of
   * subdividing a QuadCurve2D" />
   *
   * <p>The left end point and the right start point will always be
   * identical. Memory-concious programmers thus may want to pass the
   * same array for both <code>left</code> and <code>right</code>, and
   * set <code>rightOff</code> to <code>leftOff + 4</code>.
   *
   * @param src an array containing the coordinates of the curve to be
   * subdivided.  The <i>x</i> coordinate of the start point is
   * located at <code>src[srcOff]</code>, its <i>y</i> at
   * <code>src[srcOff + 1]</code>.  The <i>x</i> coordinate of the
   * control point is located at <code>src[srcOff + 2]</code>, its
   * <i>y</i> at <code>src[srcOff + 3]</code>.  The <i>x</i>
   * coordinate of the end point is located at <code>src[srcOff +
   * 4]</code>, its <i>y</i> at <code>src[srcOff + 5]</code>.
   *
   * @param srcOff an offset into <code>src</code>, specifying
   * the index of the start point&#x2019;s <i>x</i> coordinate.
   *
   * @param left an array that will receive the coordinates of the
   * left half of <code>src</code>. It is acceptable to pass
   * <code>src</code>. A caller who is not interested in the left half
   * can pass <code>null</code>.
   *
   * @param leftOff an offset into <code>left</code>, specifying the
   * index where the start point&#x2019;s <i>x</i> coordinate will be
   * stored.
   *
   * @param right an array that will receive the coordinates of the
   * right half of <code>src</code>. It is acceptable to pass
   * <code>src</code> or <code>left</code>. A caller who is not
   * interested in the right half can pass <code>null</code>.
   *
   * @param rightOff an offset into <code>right</code>, specifying the
   * index where the start point&#x2019;s <i>x</i> coordinate will be
   * stored.
   */
  public static void subdivide(double[] src, int srcOff, double[] left,
                               int leftOff, double[] right, int rightOff)
  {
    double x1;
    double y1;
    double xc;
    double yc;
    double x2;
    double y2;

    x1 = src[srcOff];
    y1 = src[srcOff + 1];
    xc = src[srcOff + 2];
    yc = src[srcOff + 3];
    x2 = src[srcOff + 4];
    y2 = src[srcOff + 5];

    if (left != null)
      {
        left[leftOff] = x1;
        left[leftOff + 1] = y1;
      }

    if (right != null)
      {
        right[rightOff + 4] = x2;
        right[rightOff + 5] = y2;
      }

    x1 = (x1 + xc) / 2;
    x2 = (xc + x2) / 2;
    xc = (x1 + x2) / 2;
    y1 = (y1 + yc) / 2;
    y2 = (y2 + yc) / 2;
    yc = (y1 + y2) / 2;

    if (left != null)
      {
        left[leftOff + 2] = x1;
        left[leftOff + 3] = y1;
        left[leftOff + 4] = xc;
        left[leftOff + 5] = yc;
      }

    if (right != null)
      {
        right[rightOff] = xc;
        right[rightOff + 1] = yc;
        right[rightOff + 2] = x2;
        right[rightOff + 3] = y2;
      }
  }

  /**
   * Finds the non-complex roots of a quadratic equation, placing the
   * results into the same array as the equation coefficients. The
   * following equation is being solved:
   *
   * <blockquote><code>eqn[2]</code> &#xb7; <i>x</i><sup>2</sup>
   * + <code>eqn[1]</code> &#xb7; <i>x</i>
   * + <code>eqn[0]</code>
   * = 0
   * </blockquote>
   *
   * <p>For some background about solving quadratic equations, see the
   * article <a href=
   * "http://planetmath.org/encyclopedia/QuadraticFormula.html"
   * >&#x201c;Quadratic Formula&#x201d;</a> in <a href=
   * "http://planetmath.org/">PlanetMath</a>. For an extensive library
   * of numerical algorithms written in the C programming language,
   * see the <a href="http://www.gnu.org/software/gsl/">GNU Scientific
   * Library</a>.
   *
   * @see #solveQuadratic(double[], double[])
   * @see CubicCurve2D#solveCubic(double[], double[])
   *
   * @param eqn an array with the coefficients of the equation. When
   * this procedure has returned, <code>eqn</code> will contain the
   * non-complex solutions of the equation, in no particular order.
   *
   * @return the number of non-complex solutions. A result of 0
   * indicates that the equation has no non-complex solutions. A
   * result of -1 indicates that the equation is constant (i.e.,
   * always or never zero).
   *
   * @author Brian Gough (bjg@network-theory.com)
   * (original C implementation in the <a href=
   * "http://www.gnu.org/software/gsl/">GNU Scientific Library</a>)
   *
   * @author Sascha Brawer (brawer@dandelis.ch)
   * (adaptation to Java)
   */
  public static int solveQuadratic(double[] eqn)
  {
    return solveQuadratic(eqn, eqn);
  }

  /**
   * Finds the non-complex roots of a quadratic equation. The
   * following equation is being solved:
   *
   * <blockquote><code>eqn[2]</code> &#xb7; <i>x</i><sup>2</sup>
   * + <code>eqn[1]</code> &#xb7; <i>x</i>
   * + <code>eqn[0]</code>
   * = 0
   * </blockquote>
   *
   * <p>For some background about solving quadratic equations, see the
   * article <a href=
   * "http://planetmath.org/encyclopedia/QuadraticFormula.html"
   * >&#x201c;Quadratic Formula&#x201d;</a> in <a href=
   * "http://planetmath.org/">PlanetMath</a>. For an extensive library
   * of numerical algorithms written in the C programming language,
   * see the <a href="http://www.gnu.org/software/gsl/">GNU Scientific
   * Library</a>.
   *
   * @see CubicCurve2D#solveCubic(double[],double[])
   *
   * @param eqn an array with the coefficients of the equation.
   *
   * @param res an array into which the non-complex roots will be
   * stored.  The results may be in an arbitrary order. It is safe to
   * pass the same array object reference for both <code>eqn</code>
   * and <code>res</code>.
   *
   * @return the number of non-complex solutions. A result of 0
   * indicates that the equation has no non-complex solutions. A
   * result of -1 indicates that the equation is constant (i.e.,
   * always or never zero).
   *
   * @author Brian Gough (bjg@network-theory.com)
   * (original C implementation in the <a href=
   * "http://www.gnu.org/software/gsl/">GNU Scientific Library</a>)
   *
   * @author Sascha Brawer (brawer@dandelis.ch)
   * (adaptation to Java)
   */
  public static int solveQuadratic(double[] eqn, double[] res)
  {
    // Taken from poly/solve_quadratic.c in the GNU Scientific Library
    // (GSL), cvs revision 1.7 of 2003-07-26. For the original source,
    // see http://www.gnu.org/software/gsl/
    //
    // Brian Gough, the author of that code, has granted the
    // permission to use it in GNU Classpath under the GNU Classpath
    // license, and has assigned the copyright to the Free Software
    // Foundation.
    //
    // The Java implementation is very similar to the GSL code, but
    // not a strict one-to-one copy. For example, GSL would sort the
    // result.
    double a;
    double b;
    double c;
    double disc;

    c = eqn[0];
    b = eqn[1];
    a = eqn[2];

    // Check for linear or constant functions. This is not done by the
    // GNU Scientific Library.  Without this special check, we
    // wouldn't return -1 for constant functions, and 2 instead of 1
    // for linear functions.
    if (a == 0)
      {
        if (b == 0)
          return -1;

        res[0] = -c / b;
        return 1;
      }

    disc = b * b - 4 * a * c;

    if (disc < 0)
      return 0;

    if (disc == 0)
      {
        // The GNU Scientific Library returns two identical results here.
        // We just return one.
        res[0] = -0.5 * b / a;
        return 1;
      }

    // disc > 0
    if (b == 0)
      {
        double r;

        r = Math.abs(0.5 * Math.sqrt(disc) / a);
        res[0] = -r;
        res[1] = r;
      }
    else
      {
        double sgnb;
        double temp;

        sgnb = (b > 0 ? 1 : -1);
        temp = -0.5 * (b + sgnb * Math.sqrt(disc));

        // The GNU Scientific Library sorts the result here. We don't.
        res[0] = temp / a;
        res[1] = c / temp;
      }
    return 2;
  }

  /**
   * Determines whether a point is inside the area bounded
   * by the curve and the straight line connecting its end points.
   *
   * <p><img src="doc-files/QuadCurve2D-5.png" width="350" height="180"
   * alt="A drawing of the area spanned by the curve" />
   *
   * <p>The above drawing illustrates in which area points are
   * considered &#x201c;inside&#x201d; a QuadCurve2D.
   */
  public boolean contains(double x, double y)
  {
    if (! getBounds2D().contains(x, y))
      return false;

    return ((getAxisIntersections(x, y, true, BIG_VALUE) & 1) != 0);
  }

  /**
   * Determines whether a point is inside the area bounded
   * by the curve and the straight line connecting its end points.
   *
   * <p><img src="doc-files/QuadCurve2D-5.png" width="350" height="180"
   * alt="A drawing of the area spanned by the curve" />
   *
   * <p>The above drawing illustrates in which area points are
   * considered &#x201c;inside&#x201d; a QuadCurve2D.
   */
  public boolean contains(Point2D p)
  {
    return contains(p.getX(), p.getY());
  }

  /**
   * Determines whether any part of a rectangle is inside the area bounded
   * by the curve and the straight line connecting its end points.
   *
   * <p><img src="doc-files/QuadCurve2D-5.png" width="350" height="180"
   * alt="A drawing of the area spanned by the curve" />
   *
   * <p>The above drawing illustrates in which area points are
   * considered &#x201c;inside&#x201d; in a CubicCurve2D.
   */
  public boolean intersects(double x, double y, double w, double h)
  {
    if (! getBounds2D().contains(x, y, w, h))
      return false;

    /* Does any edge intersect? */
    if (getAxisIntersections(x, y, true, w) != 0 /* top */
        || getAxisIntersections(x, y + h, true, w) != 0 /* bottom */
        || getAxisIntersections(x + w, y, false, h) != 0 /* right */
        || getAxisIntersections(x, y, false, h) != 0) /* left */
      return true;

    /* No intersections, is any point inside? */
    if ((getAxisIntersections(x, y, true, BIG_VALUE) & 1) != 0)
      return true;

    return false;
  }

  /**
   * Determines whether any part of a Rectangle2D is inside the area bounded
   * by the curve and the straight line connecting its end points.
   * @see #intersects(double, double, double, double)
   */
  public boolean intersects(Rectangle2D r)
  {
    return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
  }

  /**
   * Determines whether a rectangle is entirely inside the area bounded
   * by the curve and the straight line connecting its end points.
   *
   * <p><img src="doc-files/QuadCurve2D-5.png" width="350" height="180"
   * alt="A drawing of the area spanned by the curve" />
   *
   * <p>The above drawing illustrates in which area points are
   * considered &#x201c;inside&#x201d; a QuadCurve2D.
   * @see #contains(double, double)
   */
  public boolean contains(double x, double y, double w, double h)
  {
    if (! getBounds2D().intersects(x, y, w, h))
      return false;

    /* Does any edge intersect? */
    if (getAxisIntersections(x, y, true, w) != 0 /* top */
        || getAxisIntersections(x, y + h, true, w) != 0 /* bottom */
        || getAxisIntersections(x + w, y, false, h) != 0 /* right */
        || getAxisIntersections(x, y, false, h) != 0) /* left */
      return false;

    /* No intersections, is any point inside? */
    if ((getAxisIntersections(x, y, true, BIG_VALUE) & 1) != 0)
      return true;

    return false;
  }

  /**
   * Determines whether a Rectangle2D is entirely inside the area that is
   * bounded by the curve and the straight line connecting its end points.
   * @see #contains(double, double, double, double)
   */
  public boolean contains(Rectangle2D r)
  {
    return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
  }

  /**
   * Determines the smallest rectangle that encloses the
   * curve&#x2019;s start, end and control point. As the illustration
   * below shows, the invisible control point may cause the bounds to
   * be much larger than the area that is actually covered by the
   * curve.
   *
   * <p><img src="doc-files/QuadCurve2D-2.png" width="350" height="180"
   * alt="An illustration of the bounds of a QuadCurve2D" />
   */
  public Rectangle getBounds()
  {
    return getBounds2D().getBounds();
  }

  public PathIterator getPathIterator(final AffineTransform at)
  {
    return new PathIterator()
      {
        /** Current coordinate. */
        private int current = 0;

        public int getWindingRule()
        {
          return WIND_NON_ZERO;
        }

        public boolean isDone()
        {
          return current >= 2;
        }

        public void next()
        {
          current++;
        }

        public int currentSegment(float[] coords)
        {
          int result;
          switch (current)
            {
            case 0:
              coords[0] = (float) getX1();
              coords[1] = (float) getY1();
              result = SEG_MOVETO;
              break;
            case 1:
              coords[0] = (float) getCtrlX();
              coords[1] = (float) getCtrlY();
              coords[2] = (float) getX2();
              coords[3] = (float) getY2();
              result = SEG_QUADTO;
              break;
            default:
              throw new NoSuchElementException("quad iterator out of bounds");
            }
          if (at != null)
            at.transform(coords, 0, coords, 0, 2);
          return result;
        }

        public int currentSegment(double[] coords)
        {
          int result;
          switch (current)
            {
            case 0:
              coords[0] = getX1();
              coords[1] = getY1();
              result = SEG_MOVETO;
              break;
            case 1:
              coords[0] = getCtrlX();
              coords[1] = getCtrlY();
              coords[2] = getX2();
              coords[3] = getY2();
              result = SEG_QUADTO;
              break;
            default:
              throw new NoSuchElementException("quad iterator out of bounds");
            }
          if (at != null)
            at.transform(coords, 0, coords, 0, 2);
          return result;
        }
      };
  }

  public PathIterator getPathIterator(AffineTransform at, double flatness)
  {
    return new FlatteningPathIterator(getPathIterator(at), flatness);
  }

  /**
   * Creates a new curve with the same contents as this one.
   *
   * @return the clone.
   */
  public Object clone()
  {
    try
      {
        return super.clone();
      }
    catch (CloneNotSupportedException e)
      {
        throw (Error) new InternalError().initCause(e); // Impossible
      }
  }

  /**
   * Helper method used by contains() and intersects() methods
   * Return the number of curve/line intersections on a given axis
   * extending from a certain point. useYaxis is true for using the Y axis,
   * @param x x coordinate of the origin point
   * @param y y coordinate of the origin point
   * @param useYaxis axis to follow, if true the positive Y axis is used,
   * false uses the positive X axis.
   *
   * This is an implementation of the line-crossings algorithm,
   * Detailed in an article on Eric Haines' page:
   * http://www.acm.org/tog/editors/erich/ptinpoly/
   */
  private int getAxisIntersections(double x, double y, boolean useYaxis,
                                   double distance)
  {
    int nCrossings = 0;
    double a0;
    double a1;
    double a2;
    double b0;
    double b1;
    double b2;
    double[] r = new double[3];
    int nRoots;

    a0 = a2 = 0.0;

    if (useYaxis)
      {
        a0 = getY1() - y;
        a1 = getCtrlY() - y;
        a2 = getY2() - y;
        b0 = getX1() - x;
        b1 = getCtrlX() - x;
        b2 = getX2() - x;
      }
    else
      {
        a0 = getX1() - x;
        a1 = getCtrlX() - x;
        a2 = getX2() - x;
        b0 = getY1() - y;
        b1 = getCtrlY() - y;
        b2 = getY2() - y;
      }

    /* If the axis intersects a start/endpoint, shift it up by some small
       amount to guarantee the line is 'inside'
       If this is not done,bad behaviour may result for points on that axis. */
    if (a0 == 0.0 || a2 == 0.0)
      {
        double small = getFlatness() * EPSILON;
        if (a0 == 0.0)
          a0 -= small;

        if (a2 == 0.0)
          a2 -= small;
      }

    r[0] = a0;
    r[1] = 2 * (a1 - a0);
    r[2] = (a2 - 2 * a1 + a0);

    nRoots = solveQuadratic(r);
    for (int i = 0; i < nRoots; i++)
      {
        double t = r[i];
        if (t >= 0.0 && t <= 1.0)
          {
            double crossing = t * t * (b2 - 2 * b1 + b0) + 2 * t * (b1 - b0)
                              + b0;
            /* single root is always doubly degenerate in quads */
            if (crossing > 0 && crossing < distance)
              nCrossings += (nRoots == 1) ? 2 : 1;
          }
      }

    if (useYaxis)
      {
        if (Line2D.linesIntersect(b0, a0, b2, a2, EPSILON, 0.0, distance, 0.0))
          nCrossings++;
      }
    else
      {
        if (Line2D.linesIntersect(a0, b0, a2, b2, 0.0, EPSILON, 0.0, distance))
          nCrossings++;
      }

    return (nCrossings);
  }

  /**
   * A two-dimensional curve that is parameterized with a quadratic
   * function and stores coordinate values in double-precision
   * floating-point format.
   *
   * @see QuadCurve2D.Float
   *
   * @author Eric Blake (ebb9@email.byu.edu)
   * @author Sascha Brawer (brawer@dandelis.ch)
   */
  public static class Double extends QuadCurve2D
  {
    /**
     * The <i>x</i> coordinate of the curve&#x2019;s start point.
     */
    public double x1;

    /**
     * The <i>y</i> coordinate of the curve&#x2019;s start point.
     */
    public double y1;

    /**
     * The <i>x</i> coordinate of the curve&#x2019;s control point.
     */
    public double ctrlx;

    /**
     * The <i>y</i> coordinate of the curve&#x2019;s control point.
     */
    public double ctrly;

    /**
     * The <i>x</i> coordinate of the curve&#x2019;s end point.
     */
    public double x2;

    /**
     * The <i>y</i> coordinate of the curve&#x2019;s end point.
     */
    public double y2;

    /**
     * Constructs a new QuadCurve2D that stores its coordinate values
     * in double-precision floating-point format. All points are
     * initially at position (0, 0).
     */
    public Double()
    {
    }

    /**
     * Constructs a new QuadCurve2D that stores its coordinate values
     * in double-precision floating-point format, specifying the
     * initial position of each point.
     *
     * @param x1 the <i>x</i> coordinate of the curve&#x2019;s start
     * point.
     *
     * @param y1 the <i>y</i> coordinate of the curve&#x2019;s start
     * point.
     *
     * @param cx the <i>x</i> coordinate of the curve&#x2019;s control
     * point.
     *
     * @param cy the <i>y</i> coordinate of the curve&#x2019;s control
     * point.
     *
     * @param x2 the <i>x</i> coordinate of the curve&#x2019;s end
     * point.
     *
     * @param y2 the <i>y</i> coordinate of the curve&#x2019;s end
     * point.
     */
    public Double(double x1, double y1, double cx, double cy, double x2,
                  double y2)
    {
      this.x1 = x1;
      this.y1 = y1;
      ctrlx = cx;
      ctrly = cy;
      this.x2 = x2;
      this.y2 = y2;
    }

    /**
     * Returns the <i>x</i> coordinate of the curve&#x2019;s start
     * point.
     */
    public double getX1()
    {
      return x1;
    }

    /**
     * Returns the <i>y</i> coordinate of the curve&#x2019;s start
     * point.
     */
    public double getY1()
    {
      return y1;
    }

    /**
     * Returns the curve&#x2019;s start point.
     */
    public Point2D getP1()
    {
      return new Point2D.Double(x1, y1);
    }

    /**
     * Returns the <i>x</i> coordinate of the curve&#x2019;s control
     * point.
     */
    public double getCtrlX()
    {
      return ctrlx;
    }

    /**
     * Returns the <i>y</i> coordinate of the curve&#x2019;s control
     * point.
     */
    public double getCtrlY()
    {
      return ctrly;
    }

    /**
     * Returns the curve&#x2019;s control point.
     */
    public Point2D getCtrlPt()
    {
      return new Point2D.Double(ctrlx, ctrly);
    }

    /**
     * Returns the <i>x</i> coordinate of the curve&#x2019;s end
     * point.
     */
    public double getX2()
    {
      return x2;
    }

    /**
     * Returns the <i>y</i> coordinate of the curve&#x2019;s end
     * point.
     */
    public double getY2()
    {
      return y2;
    }

    /**
     * Returns the curve&#x2019;s end point.
     */
    public Point2D getP2()
    {
      return new Point2D.Double(x2, y2);
    }

    /**
     * Changes the geometry of the curve.
     *
     * @param x1 the <i>x</i> coordinate of the curve&#x2019;s new
     * start point.
     *
     * @param y1 the <i>y</i> coordinate of the curve&#x2019;s new
     * start point.
     *
     * @param cx the <i>x</i> coordinate of the curve&#x2019;s new
     * control point.
     *
     * @param cy the <i>y</i> coordinate of the curve&#x2019;s new
     * control point.
     *
     * @param x2 the <i>x</i> coordinate of the curve&#x2019;s new
     * end point.
     *
     * @param y2 the <i>y</i> coordinate of the curve&#x2019;s new
     * end point.
     */
    public void setCurve(double x1, double y1, double cx, double cy,
                         double x2, double y2)
    {
      this.x1 = x1;
      this.y1 = y1;
      ctrlx = cx;
      ctrly = cy;
      this.x2 = x2;
      this.y2 = y2;
    }

    /**
     * Determines the smallest rectangle that encloses the
     * curve&#x2019;s start, end and control point. As the
     * illustration below shows, the invisible control point may cause
     * the bounds to be much larger than the area that is actually
     * covered by the curve.
     *
     * <p><img src="doc-files/QuadCurve2D-2.png" width="350" height="180"
     * alt="An illustration of the bounds of a QuadCurve2D" />
     */
    public Rectangle2D getBounds2D()
    {
      double nx1 = Math.min(Math.min(x1, ctrlx), x2);
      double ny1 = Math.min(Math.min(y1, ctrly), y2);
      double nx2 = Math.max(Math.max(x1, ctrlx), x2);
      double ny2 = Math.max(Math.max(y1, ctrly), y2);
      return new Rectangle2D.Double(nx1, ny1, nx2 - nx1, ny2 - ny1);
    }
  }

  /**
   * A two-dimensional curve that is parameterized with a quadratic
   * function and stores coordinate values in single-precision
   * floating-point format.
   *
   * @see QuadCurve2D.Double
   *
   * @author Eric Blake (ebb9@email.byu.edu)
   * @author Sascha Brawer (brawer@dandelis.ch)
   */
  public static class Float extends QuadCurve2D
  {
    /**
     * The <i>x</i> coordinate of the curve&#x2019;s start point.
     */
    public float x1;

    /**
     * The <i>y</i> coordinate of the curve&#x2019;s start point.
     */
    public float y1;

    /**
     * The <i>x</i> coordinate of the curve&#x2019;s control point.
     */
    public float ctrlx;

    /**
     * The <i>y</i> coordinate of the curve&#x2019;s control point.
     */
    public float ctrly;

    /**
     * The <i>x</i> coordinate of the curve&#x2019;s end point.
     */
    public float x2;

    /**
     * The <i>y</i> coordinate of the curve&#x2019;s end point.
     */
    public float y2;

    /**
     * Constructs a new QuadCurve2D that stores its coordinate values
     * in single-precision floating-point format. All points are
     * initially at position (0, 0).
     */
    public Float()
    {
    }

    /**
     * Constructs a new QuadCurve2D that stores its coordinate values
     * in single-precision floating-point format, specifying the
     * initial position of each point.
     *
     * @param x1 the <i>x</i> coordinate of the curve&#x2019;s start
     * point.
     *
     * @param y1 the <i>y</i> coordinate of the curve&#x2019;s start
     * point.
     *
     * @param cx the <i>x</i> coordinate of the curve&#x2019;s control
     * point.
     *
     * @param cy the <i>y</i> coordinate of the curve&#x2019;s control
     * point.
     *
     * @param x2 the <i>x</i> coordinate of the curve&#x2019;s end
     * point.
     *
     * @param y2 the <i>y</i> coordinate of the curve&#x2019;s end
     * point.
     */
    public Float(float x1, float y1, float cx, float cy, float x2, float y2)
    {
      this.x1 = x1;
      this.y1 = y1;
      ctrlx = cx;
      ctrly = cy;
      this.x2 = x2;
      this.y2 = y2;
    }

    /**
     * Returns the <i>x</i> coordinate of the curve&#x2019;s start
     * point.
     */
    public double getX1()
    {
      return x1;
    }

    /**
     * Returns the <i>y</i> coordinate of the curve&#x2019;s start
     * point.
     */
    public double getY1()
    {
      return y1;
    }

    /**
     * Returns the curve&#x2019;s start point.
     */
    public Point2D getP1()
    {
      return new Point2D.Float(x1, y1);
    }

    /**
     * Returns the <i>x</i> coordinate of the curve&#x2019;s control
     * point.
     */
    public double getCtrlX()
    {
      return ctrlx;
    }

    /**
     * Returns the <i>y</i> coordinate of the curve&#x2019;s control
     * point.
     */
    public double getCtrlY()
    {
      return ctrly;
    }

    /**
     * Returns the curve&#x2019;s control point.
     */
    public Point2D getCtrlPt()
    {
      return new Point2D.Float(ctrlx, ctrly);
    }

    /**
     * Returns the <i>x</i> coordinate of the curve&#x2019;s end
     * point.
     */
    public double getX2()
    {
      return x2;
    }

    /**
     * Returns the <i>y</i> coordinate of the curve&#x2019;s end
     * point.
     */
    public double getY2()
    {
      return y2;
    }

    /**
     * Returns the curve&#x2019;s end point.
     */
    public Point2D getP2()
    {
      return new Point2D.Float(x2, y2);
    }

    /**
     * Changes the geometry of the curve, specifying coordinate values
     * as double-precision floating-point numbers.
     *
     * @param x1 the <i>x</i> coordinate of the curve&#x2019;s new
     * start point.
     *
     * @param y1 the <i>y</i> coordinate of the curve&#x2019;s new
     * start point.
     *
     * @param cx the <i>x</i> coordinate of the curve&#x2019;s new
     * control point.
     *
     * @param cy the <i>y</i> coordinate of the curve&#x2019;s new
     * control point.
     *
     * @param x2 the <i>x</i> coordinate of the curve&#x2019;s new
     * end point.
     *
     * @param y2 the <i>y</i> coordinate of the curve&#x2019;s new
     * end point.
     */
    public void setCurve(double x1, double y1, double cx, double cy,
                         double x2, double y2)
    {
      this.x1 = (float) x1;
      this.y1 = (float) y1;
      ctrlx = (float) cx;
      ctrly = (float) cy;
      this.x2 = (float) x2;
      this.y2 = (float) y2;
    }

    /**
     * Changes the geometry of the curve, specifying coordinate values
     * as single-precision floating-point numbers.
     *
     * @param x1 the <i>x</i> coordinate of the curve&#x2019;s new
     * start point.
     *
     * @param y1 the <i>y</i> coordinate of the curve&#x2019;s new
     * start point.
     *
     * @param cx the <i>x</i> coordinate of the curve&#x2019;s new
     * control point.
     *
     * @param cy the <i>y</i> coordinate of the curve&#x2019;s new
     * control point.
     *
     * @param x2 the <i>x</i> coordinate of the curve&#x2019;s new
     * end point.
     *
     * @param y2 the <i>y</i> coordinate of the curve&#x2019;s new
     * end point.
     */
    public void setCurve(float x1, float y1, float cx, float cy, float x2,
                         float y2)
    {
      this.x1 = x1;
      this.y1 = y1;
      ctrlx = cx;
      ctrly = cy;
      this.x2 = x2;
      this.y2 = y2;
    }

    /**
     * Determines the smallest rectangle that encloses the
     * curve&#x2019;s start, end and control point. As the
     * illustration below shows, the invisible control point may cause
     * the bounds to be much larger than the area that is actually
     * covered by the curve.
     *
     * <p><img src="doc-files/QuadCurve2D-2.png" width="350" height="180"
     * alt="An illustration of the bounds of a QuadCurve2D" />
     */
    public Rectangle2D getBounds2D()
    {
      float nx1 = Math.min(Math.min(x1, ctrlx), x2);
      float ny1 = Math.min(Math.min(y1, ctrly), y2);
      float nx2 = Math.max(Math.max(x1, ctrlx), x2);
      float ny2 = Math.max(Math.max(y1, ctrly), y2);
      return new Rectangle2D.Float(nx1, ny1, nx2 - nx1, ny2 - ny1);
    }
  }
}
