gt: 	bounds = new Rectangle (minx, miny, maxx - minx, maxy - miny);
context: /* Copyright (C) 2001  Free Software Foundation
  
     This file is part of libjava.
  
  This software is copyrighted work licensed under the terms of the
  Libjava License.  Please consult the file "LIBJAVA_LICENSE" for
  details.  */
  
  package java.awt;
  
  import java.awt.geom.*;
  import java.io.Serializable;
  import java.util.Arrays;
  
  /**
   * @author Tom Tromey <tromey@redhat.com>
   * @date May 10, 2001
   */
  
  /** The Polygon class represents a closed region whose boundary is
      made of line segments.  The Polygon is defined by its vertices.  */
  public class Polygon implements Shape, Serializable
  {
    /** The bounds of the polygon.  This is null until the bounds have
     *  been computed for the first time; then it is correctly
     *  maintained whenever it is modified.  */
    protected Rectangle bounds;
  
    /** The number of points in the polygon.  */
    public int npoints;
  
    /** The x coordinates of the points.  */
    public int[] xpoints;
  
    /** The y coordinates of the points.  */
    public int[] ypoints;
  
    /** Create a new, empty Polygon.  */
    public Polygon ()
    {
      this.xpoints = new int[0];
      this.ypoints = new int[0];
      this.npoints = 0;
    }
  
    /** Create a new Polygon from the given vertices.
     * @param xpoints The x coordinates
     * @param ypoints The y coordinates
     * @param npoints The number of points
     */
    public Polygon (int[] xpoints, int[] ypoints, int npoints)
    {
      // We make explicit copies instead of relying on clone so that we
      // ensure the new arrays are the same size.
      this.xpoints = new int[npoints];
      this.ypoints = new int[npoints];
      System.arraycopy (xpoints, 0, this.xpoints, 0, npoints);
      System.arraycopy (ypoints, 0, this.ypoints, 0, npoints);
    }
  
    /** Append the specified point to this Polygon.
     * @param x The x coordinate
     * @param y The y coordinate
     */
    public void addPoint (int x, int y)
    {
      int[] newx = new int[npoints + 1];
      System.arraycopy (xpoints, 0, newx, 0, npoints);
      int[] newy = new int[npoints + 1];
      System.arraycopy (ypoints, 0, newy, 0, npoints);
      newx[npoints] = x;
      newy[npoints] = y;
      ++npoints;
      xpoints = newx;
      ypoints = newy;
  
      // It is simpler to just recompute.
      if (bounds != null)
        computeBoundingBox ();
    }
  
    /** Return true if the indicated point is inside this Polygon.
     * This uses an even-odd rule to determine insideness.
     * @param x The x coordinate
     * @param y The y coordinate
     * @returns true if the point is contained by this Polygon.
     */
    public boolean contains (double x, double y)
    {
      // What we do is look at each line segment.  If the line segment
      // crosses the "scan line" at y at a point x' < x, then we
      // increment our counter.  At the end, an even number means the
      // point is outside the polygon.  Instead of a number, though, we
      // use a boolean.
      boolean inside = false;
      for (int i = 0; i < npoints; ++i)
        {
  	// Handle the wrap case.
  	int x2 = (i == npoints) ? xpoints[0] : xpoints[i + 1];
  	int y2 = (i == npoints) ? ypoints[0] : ypoints[i + 1];
  
  	if (ypoints[i] == y2)
  	  {
  	    // We ignore horizontal lines.  This might give weird
  	    // results in some situations -- ?
  	    continue;
  	  }
  
  	double t = (y - ypoints[i]) / (double) (y2 - ypoints[i]);
  	double x3 = xpoints[i] + t * (x2 - xpoints[i]);
  	if (x3 < x)
  	  inside = ! inside;
        }
  
      return inside;
    }
  
    /** Return true if the indicated rectangle is entirely inside this
     * Polygon.
     * This uses an even-odd rule to determine insideness.
     * @param x The x coordinate
     * @param y The y coordinate
     * @param w The width
     * @param h The height
     * @returns true if the rectangle is contained by this Polygon.
     */
    public boolean contains (double x, double y, double w, double h)
    {
      return intersectOrContains (x, y, w, h, false);
    }
  
    /** Return true if the indicated point is inside this Polygon.
     * This uses an even-odd rule to determine insideness.
     * @param x The x coordinate
     * @param y The y coordinate
     * @returns true if the point is contained by this Polygon.
     */
    public boolean contains (int x, int y)
    {
      return contains ((double) x, (double) y);
    }
  
    /** Return true if the indicated point is inside this Polygon.
     * This uses an even-odd rule to determine insideness.
     * @param p The point
     * @returns true if the point is contained by this Polygon.
     */
    public boolean contains (Point p)
    {
      return contains (p.x, p.y);
    }
  
    /** Return true if the indicated point is inside this Polygon.
     * This uses an even-odd rule to determine insideness.
     * @param p The point
     * @returns true if the point is contained by this Polygon.
     */
    public boolean contains (Point2D p)
    {
      return contains (p.getX (), p.getY ());
    }
  
    /** Return true if the indicated rectangle is entirely inside this
     * Polygon.  This uses an even-odd rule to determine insideness.
     * @param r The rectangle
     * @returns true if the rectangle is contained by this Polygon.
     */
    public boolean contains (Rectangle2D r)
    {
      return contains (r.getX (), r.getY (), r.getWidth (), r.getHeight ());
    }
  
    /** Returns the bounds of this Polygon.
     * @deprecated Use getBounds() instead.
     */
    public Rectangle getBoundingBox ()
    {
      if (bounds == null)
        computeBoundingBox ();
      return bounds;
    }
  
    /** Returns the bounds of this Polygon.  */
    public Rectangle getBounds ()
    {
      if (bounds == null)
        computeBoundingBox ();
      return bounds;
    }
  
    /** Returns the bounds of this Polygon.  */
    public Rectangle2D getBounds2D ()
    {
      if (bounds == null)
        computeBoundingBox ();
      return bounds;		// Why not?
    }
  
    /** Return an iterator for the boundary of this Polygon.
     * @param at A transform to apply to the coordinates.
     * @returns A path iterator for the Polygon's boundary.
     */
    public PathIterator getPathIterator (AffineTransform at)
    {
      return new Iterator (at);
    }
  
    /** Return an iterator for the boundary of this Polygon.
     * @param at A transform to apply to the coordinates.
     * @param flatness The flatness of the result; it is ignored by
     *                 this class.
     * @returns A path iterator for the Polygon's boundary.
     */
    public PathIterator getPathIterator (AffineTransform at, double flatness)
    {
      // We ignore the flatness.
      return new Iterator (at);
    }
  
    /** @deprecated use contains(int,int).  */
    public boolean inside (int x, int y)
    {
      return contains (x, y);
    }
  
    /** Return true if this Polygon's interior intersects the given
     * rectangle's interior.
     * @param x The x coordinate
     * @param y The y coordinate
     * @param w The width
     * @param h The height
     */
    public boolean intersects (double x, double y, double w, double h)
    {
      return intersectOrContains (x, y, w, h, true);
    }
  
    /** Return true if this Polygon's interior intersects the given
     * rectangle's interior.
     * @param r The rectangle
     */
    public boolean intersects (Rectangle2D r)
    {
      return intersects (r.getX (), r.getY (), r.getWidth (), r.getHeight ());
    }
  
    // This tests for intersection with or containment of a rectangle,
    // depending on the INTERSECT argument.
    private boolean intersectOrContains (double x, double y, double w, double h,
  				       boolean intersect)
    {
      // First compute the rectangle of possible intersection points.
      Rectangle r = getBounds ();
      int minx = Math.max (r.x, (int) x);
      int maxx = Math.min (r.x + r.width, (int) (x + w));
      int miny = Math.max (r.y, (int) y);
      int maxy = Math.min (r.y + r.height, (int) (y + h));
  
      if (miny > maxy)
        return false;
  
      double[] crosses = new double[npoints + 1];
  
      for (; miny < maxy; ++miny)
        {
  	// First compute every place where the polygon might intersect
  	// the scan line at Y.
  	int ins = 0;
  	for (int i = 0; i < npoints; ++i)
  	  {
  	    // Handle the wrap case.
  	    int x2 = (i == npoints) ? xpoints[0] : xpoints[i + 1];
  	    int y2 = (i == npoints) ? ypoints[0] : ypoints[i + 1];
  
  	    if (ypoints[i] == y2)
  	      {
  		// We ignore horizontal lines.  This might give weird
  		// results in some situations -- ?
  		continue;
  	      }
  
  	    double t = (((double) miny - ypoints[i])
  			/ (double) (y2 - ypoints[i]));
  	    double x3 = xpoints[i] + t * (x2 - xpoints[i]);
  	    crosses[ins++] = x3;
  	  }
  
  	// Now we can sort into increasing order and look to see if
  	// any point in the rectangle is in the polygon.  We examine
  	// every other pair due to our even-odd rule.
  	Arrays.sort (crosses, 0, ins);
  	int i = intersect ? 0 : 1;
  	for (; i < ins - 1; i += 2)
  	  {
  	    // Pathological case.
  	    if (crosses[i] == crosses[i + 1])
  	      continue;
  
  	    // Found a point on the inside.
  	    if ((crosses[i] >= x && crosses[i] < x + w)
  		|| (crosses[i + 1] >= x && crosses[i + 1] < x + w))
  	      {
  		// If we're checking containment then we just lost.
  		// But if we're checking intersection then we just
  		// won.
  		return intersect;
  	      }
  	  }
        }
  
      return false;
    }
  
    /** Translates all the vertices of the polygon via a given vector.
     * @param deltaX The X offset
     * @param deltaY The Y offset
     */
    public void translate (int deltaX, int deltaY)
    {
      for (int i = 0; i < npoints; ++i)
        {
  	xpoints[i] += deltaX;
  	ypoints[i] += deltaY;
        }
  
      if (bounds != null)
        {
  	bounds.x += deltaX;
  	bounds.y += deltaY;
        }
    }
  
    // This computes the bounding box if required.
    private void computeBoundingBox ()
    {
      if (npoints == 0)
        {
  	// This is wrong if the user adds a new point, but we
  	// account for that in addPoint().
  	bounds = new Rectangle (0, 0, 0, 0);
        }
      else
        {
  	int maxx = xpoints[0];
  	int minx = xpoints[0];
  	int maxy = ypoints[0];
  	int miny = ypoints[0];
  
  	for (int i = 1; i < npoints; ++i)
  	  {
  	    maxx = Math.max (maxx, xpoints[i]);
  	    minx = Math.min (minx, xpoints[i]);
  	    maxy = Math.max (maxy, ypoints[i]);
  	    miny = Math.min (miny, ypoints[i]);
  	  }
  
  