/* Area.java -- represents a shape built by constructive area geometry
   Copyright (C) 2002, 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.Vector;


/**
 * The Area class represents any area for the purpose of
 * Constructive Area Geometry (CAG) manipulations. CAG manipulations
 * work as an area-wise form of boolean logic, where the basic operations are:
 * <P><li>Add (in boolean algebra: A <B>or</B> B)<BR>
 * <li>Subtract (in boolean algebra: A <B>and</B> (<B>not</B> B) )<BR>
 * <li>Intersect (in boolean algebra: A <B>and</B> B)<BR>
 * <li>Exclusive Or <BR>
 * <img src="doc-files/Area-1.png" width="342" height="302"
 * alt="Illustration of CAG operations" /><BR>
 * Above is an illustration of the CAG operations on two ring shapes.<P>
 *
 * The contains and intersects() methods are also more accurate than the
 * specification of #Shape requires.<P>
 *
 * Please note that constructing an Area can be slow
 * (Self-intersection resolving is proportional to the square of
 * the number of segments).<P>
 * @see #add(Area)
 * @see #subtract(Area)
 * @see #intersect(Area)
 * @see #exclusiveOr(Area)
 *
 * @author Sven de Marothy (sven@physto.se)
 *
 * @since 1.2
 * @status Works, but could be faster and more reliable.
 */
public class Area implements Shape, Cloneable
{
  /**
   * General numerical precision
   */
  private static final double EPSILON = 1E-11;

  /**
   * recursive subdivision epsilon - (see getRecursionDepth)
   */
  private static final double RS_EPSILON = 1E-13;

  /**
   * Snap distance - points within this distance are considered equal
   */
  private static final double PE_EPSILON = 1E-11;

  /**
   * Segment vectors containing solid areas and holes
   * This is package-private to avoid an accessor method.
   */
  Vector solids;

  /**
   * Segment vectors containing solid areas and holes
   * This is package-private to avoid an accessor method.
   */
  Vector holes;

  /**
   * Vector (temporary) storing curve-curve intersections
   */
  private Vector cc_intersections;

  /**
   * Winding rule WIND_NON_ZERO used, after construction,
   * this is irrelevant.
   */
  private int windingRule;

  /**
   * Constructs an empty Area
   */
  public Area()
  {
    solids = new Vector();
    holes = new Vector();
  }

  /**
   * Constructs an Area from any given Shape. <P>
   *
   * If the Shape is self-intersecting, the created Area will consist
   * of non-self-intersecting subpaths, and any inner paths which
   * are found redundant in accordance with the Shape's winding rule
   * will not be included.
   * 
   * @param s  the shape (<code>null</code> not permitted).
   * 
   * @throws NullPointerException if <code>s</code> is <code>null</code>.
   */
  public Area(Shape s)
  {
    this();

    Vector p = makeSegment(s);

    // empty path
    if (p == null)
      return;

    // delete empty paths
    for (int i = 0; i < p.size(); i++)
      if (((Segment) p.elementAt(i)).getSignedArea() == 0.0)
	p.remove(i--);

    /*
     * Resolve self intersecting paths into non-intersecting
     * solids and holes.
     * Algorithm is as follows:
     * 1: Create nodes at all self intersections
     * 2: Put all segments into a list
     * 3: Grab a segment, follow it, change direction at each node,
     *    removing segments from the list in the process
     * 4: Repeat (3) until no segments remain in the list
     * 5: Remove redundant paths and sort into solids and holes
     */
    Vector paths = new Vector();
    Segment v;

    for (int i = 0; i < p.size(); i++)
      {
	Segment path = (Segment) p.elementAt(i);
	createNodesSelf(path);
      }

    if (p.size() > 1)
      {
	for (int i = 0; i < p.size() - 1; i++)
	  for (int j = i + 1; j < p.size(); j++)
	    {
	      Segment path1 = (Segment) p.elementAt(i);
	      Segment path2 = (Segment) p.elementAt(j);
	      createNodes(path1, path2);
	    }
      }

    // we have intersecting points.
    Vector segments = new Vector();

    for (int i = 0; i < p.size(); i++)
      {
	Segment path = v = (Segment) p.elementAt(i);
	do
	  {
	    segments.add(v);
	    v = v.next;
	  }
	while (v != path);
      }

    paths = weilerAtherton(segments);
    deleteRedundantPaths(paths);
  }

  /**
   * Performs an add (union) operation on this area with another Area.<BR>
   * @param area - the area to be unioned with this one
   */
  public void add(Area area)
  {
    if (equals(area))
      return;
    if (area.isEmpty())
      return;

    Area B = (Area) area.clone();

    Vector pathA = new Vector();
    Vector pathB = new Vector();
    pathA.addAll(solids);
    pathA.addAll(holes);
    pathB.addAll(B.solids);
    pathB.addAll(B.holes);

    int nNodes = 0;

    for (int i = 0; i < pathA.size(); i++)
      {
	Segment a = (Segment) pathA.elementAt(i);
	for (int j = 0; j < pathB.size(); j++)
	  {
	    Segment b = (Segment) pathB.elementAt(j);
	    nNodes += createNodes(a, b);
	  }
      }

    Vector paths = new Vector();
    Segment v;

    // we have intersecting points.
    Vector segments = new Vector();

    // In a union operation, we keep all
    // segments of A oustide B and all B outside A
    for (int i = 0; i < pathA.size(); i++)
      {
	v = (Segment) pathA.elementAt(i);
	Segment path = v;
	do
	  {
	    if (v.isSegmentOutside(area))
	      segments.add(v);
	    v = v.next;
	  }
	while (v != path);
      }

    for (int i = 0; i < pathB.size(); i++)
      {
	v = (Segment) pathB.elementAt(i);
	Segment path = v;
	do
	  {
	    if (v.isSegmentOutside(this))
	      segments.add(v);
	    v = v.next;
	  }
	while (v != path);
      }

    paths = weilerAtherton(segments);
    deleteRedundantPaths(paths);
  }

  /**
   * Performs a subtraction operation on this Area.<BR>
   * @param area the area to be subtracted from this area.
   * @throws NullPointerException if <code>area</code> is <code>null</code>.
   */
  public void subtract(Area area)
  {
    if (isEmpty() || area.isEmpty())
      return;

    if (equals(area))
      {
	reset();
	return;
      }

    Vector pathA = new Vector();
    Area B = (Area) area.clone();
    pathA.addAll(solids);
    pathA.addAll(holes);

    // reverse the directions of B paths.
    setDirection(B.holes, true);
    setDirection(B.solids, false);

    Vector pathB = new Vector();
    pathB.addAll(B.solids);
    pathB.addAll(B.holes);

    int nNodes = 0;

    // create nodes
    for (int i = 0; i < pathA.size(); i++)
      {
	Segment a = (Segment) pathA.elementAt(i);
	for (int j = 0; j < pathB.size(); j++)
	  {
	    Segment b = (Segment) pathB.elementAt(j);
	    nNodes += createNodes(a, b);
	  }
      }

    Vector paths = new Vector();

    // we have intersecting points.
    Vector segments = new Vector();

    // In a subtraction operation, we keep all
    // segments of A oustide B and all B within A
    // We outsideness-test only one segment in each path
    // and the segments before and after any node
    for (int i = 0; i < pathA.size(); i++)
      {
	Segment v = (Segment) pathA.elementAt(i);
	Segment path = v;
	if (v.isSegmentOutside(area) && v.node == null)
	  segments.add(v);
	boolean node = false;
	do
	  {
	    if ((v.node != null || node))
	      {
		node = (v.node != null);
		if (v.isSegmentOutside(area))
		  segments.add(v);
	      }
	    v = v.next;
	  }
	while (v != path);
      }

    for (int i = 0; i < pathB.size(); i++)
      {
	Segment v = (Segment) pathB.elementAt(i);
	Segment path = v;
	if (! v.isSegmentOutside(this) && v.node == null)
	  segments.add(v);
	v = v.next;
	boolean node = false;
	do
	  {
	    if ((v.node != null || node))
	      {
		node = (v.node != null);
		if (! v.isSegmentOutside(this))
		  segments.add(v);
	      }
	    v = v.next;
	  }
	while (v != path);
      }

    paths = weilerAtherton(segments);
    deleteRedundantPaths(paths);
  }

  /**
   * Performs an intersection operation on this Area.<BR>
   * @param area - the area to be intersected with this area.
   * @throws NullPointerException if <code>area</code> is <code>null</code>.
   */
  public void intersect(Area area)
  {
    if (isEmpty() || area.isEmpty())
      {
	reset();
	return;
      }
    if (equals(area))
      return;

    Vector pathA = new Vector();
    Area B = (Area) area.clone();
    pathA.addAll(solids);
    pathA.addAll(holes);

    Vector pathB = new Vector();
    pathB.addAll(B.solids);
    pathB.addAll(B.holes);

    int nNodes = 0;

    // create nodes
    for (int i = 0; i < pathA.size(); i++)
      {
	Segment a = (Segment) pathA.elementAt(i);
	for (int j = 0; j < pathB.size(); j++)
	  {
	    Segment b = (Segment) pathB.elementAt(j);
	    nNodes += createNodes(a, b);
	  }
      }

    Vector paths = new Vector();

    // we have intersecting points.
    Vector segments = new Vector();

    // In an intersection operation, we keep all
    // segments of A within B and all B within A
    // (The rest must be redundant)
    // We outsideness-test only one segment in each path
    // and the segments before and after any node
    for (int i = 0; i < pathA.size(); i++)
      {
	Segment v = (Segment) pathA.elementAt(i);
	Segment path = v;
	if (! v.isSegmentOutside(area) && v.node == null)
	  segments.add(v);
	boolean node = false;
	do
	  {
	    if ((v.node != null || node))
	      {
		node = (v.node != null);
		if (! v.isSegmentOutside(area))
		  segments.add(v);
	      }
	    v = v.next;
	  }
	while (v != path);
      }

    for (int i = 0; i < pathB.size(); i++)
      {
	Segment v = (Segment) pathB.elementAt(i);
	Segment path = v;
	if (! v.isSegmentOutside(this) && v.node == null)
	  segments.add(v);
	v = v.next;
	boolean node = false;
	do
	  {
	    if ((v.node != null || node))
	      {
		node = (v.node != null);
		if (! v.isSegmentOutside(this))
		  segments.add(v);
	      }
	    v = v.next;
	  }
	while (v != path);
      }

    paths = weilerAtherton(segments);
    deleteRedundantPaths(paths);
  }

  /**
   * Performs an exclusive-or operation on this Area.<BR>
   * @param area - the area to be XORed with this area.
   * @throws NullPointerException if <code>area</code> is <code>null</code>.
   */
  public void exclusiveOr(Area area)
  {
    if (area.isEmpty())
      return;

    if (isEmpty())
      {
	Area B = (Area) area.clone();
	solids = B.solids;
	holes = B.holes;
	return;
      }
    if (equals(area))
      {
	reset();
	return;
      }

    Vector pathA = new Vector();

    Area B = (Area) area.clone();
    Vector pathB = new Vector();
    pathA.addAll(solids);
    pathA.addAll(holes);

    // reverse the directions of B paths.
    setDirection(B.holes, true);
    setDirection(B.solids, false);
    pathB.addAll(B.solids);
    pathB.addAll(B.holes);

    int nNodes = 0;

    for (int i = 0; i < pathA.size(); i++)
      {
	Segment a = (Segment) pathA.elementAt(i);
	for (int j = 0; j < pathB.size(); j++)
	  {
	    Segment b = (Segment) pathB.elementAt(j);
	    nNodes += createNodes(a, b);
	  }
      }

    Vector paths = new Vector();
    Segment v;

    // we have intersecting points.
    Vector segments = new Vector();

    // In an XOR operation, we operate on all segments
    for (int i = 0; i < pathA.size(); i++)
      {
	v = (Segment) pathA.elementAt(i);
	Segment path = v;
	do
	  {
	    segments.add(v);
	    v = v.next;
	  }
	while (v != path);
      }

    for (int i = 0; i < pathB.size(); i++)
      {
	v = (Segment) pathB.elementAt(i);
	Segment path = v;
	do
	  {
	    segments.add(v);
	    v = v.next;
	  }
	while (v != path);
      }

    paths = weilerAtherton(segments);
    deleteRedundantPaths(paths);
  }

  /**
   * Clears the Area object, creating an empty area.
   */
  public void reset()
  {
    solids = new Vector();
    holes = new Vector();
  }

  /**
   * Returns whether this area encloses any area.
   * @return true if the object encloses any area.
   */
  public boolean isEmpty()
  {
    if (solids.size() == 0)
      return true;

    double totalArea = 0;
    for (int i = 0; i < solids.size(); i++)
      totalArea += Math.abs(((Segment) solids.elementAt(i)).getSignedArea());
    for (int i = 0; i < holes.size(); i++)
      totalArea -= Math.abs(((Segment) holes.elementAt(i)).getSignedArea());
    if (totalArea <= EPSILON)
      return true;

    return false;
  }

  /**
   * Determines whether the Area consists entirely of line segments
   * @return true if the Area lines-only, false otherwise
   */
  public boolean isPolygonal()
  {
    for (int i = 0; i < holes.size(); i++)
      if (! ((Segment) holes.elementAt(i)).isPolygonal())
	return false;
    for (int i = 0; i < solids.size(); i++)
      if (! ((Segment) solids.elementAt(i)).isPolygonal())
	return false;
    return true;
  }

  /**
   * Determines if the Area is rectangular.<P>
   *
   * This is strictly qualified. An area is considered rectangular if:<BR>
   * <li>It consists of a single polygonal path.<BR>
   * <li>It is oriented parallel/perpendicular to the xy axis<BR>
   * <li>It must be exactly rectangular, i.e. small errors induced by
   * transformations may cause a false result, although the area is
   * visibly rectangular.<P>
   * @return true if the above criteria are met, false otherwise
   */
  public boolean isRectangular()
  {
    if (isEmpty())
      return true;

    if (holes.size() != 0 || solids.size() != 1)
      return false;

    Segment path = (Segment) solids.elementAt(0);
    if (! path.isPolygonal())
      return false;

    int nCorners = 0;
    Segment s = path;
    do
      {
	Segment s2 = s.next;
	double d1 = (s.P2.getX() - s.P1.getX())*(s2.P2.getX() - s2.P1.getX())/
	    ((s.P1.distance(s.P2)) * (s2.P1.distance(s2.P2)));
	double d2 = (s.P2.getY() - s.P1.getY())*(s2.P2.getY() - s2.P1.getY())/ 
	    ((s.P1.distance(s.P2)) * (s2.P1.distance(s2.P2)));
	double dotproduct = d1 + d2;

	// For some reason, only rectangles on the XY axis count.
	if (d1 != 0 && d2 != 0)
	  return false;

	if (Math.abs(dotproduct) == 0) // 90 degree angle
	  nCorners++;
	else if ((Math.abs(1.0 - dotproduct) > 0)) // 0 degree angle?
	  return false; // if not, return false

	s = s.next;
      }
    while (s != path);

    return nCorners == 4;
  }

  /**
   * Returns whether the Area consists of more than one simple
   * (non self-intersecting) subpath.
   *
   * @return true if the Area consists of none or one simple subpath,
   * false otherwise.
   */
  public boolean isSingular()
  {
    return (holes.size() == 0 && solids.size() <= 1);
  }

  /**
   * Returns the bounding box of the Area.<P> Unlike the CubicCurve2D and
   * QuadraticCurve2D classes, this method will return the tightest possible
   * bounding box, evaluating the extreme points of each curved segment.<P>
   * @return the bounding box
   */
  public Rectangle2D getBounds2D()
  {
    if (solids.size() == 0)
      return new Rectangle2D.Double(0.0, 0.0, 0.0, 0.0);

    double xmin;
    double xmax;
    double ymin;
    double ymax;
    xmin = xmax = ((Segment) solids.elementAt(0)).P1.getX();
    ymin = ymax = ((Segment) solids.elementAt(0)).P1.getY();

    for (int path = 0; path < solids.size(); path++)
      {
	Rectangle2D r = ((Segment) solids.elementAt(path)).getPathBounds();
	xmin = Math.min(r.getMinX(), xmin);
	ymin = Math.min(r.getMinY(), ymin);
	xmax = Math.max(r.getMaxX(), xmax);
	ymax = Math.max(r.getMaxY(), ymax);
      }

    return (new Rectangle2D.Double(xmin, ymin, (xmax - xmin), (ymax - ymin)));
  }

  /**
   * Returns the bounds of this object in Rectangle format.
   * Please note that this may lead to loss of precision.
   * 
   * @return The bounds.
   * @see #getBounds2D()
   */
  public Rectangle getBounds()
  {
    return getBounds2D().getBounds();
  }

  /**
   * Create a new area of the same run-time type with the same contents as
   * this one.
   *
   * @return the clone
   */
  public Object clone()
  {
    try
      {
	Area clone = new Area();
	for (int i = 0; i < solids.size(); i++)
	  clone.solids.add(((Segment) solids.elementAt(i)).cloneSegmentList());
	for (int i = 0; i < holes.size(); i++)
	  clone.holes.add(((Segment) holes.elementAt(i)).cloneSegmentList());
	return clone;
      }
    catch (CloneNotSupportedException e)
      {
	throw (Error) new InternalError().initCause(e); // Impossible
      }
  }

  /**
   * Compares two Areas.
   * 
   * @param area  the area to compare against this area (<code>null</code>
   *              permitted).
   * @return <code>true</code> if the areas are equal, and <code>false</code>
   *         otherwise.
   */
  public boolean equals(Area area)
  {
    if (area == null)
      return false;

    if (! getBounds2D().equals(area.getBounds2D()))
      return false;

    if (solids.size() != area.solids.size()
        || holes.size() != area.holes.size())
      return false;

    Vector pathA = new Vector();
    pathA.addAll(solids);
    pathA.addAll(holes);
    Vector pathB = new Vector();
    pathB.addAll(area.solids);
    pathB.addAll(area.holes);

    int nPaths = pathA.size();
    boolean[][] match = new boolean[2][nPaths];

    for (int i = 0; i < nPaths; i++)
      {
	for (int j = 0; j < nPaths; j++)
	  {
	    Segment p1 = (Segment) pathA.elementAt(i);
	    Segment p2 = (Segment) pathB.elementAt(j);
	    if (! match[0][i] && ! match[1][j])
	      if (p1.pathEquals(p2))
		match[0][i] = match[1][j] = true;
	  }
      }

    boolean result = true;
    for (int i = 0; i < nPaths; i++)
      result = result && match[0][i] && match[1][i];
    return result;
  }

  /**
   * Transforms this area by the AffineTransform at.
   * 
   * @param at  the transform.
   */
  public void transform(AffineTransform at)
  {
    for (int i = 0; i < solids.size(); i++)
      ((Segment) solids.elementAt(i)).transformSegmentList(at);
    for (int i = 0; i < holes.size(); i++)
      ((Segment) holes.elementAt(i)).transformSegmentList(at);

    // Note that the orientation is not invariant under inversion
    if ((at.getType() & AffineTransform.TYPE_FLIP) != 0)
      {
	setDirection(holes, false);
	setDirection(solids, true);
      }
  }

  /**
   * Returns a new Area equal to this one, transformed
   * by the AffineTransform at.
   * @param at  the transform.
   * @return the transformed area
   * @throws NullPointerException if <code>at</code> is <code>null</code>.
   */
  public Area createTransformedArea(AffineTransform at)
  {
    Area a = (Area) clone();
    a.transform(at);
    return a;
  }

  /**
   * Determines if the point (x,y) is contained within this Area.
   *
   * @param x the x-coordinate of the point.
   * @param y the y-coordinate of the point.
   * @return true if the point is contained, false otherwise.
   */
  public boolean contains(double x, double y)
  {
    int n = 0;
    for (int i = 0; i < solids.size(); i++)
      if (((Segment) solids.elementAt(i)).contains(x, y))
	n++;

    for (int i = 0; i < holes.size(); i++)
      if (((Segment) holes.elementAt(i)).contains(x, y))
	n--;

    return (n != 0);
  }

  /**
   * Determines if the Point2D p is contained within this Area.
   *
   * @param p the point.
   * @return <code>true</code> if the point is contained, <code>false</code> 
   *         otherwise.
   * @throws NullPointerException if <code>p</code> is <code>null</code>.
   */
  public boolean contains(Point2D p)
  {
    return contains(p.getX(), p.getY());
  }

  /**
   * Determines if the rectangle specified by (x,y) as the upper-left
   * and with width w and height h is completely contained within this Area,
   * returns false otherwise.<P>
   *
   * This method should always produce the correct results, unlike for other
   * classes in geom.
   * 
   * @param x the x-coordinate of the rectangle.
   * @param y the y-coordinate of the rectangle.
   * @param w the width of the the rectangle.
   * @param h the height of the rectangle.
   * @return <code>true</code> if the rectangle is considered contained
   */
  public boolean contains(double x, double y, double w, double h)
  {
    LineSegment[] l = new LineSegment[4];
    l[0] = new LineSegment(x, y, x + w, y);
    l[1] = new LineSegment(x, y + h, x + w, y + h);
    l[2] = new LineSegment(x, y, x, y + h);
    l[3] = new LineSegment(x + w, y, x + w, y + h);

    // Since every segment in the area must a contour
    // between inside/outside segments, ANY intersection
    // will mean the rectangle is not entirely contained.
    for (int i = 0; i < 4; i++)
      {
	for (int path = 0; path < solids.size(); path++)
	  {
	    Segment v;
	    Segment start;
	    start = v = (Segment) solids.elementAt(path);
	    do
	      {
		if (l[i].hasIntersections(v))
		  return false;
		v = v.next;
	      }
	    while (v != start);
	  }
	for (int path = 0; path < holes.size(); path++)
	  {
	    Segment v;
	    Segment start;
	    start = v = (Segment) holes.elementAt(path);
	    do
	      {
		if (l[i].hasIntersections(v))
		  return false;
		v = v.next;
	      }
	    while (v != start);
	  }
      }

    // Is any point inside?
    if (! contains(x, y))
      return false;

    // Final hoop: Is the rectangle non-intersecting and inside, 
    // but encloses a hole?
    Rectangle2D r = new Rectangle2D.Double(x, y, w, h);
    for (int path = 0; path < holes.size(); path++)
      if (! ((Segment) holes.elementAt(path)).isSegmentOutside(r))
        return false;

    return true;
  }

  /**
   * Determines if the Rectangle2D specified by r is completely contained
   * within this Area, returns false otherwise.<P>
   *
   * This method should always produce the correct results, unlike for other
   * classes in geom.
   * 
   * @param r the rectangle.
   * @return <code>true</code> if the rectangle is considered contained
   * 
   * @throws NullPointerException if <code>r</code> is <code>null</code>.
   */
  public boolean contains(Rectangle2D r)
  {
    return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
  }

  /**
   * Determines if the rectangle specified by (x,y) as the upper-left
   * and with width w and height h intersects any part of this Area.
   * 
   * @param x  the x-coordinate for the rectangle.
   * @param y  the y-coordinate for the rectangle.
   * @param w  the width of the rectangle.
   * @param h  the height of the rectangle.
   * @return <code>true</code> if the rectangle intersects the area, 
   *         <code>false</code> otherwise.
   */
  public boolean intersects(double x, double y, double w, double h)
  {
    if (solids.size() == 0)
      return false;

    LineSegment[] l = new LineSegment[4];
    l[0] = new LineSegment(x, y, x + w, y);
    l[1] = new LineSegment(x, y + h, x + w, y + h);
    l[2] = new LineSegment(x, y, x, y + h);
    l[3] = new LineSegment(x + w, y, x + w, y + h);

    // Return true on any intersection
    for (int i = 0; i < 4; i++)
      {
	for (int path = 0; path < solids.size(); path++)
	  {
	    Segment v;
	    Segment start;
	    start = v = (Segment) solids.elementAt(path);
	    do
	      {
		if (l[i].hasIntersections(v))
		  return true;
		v = v.next;
	      }
	    while (v != start);
	  }
	for (int path = 0; path < holes.size(); path++)
	  {
	    Segment v;
	    Segment start;
	    start = v = (Segment) holes.elementAt(path);
	    do
	      {
		if (l[i].hasIntersections(v))
		  return true;
		v = v.next;
	      }
	    while (v != start);
	  }
      }

    // Non-intersecting, Is any point inside?
    if (contains(x + w * 0.5, y + h * 0.5))
      return true;

    // What if the rectangle encloses the whole shape?
    Point2D p = ((Segment) solids.elementAt(0)).getMidPoint();
    if ((new Rectangle2D.Double(x, y, w, h)).contains(p))
      return true;
    return false;
  }

  /**
   * Determines if the Rectangle2D specified by r intersects any
   * part of this Area.
   * @param r  the rectangle to test intersection with (<code>null</code>
   *           not permitted).
   * @return <code>true</code> if the rectangle intersects the area, 
   *         <code>false</code> otherwise.
   * @throws NullPointerException if <code>r</code> is <code>null</code>.
   */
  public boolean intersects(Rectangle2D r)
  {
    return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
  }

  /**
   * Returns a PathIterator object defining the contour of this Area,
   * transformed by at.
   * 
   * @param at  the transform.
   * @return A path iterator.
   */
  public PathIterator getPathIterator(AffineTransform at)
  {
    return (new AreaIterator(at));
  }

  /**
   * Returns a flattened PathIterator object defining the contour of this
   * Area, transformed by at and with a defined flatness.
   * 
   * @param at  the transform.
   * @param flatness the flatness.
   * @return A path iterator.
   */
  public PathIterator getPathIterator(AffineTransform at, double flatness)
  {
    return new FlatteningPathIterator(getPathIterator(at), flatness);
  }

  //---------------------------------------------------------------------
  // Non-public methods and classes 

  /**
   * Private pathiterator object.
   */
  private class AreaIterator implements PathIterator
  {
    private Vector segments;
    private int index;
    private AffineTransform at;

    // Simple compound type for segments
    class IteratorSegment
    {
      int type;
      double[] coords;

      IteratorSegment()
      {
	coords = new double[6];
      }
    }

    /**
     * The contructor here does most of the work,
     * creates a vector of IteratorSegments, which can
     * readily be returned
     */
    public AreaIterator(AffineTransform at)
    {
      this.at = at;
      index = 0;
      segments = new Vector();
      Vector allpaths = new Vector();
      allpaths.addAll(solids);
      allpaths.addAll(holes);

      for (int i = 0; i < allpaths.size(); i++)
        {
	  Segment v = (Segment) allpaths.elementAt(i);
	  Segment start = v;

	  IteratorSegment is = new IteratorSegment();
	  is.type = SEG_MOVETO;
	  is.coords[0] = start.P1.getX();
	  is.coords[1] = start.P1.getY();
	  segments.add(is);

	  do
	    {
	      is = new IteratorSegment();
	      is.type = v.pathIteratorFormat(is.coords);
	      segments.add(is);
	      v = v.next;
	    }
	  while (v != start);

	  is = new IteratorSegment();
	  is.type = SEG_CLOSE;
	  segments.add(is);
        }
    }

    public int currentSegment(double[] coords)
    {
      IteratorSegment s = (IteratorSegment) segments.elementAt(index);
      if (at != null)
	at.transform(s.coords, 0, coords, 0, 3);
      else
	for (int i = 0; i < 6; i++)
	  coords[i] = s.coords[i];
      return (s.type);
    }

    public int currentSegment(float[] coords)
    {
      IteratorSegment s = (IteratorSegment) segments.elementAt(index);
      double[] d = new double[6];
      if (at != null)
        {
	  at.transform(s.coords, 0, d, 0, 3);
	  for (int i = 0; i < 6; i++)
	    coords[i] = (float) d[i];
        }
      else
	for (int i = 0; i < 6; i++)
	  coords[i] = (float) s.coords[i];
      return (s.type);
    }

    // Note that the winding rule should not matter here,
    // EVEN_ODD is chosen because it renders faster.
    public int getWindingRule()
    {
      return (PathIterator.WIND_EVEN_ODD);
    }

    public boolean isDone()
    {
      return (index >= segments.size());
    }

    public void next()
    {
      index++;
    }
  }

  /**
   * Performs the fundamental task of the Weiler-Atherton algorithm,
   * traverse a list of segments, for each segment:
   * Follow it, removing segments from the list and switching paths
   * at each node. Do so until the starting segment is reached.
   *
   * Returns a Vector of the resulting paths.
   */
  private Vector weilerAtherton(Vector segments)
  {
    Vector paths = new Vector();
    while (segments.size() > 0)
      {
	// Iterate over the path
	Segment start = (Segment) segments.elementAt(0);
	Segment s = start;
	do
	  {
	    segments.remove(s);
	    if (s.node != null)
	      { // switch over
		s.next = s.node;
		s.node = null;
	      }
	    s = s.next; // continue
	  }
	while (s != start);

	paths.add(start);
      }
    return paths;
  }

  /**
   * A small wrapper class to store intersection points
   */
  private class Intersection
  {
    Point2D p; // the 2D point of intersection
    double ta; // the parametric value on a
    double tb; // the parametric value on b
    Segment seg; // segment placeholder for node setting

    public Intersection(Point2D p, double ta, double tb)
    {
      this.p = p;
      this.ta = ta;
      this.tb = tb;
    }
  }

  /**
   * Returns the recursion depth necessary to approximate the
   * curve by line segments within the error RS_EPSILON.
   *
   * This is done with Wang's formula:
   * L0 = max{0<=i<=N-2}(|xi - 2xi+1 + xi+2|,|yi - 2yi+1 + yi+2|)
   * r0 = log4(sqrt(2)*N*(N-1)*L0/8e)
   * Where e is the maximum distance error (RS_EPSILON)
   */
  private int getRecursionDepth(CubicSegment curve)
  {
    double x0 = curve.P1.getX();
    double y0 = curve.P1.getY();

    double x1 = curve.cp1.getX();
    double y1 = curve.cp1.getY();

    double x2 = curve.cp2.getX();
    double y2 = curve.cp2.getY();

    double x3 = curve.P2.getX();
    double y3 = curve.P2.getY();

    double L0 = Math.max(Math.max(Math.abs(x0 - 2 * x1 + x2),
                                  Math.abs(x1 - 2 * x2 + x3)),
                         Math.max(Math.abs(y0 - 2 * y1 + y2),
                                  Math.abs(y1 - 2 * y2 + y3)));

    double f = Math.sqrt(2) * 6.0 * L0 / (8.0 * RS_EPSILON);

    int r0 = (int) Math.ceil(Math.log(f) / Math.log(4.0));
    return (r0);
  }

  /**
   * Performs recursive subdivision:
   * @param c1 - curve 1
   * @param c2 - curve 2
   * @param depth1 - recursion depth of curve 1
   * @param depth2 - recursion depth of curve 2
   * @param t1 - global parametric value of the first curve's starting point
   * @param t2 - global parametric value of the second curve's starting point
   * @param w1 - global parametric length of curve 1
   * @param w2 - global parametric length of curve 2
   *
   * The final four parameters are for keeping track of the parametric
   * value of the curve. For a full curve t = 0, w = 1, w is halved with
   * each subdivision.
   */
  private void recursiveSubdivide(CubicCurve2D c1, CubicCurve2D c2,
                                  int depth1, int depth2, double t1,
                                  double t2, double w1, double w2)
  {
    boolean flat1 = depth1 <= 0;
    boolean flat2 = depth2 <= 0;

    if (flat1 && flat2)
      {
	double xlk = c1.getP2().getX() - c1.getP1().getX();
	double ylk = c1.getP2().getY() - c1.getP1().getY();

	double xnm = c2.getP2().getX() - c2.getP1().getX();
	double ynm = c2.getP2().getY() - c2.getP1().getY();

	double xmk = c2.getP1().getX() - c1.getP1().getX();
	double ymk = c2.getP1().getY() - c1.getP1().getY();
	double det = xnm * ylk - ynm * xlk;

	if (det + 1.0 == 1.0)
	  return;

	double detinv = 1.0 / det;
	double s = (xnm * ymk - ynm * xmk) * detinv;
	double t = (xlk * ymk - ylk * xmk) * detinv;
	if ((s < 0.0) || (s > 1.0) || (t < 0.0) || (t > 1.0))
	  return;

	double[] temp = new double[2];
	temp[0] = t1 + s * w1;
	temp[1] = t2 + t * w1;
	cc_intersections.add(temp);
	return;
      }

    CubicCurve2D.Double c11 = new CubicCurve2D.Double();
    CubicCurve2D.Double c12 = new CubicCurve2D.Double();
    CubicCurve2D.Double c21 = new CubicCurve2D.Double();
    CubicCurve2D.Double c22 = new CubicCurve2D.Double();

    if (! flat1 && ! flat2)
      {
	depth1--;
	depth2--;
	w1 = w1 * 0.5;
	w2 = w2 * 0.5;
	c1.subdivide(c11, c12);
	c2.subdivide(c21, c22);
	if (c11.getBounds2D().intersects(c21.getBounds2D()))
	  recursiveSubdivide(c11, c21, depth1, depth2, t1, t2, w1, w2);
	if (c11.getBounds2D().intersects(c22.getBounds2D()))
	  recursiveSubdivide(c11, c22, depth1, depth2, t1, t2 + w2, w1, w2);
	if (c12.getBounds2D().intersects(c21.getBounds2D()))
	  recursiveSubdivide(c12, c21, depth1, depth2, t1 + w1, t2, w1, w2);
	if (c12.getBounds2D().intersects(c22.getBounds2D()))
	  recursiveSubdivide(c12, c22, depth1, depth2, t1 + w1, t2 + w2, w1, w2);
	return;
      }

    if (! flat1)
      {
	depth1--;
	c1.subdivide(c11, c12);
	w1 = w1 * 0.5;
	if (c11.getBounds2D().intersects(c2.getBounds2D()))
	  recursiveSubdivide(c11, c2, depth1, depth2, t1, t2, w1, w2);
	if (c12.getBounds2D().intersects(c2.getBounds2D()))
	  recursiveSubdivide(c12, c2, depth1, depth2, t1 + w1, t2, w1, w2);
	return;
      }

    depth2--;
    c2.subdivide(c21, c22);
    w2 = w2 * 0.5;
    if (c1.getBounds2D().intersects(c21.getBounds2D()))
      recursiveSubdivide(c1, c21, depth1, depth2, t1, t2, w1, w2);
    if (c1.getBounds2D().intersects(c22.getBounds2D()))
      recursiveSubdivide(c1, c22, depth1, depth2, t1, t2 + w2, w1, w2);
  }

  /**
   * Returns a set of interesections between two Cubic segments
   * Or null if no intersections were found.
   *
   * The method used to find the intersection is recursive midpoint
   * subdivision. Outline description:
   *
   * 1) Check if the bounding boxes of the curves intersect,
   * 2) If so, divide the curves in the middle and test the bounding
   * boxes again,
   * 3) Repeat until a maximum recursion depth has been reached, where
   * the intersecting curves can be approximated by line segments.
   *
   * This is a reasonably accurate method, although the recursion depth
   * is typically around 20, the bounding-box tests allow for significant
   * pruning of the subdivision tree.
   * 
   * This is package-private to avoid an accessor method.
   */
  Intersection[] cubicCubicIntersect(CubicSegment curve1, CubicSegment curve2)
  {
    Rectangle2D r1 = curve1.getBounds();
    Rectangle2D r2 = curve2.getBounds();

    if (! r1.intersects(r2))
      return null;

    cc_intersections = new Vector();
    recursiveSubdivide(curve1.getCubicCurve2D(), curve2.getCubicCurve2D(),
                       getRecursionDepth(curve1), getRecursionDepth(curve2),
                       0.0, 0.0, 1.0, 1.0);

    if (cc_intersections.size() == 0)
      return null;

    Intersection[] results = new Intersection[cc_intersections.size()];
    for (int i = 0; i < cc_intersections.size(); i++)
      {
	double[] temp = (double[]) cc_intersections.elementAt(i);
	results[i] = new Intersection(curve1.evaluatePoint(temp[0]), temp[0],
	                              temp[1]);
      }
    cc_intersections = null;
    return (results);
  }

  /**
   * Returns the intersections between a line and a quadratic bezier
   * Or null if no intersections are found1
   * This is done through combining the line's equation with the
   * parametric form of the Bezier and solving the resulting quadratic.
   * This is package-private to avoid an accessor method.
   */
  Intersection[] lineQuadIntersect(LineSegment l, QuadSegment c)
  {
    double[] y = new double[3];
    double[] x = new double[3];
    double[] r = new double[3];
    int nRoots;
    double x0 = c.P1.getX();
    double y0 = c.P1.getY();
    double x1 = c.cp.getX();
    double y1 = c.cp.getY();
    double x2 = c.P2.getX();
    double y2 = c.P2.getY();

    double lx0 = l.P1.getX();
    double ly0 = l.P1.getY();
    double lx1 = l.P2.getX();
    double ly1 = l.P2.getY();
    double dx = lx1 - lx0;
    double dy = ly1 - ly0;

    // form r(t) = y(t) - x(t) for the bezier
    y[0] = y0;
    y[1] = 2 * (y1 - y0);
    y[2] = (y2 - 2 * y1 + y0);

    x[0] = x0;
    x[1] = 2 * (x1 - x0);
    x[2] = (x2 - 2 * x1 + x0);

    // a point, not a line
    if (dy == 0 && dx == 0)
      return null;

    // line on y axis
    if (dx == 0 || (dy / dx) > 1.0)
      {
	double k = dx / dy;
	x[0] -= lx0;
	y[0] -= ly0;
	y[0] *= k;
	y[1] *= k;
	y[2] *= k;
      }
    else
      {
	double k = dy / dx;
	x[0] -= lx0;
	y[0] -= ly0;
	x[0] *= k;
	x[1] *= k;
	x[2] *= k;
      }

    for (int i = 0; i < 3; i++)
      r[i] = y[i] - x[i];

    if ((nRoots = QuadCurve2D.solveQuadratic(r)) > 0)
      {
	Intersection[] temp = new Intersection[nRoots];
	int intersections = 0;
	for (int i = 0; i < nRoots; i++)
	  {
	    double t = r[i];
	    if (t >= 0.0 && t <= 1.0)
	      {
		Point2D p = c.evaluatePoint(t);

		// if the line is on an axis, snap the point to that axis.
		if (dx == 0)
		  p.setLocation(lx0, p.getY());
		if (dy == 0)
		  p.setLocation(p.getX(), ly0);

		if (p.getX() <= Math.max(lx0, lx1)
		    && p.getX() >= Math.min(lx0, lx1)
		    && p.getY() <= Math.max(ly0, ly1)
		    && p.getY() >= Math.min(ly0, ly1))
		  {
		    double lineparameter = p.distance(l.P1) / l.P2.distance(l.P1);
		    temp[i] = new Intersection(p, lineparameter, t);
		    intersections++;
		  }
	      }
	    else
	      temp[i] = null;
	  }
	if (intersections == 0)
	  return null;

	Intersection[] rValues = new Intersection[intersections];

	for (int i = 0; i < nRoots; i++)
	  if (temp[i] != null)
	    rValues[--intersections] = temp[i];
	return (rValues);
      }
    return null;
  }

  /**
   * Returns the intersections between a line and a cubic segment
   * This is done through combining the line's equation with the
   * parametric form of the Bezier and solving the resulting quadratic.
   * This is package-private to avoid an accessor method. 
   */
  Intersection[] lineCubicIntersect(LineSegment l, CubicSegment c)
  {
    double[] y = new double[4];
    double[] x = new double[4];
    double[] r = new double[4];
    int nRoots;
    double x0 = c.P1.getX();
    double y0 = c.P1.getY();
    double x1 = c.cp1.getX();
    double y1 = c.cp1.getY();
    double x2 = c.cp2.getX();
    double y2 = c.cp2.getY();
    double x3 = c.P2.getX();
    double y3 = c.P2.getY();

    double lx0 = l.P1.getX();
    double ly0 = l.P1.getY();
    double lx1 = l.P2.getX();
    double ly1 = l.P2.getY();
    double dx = lx1 - lx0;
    double dy = ly1 - ly0;

    // form r(t) = y(t) - x(t) for the bezier
    y[0] = y0;
    y[1] = 3 * (y1 - y0);
    y[2] = 3 * (y2 + y0 - 2 * y1);
    y[3] = y3 - 3 * y2 + 3 * y1 - y0;

    x[0] = x0;
    x[1] = 3 * (x1 - x0);
    x[2] = 3 * (x2 + x0 - 2 * x1);
    x[3] = x3 - 3 * x2 + 3 * x1 - x0;

    // a point, not a line
    if (dy == 0 && dx == 0)
      return null;

    // line on y axis
    if (dx == 0 || (dy / dx) > 1.0)
      {
	double k = dx / dy;
	x[0] -= lx0;
	y[0] -= ly0;
	y[0] *= k;
	y[1] *= k;
	y[2] *= k;
	y[3] *= k;
      }
    else
      {
	double k = dy / dx;
	x[0] -= lx0;
	y[0] -= ly0;
	x[0] *= k;
	x[1] *= k;
	x[2] *= k;
	x[3] *= k;
      }
    for (int i = 0; i < 4; i++)
      r[i] = y[i] - x[i];

    if ((nRoots = CubicCurve2D.solveCubic(r)) > 0)
      {
	Intersection[] temp = new Intersection[nRoots];
	int intersections = 0;
	for (int i = 0; i < nRoots; i++)
	  {
	    double t = r[i];
	    if (t >= 0.0 && t <= 1.0)
	      {
		// if the line is on an axis, snap the point to that axis.
		Point2D p = c.evaluatePoint(t);
		if (dx == 0)
		  p.setLocation(lx0, p.getY());
		if (dy == 0)
		  p.setLocation(p.getX(), ly0);

		if (p.getX() <= Math.max(lx0, lx1)
		    && p.getX() >= Math.min(lx0, lx1)
		    && p.getY() <= Math.max(ly0, ly1)
		    && p.getY() >= Math.min(ly0, ly1))
		  {
		    double lineparameter = p.distance(l.P1) / l.P2.distance(l.P1);
		    temp[i] = new Intersection(p, lineparameter, t);
		    intersections++;
		  }
	      }
	    else
	      temp[i] = null;
	  }

	if (intersections == 0)
	  return null;

	Intersection[] rValues = new Intersection[intersections];
	for (int i = 0; i < nRoots; i++)
	  if (temp[i] != null)
	    rValues[--intersections] = temp[i];
	return (rValues);
      }
    return null;
  }

  /**
   * Returns the intersection between two lines, or null if there is no
   * intersection.
   * This is package-private to avoid an accessor method.
   */
  Intersection linesIntersect(LineSegment a, LineSegment b)
  {
    Point2D P1 = a.P1;
    Point2D P2 = a.P2;
    Point2D P3 = b.P1;
    Point2D P4 = b.P2;

    if (! Line2D.linesIntersect(P1.getX(), P1.getY(), P2.getX(), P2.getY(),
                                P3.getX(), P3.getY(), P4.getX(), P4.getY()))
      return null;

    double x1 = P1.getX();
    double y1 = P1.getY();
    double rx = P2.getX() - x1;
    double ry = P2.getY() - y1;

    double x2 = P3.getX();
    double y2 = P3.getY();
    double sx = P4.getX() - x2;
    double sy = P4.getY() - y2;

    double determinant = sx * ry - sy * rx;
    double nom = (sx * (y2 - y1) + sy * (x1 - x2));

    // Parallel lines don't intersect. At least we pretend they don't.
    if (Math.abs(determinant) < EPSILON)
      return null;

    nom = nom / determinant;

    if (nom == 0.0)
      return null;
    if (nom == 1.0)
      return null;

    Point2D p = new Point2D.Double(x1 + nom * rx, y1 + nom * ry);

    return new Intersection(p, p.distance(P1) / P1.distance(P2),
                            p.distance(P3) / P3.distance(P4));
  }

  /**
   * Determines if two points are equal, within an error margin
   * 'snap distance'
   * This is package-private to avoid an accessor method.
   */
  boolean pointEquals(Point2D a, Point2D b)
  {
    return (a.equals(b) || a.distance(b) < PE_EPSILON);
  }

  /**
   * Helper method
   * Turns a shape into a Vector of Segments
   */
  private Vector makeSegment(Shape s)
  {
    Vector paths = new Vector();
    PathIterator pi = s.getPathIterator(null);
    double[] coords = new double[6];
    Segment subpath = null;
    Segment current = null;
    double cx;
    double cy;
    double subpathx;
    double subpathy;
    cx = cy = subpathx = subpathy = 0.0;

    this.windingRule = pi.getWindingRule();

    while (! pi.isDone())
      {
	Segment v;
	switch (pi.currentSegment(coords))
	  {
	  case PathIterator.SEG_MOVETO:
	    if (subpath != null)
	      { // close existing open path
		current.next = new LineSegment(cx, cy, subpathx, subpathy);
		current = current.next;
		current.next = subpath;
	      }
	    subpath = null;
	    subpathx = cx = coords[0];
	    subpathy = cy = coords[1];
	    break;

	  // replace 'close' with a line-to.
	  case PathIterator.SEG_CLOSE:
	    if (subpath != null && (subpathx != cx || subpathy != cy))
	      {
		current.next = new LineSegment(cx, cy, subpathx, subpathy);
		current = current.next;
		current.next = subpath;
		cx = subpathx;
		cy = subpathy;
		subpath = null;
	      }
	    else if (subpath != null)
	      {
		current.next = subpath;
		subpath = null;
	      }
	    break;
	  case PathIterator.SEG_LINETO:
	    if (cx != coords[0] || cy != coords[1])
	      {
		v = new LineSegment(cx, cy, coords[0], coords[1]);
		if (subpath == null)
		  {
		    subpath = current = v;
		    paths.add(subpath);
		  }
		else
		  {
		    current.next = v;
		    current = current.next;
		  }
		cx = coords[0];
		cy = coords[1];
	      }
	    break;
	  case PathIterator.SEG_QUADTO:
	    v = new QuadSegment(cx, cy, coords[0], coords[1], coords[2],
	                        coords[3]);
	    if (subpath == null)
	      {
		subpath = current = v;
		paths.add(subpath);
	      }
	    else
	      {
		current.next = v;
		current = current.next;
	      }
	    cx = coords[2];
	    cy = coords[3];
	    break;
	  case PathIterator.SEG_CUBICTO:
	    v = new CubicSegment(cx, cy, coords[0], coords[1], coords[2],
	                         coords[3], coords[4], coords[5]);
	    if (subpath == null)
	      {
		subpath = current = v;
		paths.add(subpath);
	      }
	    else
	      {
		current.next = v;
		current = current.next;
	      }

	    // check if the cubic is self-intersecting
	    double[] lpts = ((CubicSegment) v).getLoop();
	    if (lpts != null)
	      {
		// if it is, break off the loop into its own path.
		v.subdivideInsert(lpts[0]);
		v.next.subdivideInsert((lpts[1] - lpts[0]) / (1.0 - lpts[0]));

		CubicSegment loop = (CubicSegment) v.next;
		v.next = loop.next;
		loop.next = loop;

		v.P2 = v.next.P1 = loop.P2 = loop.P1; // snap points
		paths.add(loop);
		current = v.next;
	      }

	    cx = coords[4];
	    cy = coords[5];
	    break;
	  }
	pi.next();
      }

    if (subpath != null)
      { // close any open path
	if (subpathx != cx || subpathy != cy)
	  {
	    current.next = new LineSegment(cx, cy, subpathx, subpathy);
	    current = current.next;
	    current.next = subpath;
	  }
	else
	  current.next = subpath;
      }

    if (paths.size() == 0)
      return (null);

    return (paths);
  }

  /**
   * Find the intersections of two separate closed paths,
   * A and B, split the segments at the intersection points,
   * and create nodes pointing from one to the other
   */
  private int createNodes(Segment A, Segment B)
  {
    int nNodes = 0;

    Segment a = A;
    Segment b = B;

    do
      {
	do
	  {
	    nNodes += a.splitIntersections(b);
	    b = b.next;
	  }
	while (b != B);

	a = a.next; // move to the next segment
      }
    while (a != A); // until one wrap.

    return (nNodes);
  }

  /**
   * Find the intersections of a path with itself.
   * Splits the segments at the intersection points,
   * and create nodes pointing from one to the other.
   */
  private int createNodesSelf(Segment A)
  {
    int nNodes = 0;
    Segment a = A;

    if (A.next == A)
      return 0;

    do
      {
	Segment b = a.next;
	do
	  {
	    if (b != a) // necessary
	      nNodes += a.splitIntersections(b);
	    b = b.next;
	  }
	while (b != A);
	a = a.next; // move to the next segment
      }
    while (a != A); // until one wrap.

    return (nNodes);
  }

  /**
   * Deletes paths which are redundant from a list, (i.e. solid areas within
   * solid areas) Clears any nodes. Sorts the remaining paths into solids
   * and holes, sets their orientation and sets the solids and holes lists.
   */
  private void deleteRedundantPaths(Vector paths)
  {
    int npaths = paths.size();

    int[][] contains = new int[npaths][npaths];
    int[][] windingNumbers = new int[npaths][2];
    int neg;
    Rectangle2D[] bb = new Rectangle2D[npaths]; // path bounding boxes

    neg = ((windingRule == PathIterator.WIND_NON_ZERO) ? -1 : 1);

    for (int i = 0; i < npaths; i++)
      bb[i] = ((Segment) paths.elementAt(i)).getPathBounds();

    // Find which path contains which, assign winding numbers
    for (int i = 0; i < npaths; i++)
      {
	Segment pathA = (Segment) paths.elementAt(i);
	pathA.nullNodes(); // remove any now-redundant nodes, in case.
	int windingA = pathA.hasClockwiseOrientation() ? 1 : neg;

	for (int j = 0; j < npaths; j++)
	  if (i != j)
	    {
	      Segment pathB = (Segment) paths.elementAt(j);

	      // A contains B
	      if (bb[i].intersects(bb[j]))
	        {
		  Segment s = pathB.next;
		  while (s.P1.getY() == s.P2.getY() && s != pathB)
		    s = s.next;
		  Point2D p = s.getMidPoint();
		  if (pathA.contains(p.getX(), p.getY()))
		    contains[i][j] = windingA;
	        }
	      else
		// A does not contain B
		contains[i][j] = 0;
	    }
	  else
	    contains[i][j] = windingA; // i == j
      }

    for (int i = 0; i < npaths; i++)
      {
	windingNumbers[i][0] = 0;
	for (int j = 0; j < npaths; j++)
	  windingNumbers[i][0] += contains[j][i];
	windingNumbers[i][1] = contains[i][i];
      }

    Vector solids = new Vector();
    Vector holes = new Vector();

    if (windingRule == PathIterator.WIND_NON_ZERO)
      {
	for (int i = 0; i < npaths; i++)
	  {
	    if (windingNumbers[i][0] == 0)
	      holes.add(paths.elementAt(i));
	    else if (windingNumbers[i][0] - windingNumbers[i][1] == 0
	             && Math.abs(windingNumbers[i][0]) == 1)
	      solids.add(paths.elementAt(i));
	  }
      }
    else
      {
	windingRule = PathIterator.WIND_NON_ZERO;
	for (int i = 0; i < npaths; i++)
	  {
	    if ((windingNumbers[i][0] & 1) == 0)
	      holes.add(paths.elementAt(i));
	    else if ((windingNumbers[i][0] & 1) == 1)
	      solids.add(paths.elementAt(i));
	  }
      }

    setDirection(holes, false);
    setDirection(solids, true);
    this.holes = holes;
    this.solids = solids;
  }

  /**
   * Sets the winding direction of a Vector of paths
   * @param clockwise gives the direction,
   * true = clockwise, false = counter-clockwise
   */
  private void setDirection(Vector paths, boolean clockwise)
  {
    Segment v;
    for (int i = 0; i < paths.size(); i++)
      {
	v = (Segment) paths.elementAt(i);
	if (clockwise != v.hasClockwiseOrientation())
	  v.reverseAll();
      }
  }

  /**
   * Class representing a linked-list of vertices forming a closed polygon,
   * convex or concave, without holes.
   */
  private abstract class Segment implements Cloneable
  {
    // segment type, PathIterator segment types are used.
    Point2D P1;
    Point2D P2;
    Segment next;
    Segment node;

    Segment()
    {
      P1 = P2 = null;
      node = next = null;
    }

    /**
     * Reverses the direction of a single segment
     */
    abstract void reverseCoords();

    /**
     * Returns the segment's midpoint
     */
    abstract Point2D getMidPoint();

    /**
     * Returns the bounding box of this segment
     */
    abstract Rectangle2D getBounds();

    /**
     * Transforms a single segment
     */
    abstract void transform(AffineTransform at);

    /**
     * Returns the PathIterator type of a segment
     */
    abstract int getType();

    /**
     */
    abstract int splitIntersections(Segment b);

    /**
     * Returns the PathIterator coords of a segment
     */
    abstract int pathIteratorFormat(double[] coords);

    /**
     * Returns the number of intersections on the positive X axis,
     * with the origin at (x,y), used for contains()-testing
     *
     * (Although that could be done by the line-intersect methods,
     * a dedicated method is better to guarantee consitent handling
     * of endpoint-special-cases)
     */
    abstract int rayCrossing(double x, double y);

    /**
     * Subdivides the segment at parametric value t, inserting
     * the new segment into the linked list after this,
     * such that this becomes [0,t] and this.next becomes [t,1]
     */
    abstract void subdivideInsert(double t);

    /**
     * Returns twice the area of a curve, relative the P1-P2 line
     * Used for area calculations.
     */
    abstract double curveArea();

    /**
     * Compare two segments.
     */
    abstract boolean equals(Segment b);

    /**
     * Determines if this path of segments contains the point (x,y)
     */
    boolean contains(double x, double y)
    {
      Segment v = this;
      int crossings = 0;
      do
        {
	  int n = v.rayCrossing(x, y);
	  crossings += n;
	  v = v.next;
        }
      while (v != this);
      return ((crossings & 1) == 1);
    }

    /**
     * Nulls all nodes of the path. Clean up any 'hairs'.
     */
    void nullNodes()
    {
      Segment v = this;
      do
        {
	  v.node = null;
	  v = v.next;
        }
      while (v != this);
    }

    /**
     * Transforms each segment in the closed path
     */
    void transformSegmentList(AffineTransform at)
    {
      Segment v = this;
      do
        {
	  v.transform(at);
	  v = v.next;
        }
      while (v != this);
    }

    /**
     * Determines the winding direction of the path
     * By the sign of the area.
     */
    boolean hasClockwiseOrientation()
    {
      return (getSignedArea() > 0.0);
    }

    /**
     * Returns the bounds of this path
     */
    public Rectangle2D getPathBounds()
    {
      double xmin;
      double xmax;
      double ymin;
      double ymax;
      xmin = xmax = P1.getX();
      ymin = ymax = P1.getY();

      Segment v = this;
      do
        {
	  Rectangle2D r = v.getBounds();
	  xmin = Math.min(r.getMinX(), xmin);
	  ymin = Math.min(r.getMinY(), ymin);
	  xmax = Math.max(r.getMaxX(), xmax);
	  ymax = Math.max(r.getMaxY(), ymax);
	  v = v.next;
        }
      while (v != this);

      return (new Rectangle2D.Double(xmin, ymin, (xmax - xmin), (ymax - ymin)));
    }

    /**
     * Calculates twice the signed area of the path;
     */
    double getSignedArea()
    {
      Segment s;
      double area = 0.0;

      s = this;
      do
        {
	  area += s.curveArea();

	  area += s.P1.getX() * s.next.P1.getY()
	  - s.P1.getY() * s.next.P1.getX();
	  s = s.next;
        }
      while (s != this);

      return area;
    }

    /**
     * Reverses the orientation of the whole polygon
     */
    void reverseAll()
    {
      reverseCoords();
      Segment v = next;
      Segment former = this;
      while (v != this)
        {
	  v.reverseCoords();
	  Segment vnext = v.next;
	  v.next = former;
	  former = v;
	  v = vnext;
        }
      next = former;
    }

    /**
     * Inserts a Segment after this one
     */
    void insert(Segment v)
    {
      Segment n = next;
      next = v;
      v.next = n;
    }

    /**
     * Returns if this segment path is polygonal
     */
    boolean isPolygonal()
    {
      Segment v = this;
      do
        {
	  if (! (v instanceof LineSegment))
	    return false;
	  v = v.next;
        }
      while (v != this);
      return true;
    }

    /**
     * Clones this path
     */
    Segment cloneSegmentList() throws CloneNotSupportedException
    {
      Vector list = new Vector();
      Segment v = next;

      while (v != this)
        {
	  list.add(v);
	  v = v.next;
        }

      Segment clone = (Segment) this.clone();
      v = clone;
      for (int i = 0; i < list.size(); i++)
        {
	  clone.next = (Segment) ((Segment) list.elementAt(i)).clone();
	  clone = clone.next;
        }
      clone.next = v;
      return v;
    }

    /**
     * Creates a node between this segment and segment b
     * at the given intersection
     * @return the number of nodes created (0 or 1)
     */
    int createNode(Segment b, Intersection i)
    {
      Point2D p = i.p;
      if ((pointEquals(P1, p) || pointEquals(P2, p))
          && (pointEquals(b.P1, p) || pointEquals(b.P2, p)))
	return 0;

      subdivideInsert(i.ta);
      b.subdivideInsert(i.tb);

      // snap points
      b.P2 = b.next.P1 = P2 = next.P1 = i.p;

      node = b.next;
      b.node = next;
      return 1;
    }

    /**
     * Creates multiple nodes from a list of intersections,
     * This must be done in the order of ascending parameters,
     * and the parameters must be recalculated in accordance
     * with each split.
     * @return the number of nodes created
     */
    protected int createNodes(Segment b, Intersection[] x)
    {
      Vector v = new Vector();
      for (int i = 0; i < x.length; i++)
        {
	  Point2D p = x[i].p;
	  if (! ((pointEquals(P1, p) || pointEquals(P2, p))
	      && (pointEquals(b.P1, p) || pointEquals(b.P2, p))))
	    v.add(x[i]);
        }

      int nNodes = v.size();
      Intersection[] A = new Intersection[nNodes];
      Intersection[] B = new Intersection[nNodes];
      for (int i = 0; i < nNodes; i++)
	A[i] = B[i] = (Intersection) v.elementAt(i);

      // Create two lists sorted by the parameter
      // Bubble sort, OK I suppose, since the number of intersections
      // cannot be larger than 9 (cubic-cubic worst case) anyway
      for (int i = 0; i < nNodes - 1; i++)
        {
	  for (int j = i + 1; j < nNodes; j++)
	    {
	      if (A[i].ta > A[j].ta)
	        {
		  Intersection swap = A[i];
		  A[i] = A[j];
		  A[j] = swap;
	        }
	      if (B[i].tb > B[j].tb)
	        {
		  Intersection swap = B[i];
		  B[i] = B[j];
		  B[j] = swap;
	        }
	    }
        }
      // subdivide a
      Segment s = this;
      for (int i = 0; i < nNodes; i++)
        {
	  s.subdivideInsert(A[i].ta);

	  // renormalize the parameters
	  for (int j = i + 1; j < nNodes; j++)
	    A[j].ta = (A[j].ta - A[i].ta) / (1.0 - A[i].ta);

	  A[i].seg = s;
	  s = s.next;
        }

      // subdivide b, set nodes
      s = b;
      for (int i = 0; i < nNodes; i++)
        {
	  s.subdivideInsert(B[i].tb);

	  for (int j = i + 1; j < nNodes; j++)
	    B[j].tb = (B[j].tb - B[i].tb) / (1.0 - B[i].tb);

	  // set nodes
	  B[i].seg.node = s.next; // node a -> b 
	  s.node = B[i].seg.next; // node b -> a 

	  // snap points
	  B[i].seg.P2 = B[i].seg.next.P1 = s.P2 = s.next.P1 = B[i].p;
	  s = s.next;
        }
      return nNodes;
    }

    /**
     * Determines if two paths are equal.
     * Colinear line segments are ignored in the comparison.
     */
    boolean pathEquals(Segment B)
    {
      if (! getPathBounds().equals(B.getPathBounds()))
	return false;

      Segment startA = getTopLeft();
      Segment startB = B.getTopLeft();
      Segment a = startA;
      Segment b = startB;
      do
        {
	  if (! a.equals(b))
	    return false;

	  if (a instanceof LineSegment)
	    a = ((LineSegment) a).lastCoLinear();
	  if (b instanceof LineSegment)
	    b = ((LineSegment) b).lastCoLinear();

	  a = a.next;
	  b = b.next;
        }
      while (a != startA && b != startB);
      return true;
    }

    /**
     * Return the segment with the top-leftmost first point
     */
    Segment getTopLeft()
    {
      Segment v = this;
      Segment tl = this;
      do
        {
	  if (v.P1.getY() < tl.P1.getY())
	    tl = v;
	  else if (v.P1.getY() == tl.P1.getY())
	    {
	      if (v.P1.getX() < tl.P1.getX())
		tl = v;
	    }
	  v = v.next;
        }
      while (v != this);
      return tl;
    }

    /**
     * Returns if the path has a segment outside a shape
     */
    boolean isSegmentOutside(Shape shape)
    {
      return ! shape.contains(getMidPoint());
    }
  } // class Segment

  private class LineSegment extends Segment
  {
    public LineSegment(double x1, double y1, double x2, double y2)
    {
      super();
      P1 = new Point2D.Double(x1, y1);
      P2 = new Point2D.Double(x2, y2);
    }

    public LineSegment(Point2D p1, Point2D p2)
    {
      super();
      P1 = (Point2D) p1.clone();
      P2 = (Point2D) p2.clone();
    }

    /**
     * Clones this segment
     */
    public Object clone()
    {
      return new LineSegment(P1, P2);
    }

    /**
     * Transforms the segment
     */
    void transform(AffineTransform at)
    {
      P1 = at.transform(P1, null);
      P2 = at.transform(P2, null);
    }

    /**
     * Swap start and end points
     */
    void reverseCoords()
    {
      Point2D p = P1;
      P1 = P2;
      P2 = p;
    }

    /**
     * Returns the segment's midpoint
     */
    Point2D getMidPoint()
    {
      return (new Point2D.Double(0.5 * (P1.getX() + P2.getX()),
                                 0.5 * (P1.getY() + P2.getY())));
    }

    /**
     * Returns twice the area of a curve, relative the P1-P2 line
     * Obviously, a line does not enclose any area besides the line
     */
    double curveArea()
    {
      return 0;
    }

    /**
     * Returns the PathIterator type of a segment
     */
    int getType()
    {
      return (PathIterator.SEG_LINETO);
    }

    /**
     * Subdivides the segment at parametric value t, inserting
     * the new segment into the linked list after this,
     * such that this becomes [0,t] and this.next becomes [t,1]
     */
    void subdivideInsert(double t)
    {
      Point2D p = new Point2D.Double((P2.getX() - P1.getX()) * t + P1.getX(),
                                     (P2.getY() - P1.getY()) * t + P1.getY());
      insert(new LineSegment(p, P2));
      P2 = p;
      next.node = node;
      node = null;
    }

    /**
     * Determines if two line segments are strictly colinear
     */
    boolean isCoLinear(LineSegment b)
    {
      double x1 = P1.getX();
      double y1 = P1.getY();
      double x2 = P2.getX();
      double y2 = P2.getY();
      double x3 = b.P1.getX();
      double y3 = b.P1.getY();
      double x4 = b.P2.getX();
      double y4 = b.P2.getY();

      if ((y1 - y3) * (x4 - x3) - (x1 - x3) * (y4 - y3) != 0.0)
	return false;

      return ((x2 - x1) * (y4 - y3) - (y2 - y1) * (x4 - x3) == 0.0);
    }

    /**
     * Return the last segment colinear with this one.
     * Used in comparing paths.
     */
    Segment lastCoLinear()
    {
      Segment prev = this;
      Segment v = next;

      while (v instanceof LineSegment)
        {
	  if (isCoLinear((LineSegment) v))
	    {
	      prev = v;
	      v = v.next;
	    }
	  else
	    return prev;
        }
      return prev;
    }

    /**
     * Compare two segments.
     * We must take into account that the lines may be broken into colinear
     * subsegments and ignore them.
     */
    boolean equals(Segment b)
    {
      if (! (b instanceof LineSegment))
	return false;
      Point2D p1 = P1;
      Point2D p3 = b.P1;

      if (! p1.equals(p3))
	return false;

      Point2D p2 = lastCoLinear().P2;
      Point2D p4 = ((LineSegment) b).lastCoLinear().P2;
      return (p2.equals(p4));
    }

    /**
     * Returns a line segment
     */
    int pathIteratorFormat(double[] coords)
    {
      coords[0] = P2.getX();
      coords[1] = P2.getY();
      return (PathIterator.SEG_LINETO);
    }

    /**
     * Returns if the line has intersections.
     */
    boolean hasIntersections(Segment b)
    {
      if (b instanceof LineSegment)
	return (linesIntersect(this, (LineSegment) b) != null);

      if (b instanceof QuadSegment)
	return (lineQuadIntersect(this, (QuadSegment) b) != null);

      if (b instanceof CubicSegment)
	return (lineCubicIntersect(this, (CubicSegment) b) != null);

      return false;
    }

    /**
     * Splits intersections into nodes,
     * This one handles line-line, line-quadratic, line-cubic
     */
    int splitIntersections(Segment b)
    {
      if (b instanceof LineSegment)
        {
	  Intersection i = linesIntersect(this, (LineSegment) b);

	  if (i == null)
	    return 0;

	  return createNode(b, i);
        }

      Intersection[] x = null;

      if (b instanceof QuadSegment)
	x = lineQuadIntersect(this, (QuadSegment) b);

      if (b instanceof CubicSegment)
	x = lineCubicIntersect(this, (CubicSegment) b);

      if (x == null)
	return 0;

      if (x.length == 1)
	return createNode(b, (Intersection) x[0]);

      return createNodes(b, x);
    }

    /**
     * Returns the bounding box of this segment
     */
    Rectangle2D getBounds()
    {
      return (new Rectangle2D.Double(Math.min(P1.getX(), P2.getX()),
                                     Math.min(P1.getY(), P2.getY()),
                                     Math.abs(P1.getX() - P2.getX()),
                                     Math.abs(P1.getY() - P2.getY())));
    }

    /**
     * Returns the number of intersections on the positive X axis,
     * with the origin at (x,y), used for contains()-testing
     */
    int rayCrossing(double x, double y)
    {
      double x0 = P1.getX() - x;
      double y0 = P1.getY() - y;
      double x1 = P2.getX() - x;
      double y1 = P2.getY() - y;

      if (y0 * y1 > 0)
	return 0;

      if (x0 < 0 && x1 < 0)
	return 0;

      if (y0 == 0.0)
	y0 -= EPSILON;

      if (y1 == 0.0)
	y1 -= EPSILON;

      if (Line2D.linesIntersect(x0, y0, x1, y1, 
				EPSILON, 0.0, Double.MAX_VALUE, 0.0))
	return 1;
      return 0;
    }
  } // class LineSegment

  /**
   * Quadratic Bezier curve segment
   *
   * Note: Most peers don't support quadratics directly, so it might make
   * sense to represent them as cubics internally and just be done with it.
   * I think we should be peer-agnostic, however, and stay faithful to the
   * input geometry types as far as possible.
   */
  private class QuadSegment extends Segment
  {
    Point2D cp; // control point

    /**
     * Constructor, takes the coordinates of the start, control,
     * and end point, respectively.
     */
    QuadSegment(double x1, double y1, double cx, double cy, double x2,
                double y2)
    {
      super();
      P1 = new Point2D.Double(x1, y1);
      P2 = new Point2D.Double(x2, y2);
      cp = new Point2D.Double(cx, cy);
    }

    /**
     * Clones this segment
     */
    public Object clone()
    {
      return new QuadSegment(P1.getX(), P1.getY(), cp.getX(), cp.getY(),
                             P2.getX(), P2.getY());
    }

    /**
     * Returns twice the area of a curve, relative the P1-P2 line
     *
     * The area formula can be derived by using Green's formula in the
     * plane on the parametric form of the bezier.
     */
    double curveArea()
    {
      double x0 = P1.getX();
      double y0 = P1.getY();
      double x1 = cp.getX();
      double y1 = cp.getY();
      double x2 = P2.getX();
      double y2 = P2.getY();

      double P = (y2 - 2 * y1 + y0);
      double Q = 2 * (y1 - y0);

      double A = (x2 - 2 * x1 + x0);
      double B = 2 * (x1 - x0);

      double area = (B * P - A * Q) / 3.0;
      return (area);
    }

    /**
     * Compare two segments.
     */
    boolean equals(Segment b)
    {
      if (! (b instanceof QuadSegment))
	return false;

      return (P1.equals(b.P1) && cp.equals(((QuadSegment) b).cp)
             && P2.equals(b.P2));
    }

    /**
     * Returns a Point2D corresponding to the parametric value t
     * of the curve
     */
    Point2D evaluatePoint(double t)
    {
      double x0 = P1.getX();
      double y0 = P1.getY();
      double x1 = cp.getX();
      double y1 = cp.getY();
      double x2 = P2.getX();
      double y2 = P2.getY();

      return new Point2D.Double(t * t * (x2 - 2 * x1 + x0) + 2 * t * (x1 - x0)
                                + x0,
                                t * t * (y2 - 2 * y1 + y0) + 2 * t * (y1 - y0)
                                + y0);
    }

    /**
     * Returns the bounding box of this segment
     */
    Rectangle2D getBounds()
    {
      double x0 = P1.getX();
      double y0 = P1.getY();
      double x1 = cp.getX();
      double y1 = cp.getY();
      double x2 = P2.getX();
      double y2 = P2.getY();
      double r0;
      double r1;

      double xmax = Math.max(x0, x2);
      double ymax = Math.max(y0, y2);
      double xmin = Math.min(x0, x2);
      double ymin = Math.min(y0, y2);

      r0 = 2 * (y1 - y0);
      r1 = 2 * (y2 - 2 * y1 + y0);
      if (r1 != 0.0)
        {
	  double t = -r0 / r1;
	  if (t > 0.0 && t < 1.0)
	    {
	      double y = evaluatePoint(t).getY();
	      ymax = Math.max(y, ymax);
	      ymin = Math.min(y, ymin);
	    }
        }
      r0 = 2 * (x1 - x0);
      r1 = 2 * (x2 - 2 * x1 + x0);
      if (r1 != 0.0)
        {
	  double t = -r0 / r1;
	  if (t > 0.0 && t < 1.0)
	    {
	      double x = evaluatePoint(t).getY();
	      xmax = Math.max(x, xmax);
	      xmin = Math.min(x, xmin);
	    }
        }

      return (new Rectangle2D.Double(xmin, ymin, xmax - xmin, ymax - ymin));
    }

    /**
     * Returns a cubic segment corresponding to this curve
     */
    CubicSegment getCubicSegment()
    {
      double x1 = P1.getX() + 2.0 * (cp.getX() - P1.getX()) / 3.0;
      double y1 = P1.getY() + 2.0 * (cp.getY() - P1.getY()) / 3.0;
      double x2 = cp.getX() + (P2.getX() - cp.getX()) / 3.0;
      double y2 = cp.getY() + (P2.getY() - cp.getY()) / 3.0;

      return new CubicSegment(P1.getX(), P1.getY(), x1, y1, x2, y2, P2.getX(),
                              P2.getY());
    }

    /**
     * Returns the segment's midpoint
     */
    Point2D getMidPoint()
    {
      return evaluatePoint(0.5);
    }

    /**
     * Returns the PathIterator type of a segment
     */
    int getType()
    {
      return (PathIterator.SEG_QUADTO);
    }

    /**
     * Returns the PathIterator coords of a segment
     */
    int pathIteratorFormat(double[] coords)
    {
      coords[0] = cp.getX();
      coords[1] = cp.getY();
      coords[2] = P2.getX();
      coords[3] = P2.getY();
      return (PathIterator.SEG_QUADTO);
    }

    /**
     * Returns the number of intersections on the positive X axis,
     * with the origin at (x,y), used for contains()-testing
     */
    int rayCrossing(double x, double y)
    {
      double x0 = P1.getX() - x;
      double y0 = P1.getY() - y;
      double x1 = cp.getX() - x;
      double y1 = cp.getY() - y;
      double x2 = P2.getX() - x;
      double y2 = P2.getY() - y;
      double[] r = new double[3];
      int nRoots;
      int nCrossings = 0;

      /* check if curve may intersect X+ axis. */
      if ((x0 > 0.0 || x1 > 0.0 || x2 > 0.0) && (y0 * y1 <= 0 || y1 * y2 <= 0))
        {
	  if (y0 == 0.0)
	    y0 -= EPSILON;
	  if (y2 == 0.0)
	    y2 -= EPSILON;

	  r[0] = y0;
	  r[1] = 2 * (y1 - y0);
	  r[2] = (y2 - 2 * y1 + y0);

	  nRoots = QuadCurve2D.solveQuadratic(r);
	  for (int i = 0; i < nRoots; i++)
	    if (r[i] > 0.0f && r[i] < 1.0f)
	      {
		double t = r[i];
		if (t * t * (x2 - 2 * x1 + x0) + 2 * t * (x1 - x0) + x0 > 0.0)
		  nCrossings++;
	      }
        }
      return nCrossings;
    }

    /**
     * Swap start and end points
     */
    void reverseCoords()
    {
      Point2D temp = P1;
      P1 = P2;
      P2 = temp;
    }

    /**
     * Splits intersections into nodes,
     * This one handles quadratic-quadratic only,
     * Quadratic-line is passed on to the LineSegment class,
     * Quadratic-cubic is passed on to the CubicSegment class
     */
    int splitIntersections(Segment b)
    {
      if (b instanceof LineSegment)
	return (b.splitIntersections(this));

      if (b instanceof CubicSegment)
	return (b.splitIntersections(this));

      if (b instanceof QuadSegment)
        {
	  // Use the cubic-cubic intersection routine for quads as well,
	  // Since a quadratic can be exactly described as a cubic, this
	  // should not be a problem; 
	  // The recursion depth will be the same in any case.
	  Intersection[] x = cubicCubicIntersect(getCubicSegment(),
	                                         ((QuadSegment) b)
	                                         .getCubicSegment());
	  if (x == null)
	    return 0;

	  if (x.length == 1)
	    return createNode(b, (Intersection) x[0]);

	  return createNodes(b, x);
        }
      return 0;
    }

    /**
     * Subdivides the segment at parametric value t, inserting
     * the new segment into the linked list after this,
     * such that this becomes [0,t] and this.next becomes [t,1]
     */
    void subdivideInsert(double t)
    {
      double x0 = P1.getX();
      double y0 = P1.getY();
      double x1 = cp.getX();
      double y1 = cp.getY();
      double x2 = P2.getX();
      double y2 = P2.getY();

      double p10x = x0 + t * (x1 - x0);
      double p10y = y0 + t * (y1 - y0);
      double p11x = x1 + t * (x2 - x1);
      double p11y = y1 + t * (y2 - y1);
      double p20x = p10x + t * (p11x - p10x);
      double p20y = p10y + t * (p11y - p10y);

      insert(new QuadSegment(p20x, p20y, p11x, p11y, x2, y2));
      P2 = next.P1;
      cp.setLocation(p10x, p10y);

      next.node = node;
      node = null;
    }

    /**
     * Transforms the segment
     */
    void transform(AffineTransform at)
    {
      P1 = at.transform(P1, null);
      P2 = at.transform(P2, null);
      cp = at.transform(cp, null);
    }
  } // class QuadSegment

  /**
   * Cubic Bezier curve segment
   */
  private class CubicSegment extends Segment
  {
    Point2D cp1; // control points
    Point2D cp2; // control points

    /**
     * Constructor - takes coordinates of the starting point,
     * first control point, second control point and end point,
     * respecively.
     */
    public CubicSegment(double x1, double y1, double c1x, double c1y,
                        double c2x, double c2y, double x2, double y2)
    {
      super();
      P1 = new Point2D.Double(x1, y1);
      P2 = new Point2D.Double(x2, y2);
      cp1 = new Point2D.Double(c1x, c1y);
      cp2 = new Point2D.Double(c2x, c2y);
    }

    /**
     * Clones this segment
     */
    public Object clone()
    {
      return new CubicSegment(P1.getX(), P1.getY(), cp1.getX(), cp1.getY(),
                              cp2.getX(), cp2.getY(), P2.getX(), P2.getY());
    }

    /**
     * Returns twice the area of a curve, relative the P1-P2 line
     *
     * The area formula can be derived by using Green's formula in the
     * plane on the parametric form of the bezier.
     */
    double curveArea()
    {
      double x0 = P1.getX();
      double y0 = P1.getY();
      double x1 = cp1.getX();
      double y1 = cp1.getY();
      double x2 = cp2.getX();
      double y2 = cp2.getY();
      double x3 = P2.getX();
      double y3 = P2.getY();

      double P = y3 - 3 * y2 + 3 * y1 - y0;
      double Q = 3 * (y2 + y0 - 2 * y1);
      double R = 3 * (y1 - y0);

      double A = x3 - 3 * x2 + 3 * x1 - x0;
      double B = 3 * (x2 + x0 - 2 * x1);
      double C = 3 * (x1 - x0);

      double area = (B * P - A * Q) / 5.0 + (C * P - A * R) / 2.0
                    + (C * Q - B * R) / 3.0;

      return (area);
    }

    /**
     * Compare two segments.
     */
    boolean equals(Segment b)
    {
      if (! (b instanceof CubicSegment))
	return false;

      return (P1.equals(b.P1) && cp1.equals(((CubicSegment) b).cp1)
             && cp2.equals(((CubicSegment) b).cp2) && P2.equals(b.P2));
    }

    /**
     * Returns a Point2D corresponding to the parametric value t
     * of the curve
     */
    Point2D evaluatePoint(double t)
    {
      double x0 = P1.getX();
      double y0 = P1.getY();
      double x1 = cp1.getX();
      double y1 = cp1.getY();
      double x2 = cp2.getX();
      double y2 = cp2.getY();
      double x3 = P2.getX();
      double y3 = P2.getY();

      return new Point2D.Double(-(t * t * t) * (x0 - 3 * x1 + 3 * x2 - x3)
                                + 3 * t * t * (x0 - 2 * x1 + x2)
                                + 3 * t * (x1 - x0) + x0,
                                -(t * t * t) * (y0 - 3 * y1 + 3 * y2 - y3)
                                + 3 * t * t * (y0 - 2 * y1 + y2)
                                + 3 * t * (y1 - y0) + y0);
    }

    /**
     * Returns the bounding box of this segment
     */
    Rectangle2D getBounds()
    {
      double x0 = P1.getX();
      double y0 = P1.getY();
      double x1 = cp1.getX();
      double y1 = cp1.getY();
      double x2 = cp2.getX();
      double y2 = cp2.getY();
      double x3 = P2.getX();
      double y3 = P2.getY();
      double[] r = new double[3];

      double xmax = Math.max(x0, x3);
      double ymax = Math.max(y0, y3);
      double xmin = Math.min(x0, x3);
      double ymin = Math.min(y0, y3);

      r[0] = 3 * (y1 - y0);
      r[1] = 6.0 * (y2 + y0 - 2 * y1);
      r[2] = 3.0 * (y3 - 3 * y2 + 3 * y1 - y0);

      int n = QuadCurve2D.solveQuadratic(r);
      for (int i = 0; i < n; i++)
        {
	  double t = r[i];
	  if (t > 0 && t < 1.0)
	    {
	      double y = evaluatePoint(t).getY();
	      ymax = Math.max(y, ymax);
	      ymin = Math.min(y, ymin);
	    }
        }

      r[0] = 3 * (x1 - x0);
      r[1] = 6.0 * (x2 + x0 - 2 * x1);
      r[2] = 3.0 * (x3 - 3 * x2 + 3 * x1 - x0);
      n = QuadCurve2D.solveQuadratic(r);
      for (int i = 0; i < n; i++)
        {
	  double t = r[i];
	  if (t > 0 && t < 1.0)
	    {
	      double x = evaluatePoint(t).getX();
	      xmax = Math.max(x, xmax);
	      xmin = Math.min(x, xmin);
	    }
        }
      return (new Rectangle2D.Double(xmin, ymin, (xmax - xmin), (ymax - ymin)));
    }

    /**
     * Returns a CubicCurve2D object corresponding to this segment.
     */
    CubicCurve2D getCubicCurve2D()
    {
      return new CubicCurve2D.Double(P1.getX(), P1.getY(), cp1.getX(),
                                     cp1.getY(), cp2.getX(), cp2.getY(),
                                     P2.getX(), P2.getY());
    }

    /**
     * Returns the parametric points of self-intersection if the cubic
     * is self-intersecting, null otherwise.
     */
    double[] getLoop()
    {
      double x0 = P1.getX();
      double y0 = P1.getY();
      double x1 = cp1.getX();
      double y1 = cp1.getY();
      double x2 = cp2.getX();
      double y2 = cp2.getY();
      double x3 = P2.getX();
      double y3 = P2.getY();
      double[] r = new double[4];
      double k;
      double R;
      double T;
      double A;
      double B;
      double[] results = new double[2];

      R = x3 - 3 * x2 + 3 * x1 - x0;
      T = y3 - 3 * y2 + 3 * y1 - y0;

      // A qudratic
      if (R == 0.0 && T == 0.0)
	return null;

      // true cubic
      if (R != 0.0 && T != 0.0)
        {
	  A = 3 * (x2 + x0 - 2 * x1) / R;
	  B = 3 * (x1 - x0) / R;

	  double P = 3 * (y2 + y0 - 2 * y1) / T;
	  double Q = 3 * (y1 - y0) / T;

	  if (A == P || Q == B)
	    return null;

	  k = (Q - B) / (A - P);
        }
      else
        {
	  if (R == 0.0)
	    {
	      // quadratic in x
	      k = -(3 * (x1 - x0)) / (3 * (x2 + x0 - 2 * x1));
	      A = 3 * (y2 + y0 - 2 * y1) / T;
	      B = 3 * (y1 - y0) / T;
	    }
	  else
	    {
	      // quadratic in y
	      k = -(3 * (y1 - y0)) / (3 * (y2 + y0 - 2 * y1));
	      A = 3 * (x2 + x0 - 2 * x1) / R;
	      B = 3 * (x1 - x0) / R;
	    }
        }

      r[0] = -k * k * k - A * k * k - B * k;
      r[1] = 3 * k * k + 2 * k * A + 2 * B;
      r[2] = -3 * k;
      r[3] = 2;

      int n = CubicCurve2D.solveCubic(r);
      if (n != 3)
	return null;

      // sort r
      double t;
      for (int i = 0; i < 2; i++)
	for (int j = i + 1; j < 3; j++)
	  if (r[j] < r[i])
	    {
	      t = r[i];
	      r[i] = r[j];
	      r[j] = t;
	    }

      if (Math.abs(r[0] + r[2] - k) < 1E-13)
	if (r[0] >= 0.0 && r[0] <= 1.0 && r[2] >= 0.0 && r[2] <= 1.0)
	  if (evaluatePoint(r[0]).distance(evaluatePoint(r[2])) < PE_EPSILON * 10)
	    { // we snap the points anyway
	      results[0] = r[0];
	      results[1] = r[2];
	      return (results);
	    }
      return null;
    }

    /**
     * Returns the segment's midpoint
     */
    Point2D getMidPoint()
    {
      return evaluatePoint(0.5);
    }

    /**
     * Returns the PathIterator type of a segment
     */
    int getType()
    {
      return (PathIterator.SEG_CUBICTO);
    }

    /**
     * Returns the PathIterator coords of a segment
     */
    int pathIteratorFormat(double[] coords)
    {
      coords[0] = cp1.getX();
      coords[1] = cp1.getY();
      coords[2] = cp2.getX();
      coords[3] = cp2.getY();
      coords[4] = P2.getX();
      coords[5] = P2.getY();
      return (PathIterator.SEG_CUBICTO);
    }

    /**
     * Returns the number of intersections on the positive X axis,
     * with the origin at (x,y), used for contains()-testing
     */
    int rayCrossing(double x, double y)
    {
      double x0 = P1.getX() - x;
      double y0 = P1.getY() - y;
      double x1 = cp1.getX() - x;
      double y1 = cp1.getY() - y;
      double x2 = cp2.getX() - x;
      double y2 = cp2.getY() - y;
      double x3 = P2.getX() - x;
      double y3 = P2.getY() - y;
      double[] r = new double[4];
      int nRoots;
      int nCrossings = 0;

      /* check if curve may intersect X+ axis. */
      if ((x0 > 0.0 || x1 > 0.0 || x2 > 0.0 || x3 > 0.0)
          && (y0 * y1 <= 0 || y1 * y2 <= 0 || y2 * y3 <= 0))
        {
	  if (y0 == 0.0)
	    y0 -= EPSILON;
	  if (y3 == 0.0)
	    y3 -= EPSILON;

	  r[0] = y0;
	  r[1] = 3 * (y1 - y0);
	  r[2] = 3 * (y2 + y0 - 2 * y1);
	  r[3] = y3 - 3 * y2 + 3 * y1 - y0;

	  if ((nRoots = CubicCurve2D.solveCubic(r)) > 0)
	    for (int i = 0; i < nRoots; i++)
	      {
		if (r[i] > 0.0 && r[i] < 1.0)
		  {
		    double t = r[i];
		    if (-(t * t * t) * (x0 - 3 * x1 + 3 * x2 - x3)
		        + 3 * t * t * (x0 - 2 * x1 + x2) + 3 * t * (x1 - x0)
		        + x0 > 0.0)
		      nCrossings++;
		  }
	      }
        }
      return nCrossings;
    }

    /**
     * Swap start and end points
     */
    void reverseCoords()
    {
      Point2D p = P1;
      P1 = P2;
      P2 = p;
      p = cp1; // swap control points
      cp1 = cp2;
      cp2 = p;
    }

    /**
     * Splits intersections into nodes,
     * This one handles cubic-cubic and cubic-quadratic intersections
     */
    int splitIntersections(Segment b)
    {
      if (b instanceof LineSegment)
	return (b.splitIntersections(this));

      Intersection[] x = null;

      if (b instanceof QuadSegment)
	x = cubicCubicIntersect(this, ((QuadSegment) b).getCubicSegment());

      if (b instanceof CubicSegment)
	x = cubicCubicIntersect(this, (CubicSegment) b);

      if (x == null)
	return 0;

      if (x.length == 1)
	return createNode(b, x[0]);

      return createNodes(b, x);
    }

    /**
     * Subdivides the segment at parametric value t, inserting
     * the new segment into the linked list after this,
     * such that this becomes [0,t] and this.next becomes [t,1]
     */
    void subdivideInsert(double t)
    {
      CubicSegment s = (CubicSegment) clone();
      double p1x = (s.cp1.getX() - s.P1.getX()) * t + s.P1.getX();
      double p1y = (s.cp1.getY() - s.P1.getY()) * t + s.P1.getY();

      double px = (s.cp2.getX() - s.cp1.getX()) * t + s.cp1.getX();
      double py = (s.cp2.getY() - s.cp1.getY()) * t + s.cp1.getY();

      s.cp2.setLocation((s.P2.getX() - s.cp2.getX()) * t + s.cp2.getX(),
                        (s.P2.getY() - s.cp2.getY()) * t + s.cp2.getY());

      s.cp1.setLocation((s.cp2.getX() - px) * t + px,
                        (s.cp2.getY() - py) * t + py);

      double p2x = (px - p1x) * t + p1x;
      double p2y = (py - p1y) * t + p1y;

      double p3x = (s.cp1.getX() - p2x) * t + p2x;
      double p3y = (s.cp1.getY() - p2y) * t + p2y;
      s.P1.setLocation(p3x, p3y);

      // insert new curve
      insert(s);

      // set this curve
      cp1.setLocation(p1x, p1y);
      cp2.setLocation(p2x, p2y);
      P2 = s.P1;
      next.node = node;
      node = null;
    }

    /**
     * Transforms the segment
     */
    void transform(AffineTransform at)
    {
      P1 = at.transform(P1, null);
      P2 = at.transform(P2, null);
      cp1 = at.transform(cp1, null);
      cp2 = at.transform(cp2, null);
    }
  } // class CubicSegment
} // class Area
