⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 area.java

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
	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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -