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

📄 generalpath.java

📁 gcc的组建
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
   * within the path, <code>false</code> otherwise   */  public boolean contains(Rectangle2D r)  {    return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());  }  /**   * Evaluates if a rectangle intersects the path.   * @param x x coordinate of the rectangle   * @param y y coordinate of the rectangle   * @param w width of the rectangle   * @param h height of the rectangle   * @return <code>true</code> if the rectangle intersects the path,   * <code>false</code> otherwise   */  public boolean intersects(double x, double y, double w, double h)  {    /* Does any edge intersect? */    if (getAxisIntersections(x, y, false, w) != 0 /* top */        || getAxisIntersections(x, y + h, false, w) != 0 /* bottom */        || getAxisIntersections(x + w, y, true, h) != 0 /* right */        || getAxisIntersections(x, y, true, h) != 0) /* left */      return true;    /* No intersections, is any point inside? */    if (getWindingNumber(x, y) != 0)      return true;    return false;  }  /**   * Evaluates if a Rectangle2D intersects the path.   * @param r The rectangle   * @return <code>true</code> if the rectangle intersects the path,   * <code>false</code> otherwise   */  public boolean intersects(Rectangle2D r)  {    return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());  }  /**   * A PathIterator that iterates over the segments of a GeneralPath.   *   * @author Sascha Brawer (brawer@dandelis.ch)   */  private static class GeneralPathIterator implements PathIterator  {    /**     * The number of coordinate values for each segment type.     */    private static final int[] NUM_COORDS = {                                             /* 0: SEG_MOVETO */ 1,                                             /* 1: SEG_LINETO */ 1,                                             /* 2: SEG_QUADTO */ 2,                                             /* 3: SEG_CUBICTO */ 3,                                             /* 4: SEG_CLOSE */ 0};    /**     * The GeneralPath whose segments are being iterated.     * This is package-private to avoid an accessor method.     */    final GeneralPath path;    /**     * The affine transformation used to transform coordinates.     */    private final AffineTransform transform;    /**     * The current position of the iterator.     */    private int pos;    /**     * Constructs a new iterator for enumerating the segments of a     * GeneralPath.     *     * @param path the path to enumerate     * @param transform an affine transformation for projecting the returned     * points, or <code>null</code> to return the original points     * without any mapping.     */    GeneralPathIterator(GeneralPath path, AffineTransform transform)    {      this.path = path;      this.transform = transform;    }    /**     * Returns the current winding rule of the GeneralPath.     */    public int getWindingRule()    {      return path.rule;    }    /**     * Determines whether the iterator has reached the last segment in     * the path.     */    public boolean isDone()    {      return pos >= path.index;    }    /**     * Advances the iterator position by one segment.     */    public void next()    {      int seg;      /*       * Increment pos by the number of coordinate pairs.       */      seg = path.types[pos];      if (seg == SEG_CLOSE)	pos++;      else	pos += NUM_COORDS[seg];    }    /**     * Returns the current segment in float coordinates.     */    public int currentSegment(float[] coords)    {      int seg;      int numCoords;      seg = path.types[pos];      numCoords = NUM_COORDS[seg];      if (numCoords > 0)        {	  for (int i = 0; i < numCoords; i++)	    {	      coords[i << 1] = path.xpoints[pos + i];	      coords[(i << 1) + 1] = path.ypoints[pos + i];	    }	  if (transform != null)	    transform.transform( /* src */	    coords, /* srcOffset */	    0, /* dest */ coords, /* destOffset */	    0, /* numPoints */ numCoords);        }      return seg;    }    /**     * Returns the current segment in double coordinates.     */    public int currentSegment(double[] coords)    {      int seg;      int numCoords;      seg = path.types[pos];      numCoords = NUM_COORDS[seg];      if (numCoords > 0)        {	  for (int i = 0; i < numCoords; i++)	    {	      coords[i << 1] = (double) path.xpoints[pos + i];	      coords[(i << 1) + 1] = (double) path.ypoints[pos + i];	    }	  if (transform != null)	    transform.transform( /* src */	    coords, /* srcOffset */	    0, /* dest */ coords, /* destOffset */	    0, /* numPoints */ numCoords);        }      return seg;    }  }  /**   * Creates a PathIterator for iterating along the segments of the path.   *   * @param at an affine transformation for projecting the returned   * points, or <code>null</code> to let the created iterator return   * the original points without any mapping.   */  public PathIterator getPathIterator(AffineTransform at)  {    return new GeneralPathIterator(this, at);  }  /**   * Creates a new FlatteningPathIterator for the path   */  public PathIterator getPathIterator(AffineTransform at, double flatness)  {    return new FlatteningPathIterator(getPathIterator(at), flatness);  }  /**   * Creates a new shape of the same run-time type with the same contents    * as this one.   *   * @return the clone   *   * @exception OutOfMemoryError If there is not enough memory available.   *   * @since 1.2   */  public Object clone()  {    // This class is final; no need to use super.clone().    return new GeneralPath(this);  }  /**   * Helper method - ensure the size of the data arrays,   * otherwise, reallocate new ones twice the size   */  private void ensureSize(int size)  {    if (subpath < 0)      throw new IllegalPathStateException("need initial moveto");    if (size <= xpoints.length)      return;    byte[] b = new byte[types.length << 1];    System.arraycopy(types, 0, b, 0, index);    types = b;    float[] f = new float[xpoints.length << 1];    System.arraycopy(xpoints, 0, f, 0, index);    xpoints = f;    f = new float[ypoints.length << 1];    System.arraycopy(ypoints, 0, f, 0, index);    ypoints = f;  }  /**   * Helper method - Get the total number of intersections from (x,y) along    * a given axis, within a given distance.   */  private int getAxisIntersections(double x, double y, boolean useYaxis,                                   double distance)  {    return (evaluateCrossings(x, y, false, useYaxis, distance));  }  /**   * Helper method - returns the winding number of a point.   */  private int getWindingNumber(double x, double y)  {    /* Evaluate the crossings from x,y to infinity on the y axis (arbitrary        choice). Note that we don't actually use Double.INFINITY, since that's        slower, and may cause problems. */    return (evaluateCrossings(x, y, true, true, BIG_VALUE));  }  /**   * Helper method - evaluates the number of intersections on an axis from    * the point (x,y) to the point (x,y+distance) or (x+distance,y).   * @param x x coordinate.   * @param y y coordinate.   * @param neg True if opposite-directed intersections should cancel,    * false to sum all intersections.   * @param useYaxis Use the Y axis, false uses the X axis.   * @param distance Interval from (x,y) on the selected axis to find    * intersections.   */  private int evaluateCrossings(double x, double y, boolean neg,                                boolean useYaxis, double distance)  {    float cx = 0.0f;    float cy = 0.0f;    float firstx = 0.0f;    float firsty = 0.0f;    int negative = (neg) ? -1 : 1;    double x0;    double x1;    double x2;    double x3;    double y0;    double y1;    double y2;    double y3;    double[] r = new double[4];    int nRoots;    double epsilon = 0.0;    int pos = 0;    int windingNumber = 0;    boolean pathStarted = false;    if (index == 0)      return (0);    if (useYaxis)      {	float[] swap1;	swap1 = ypoints;	ypoints = xpoints;	xpoints = swap1;	double swap2;	swap2 = y;	y = x;	x = swap2;      }    /* Get a value which is hopefully small but not insignificant relative     the path. */    epsilon = ypoints[0] * 1E-7;    if(epsilon == 0)       epsilon = 1E-7;    pos = 0;    while (pos < index)      {	switch (types[pos])	  {	  case PathIterator.SEG_MOVETO:	    if (pathStarted) // close old path	      {		x0 = cx;		y0 = cy;		x1 = firstx;		y1 = firsty;		if (y0 == 0.0)		  y0 -= epsilon;		if (y1 == 0.0)		  y1 -= epsilon;		if (Line2D.linesIntersect(x0, y0, x1, y1, 					  epsilon, 0.0, distance, 0.0))		  windingNumber += (y1 < y0) ? 1 : negative;		cx = firstx;		cy = firsty;	      }	    cx = firstx = xpoints[pos] - (float) x;	    cy = firsty = ypoints[pos++] - (float) y;	    pathStarted = true;	    break;	  case PathIterator.SEG_CLOSE:	    x0 = cx;	    y0 = cy;	    x1 = firstx;	    y1 = firsty;	    if (y0 == 0.0)	      y0 -= epsilon;	    if (y1 == 0.0)	      y1 -= epsilon;	    if (Line2D.linesIntersect(x0, y0, x1, y1, 				      epsilon, 0.0, distance, 0.0))	      windingNumber += (y1 < y0) ? 1 : negative;	    cx = firstx;	    cy = firsty;	    pos++;	    pathStarted = false;	    break;	  case PathIterator.SEG_LINETO:	    x0 = cx;	    y0 = cy;	    x1 = xpoints[pos] - (float) x;	    y1 = ypoints[pos++] - (float) y;	    if (y0 == 0.0)	      y0 -= epsilon;	    if (y1 == 0.0)	      y1 -= epsilon;	    if (Line2D.linesIntersect(x0, y0, x1, y1, 				      epsilon, 0.0, distance, 0.0))	      windingNumber += (y1 < y0) ? 1 : negative;	    cx = xpoints[pos - 1] - (float) x;	    cy = ypoints[pos - 1] - (float) y;	    break;	  case PathIterator.SEG_QUADTO:	    x0 = cx;	    y0 = cy;	    x1 = xpoints[pos] - x;	    y1 = ypoints[pos++] - y;	    x2 = xpoints[pos] - x;	    y2 = ypoints[pos++] - y;	    /* 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);		/* degenerate roots (=tangent points) do not		   contribute to the winding number. */		if ((nRoots = QuadCurve2D.solveQuadratic(r)) == 2)		  for (int i = 0; i < nRoots; i++)		    {		      float t = (float) r[i];		      if (t > 0.0f && t < 1.0f)		        {			  double crossing = t * t * (x2 - 2 * x1 + x0)			                    + 2 * t * (x1 - x0) + x0;			  if (crossing >= 0.0 && crossing <= distance)			    windingNumber += (2 * t * (y2 - 2 * y1 + y0)			                   + 2 * (y1 - y0) < 0) ? 1 : negative;		        }		    }	      }	    cx = xpoints[pos - 1] - (float) x;	    cy = ypoints[pos - 1] - (float) y;	    break;	  case PathIterator.SEG_CUBICTO:	    x0 = cx;	    y0 = cy;	    x1 = xpoints[pos] - x;	    y1 = ypoints[pos++] - y;	    x2 = xpoints[pos] - x;	    y2 = ypoints[pos++] - y;	    x3 = xpoints[pos] - x;	    y3 = ypoints[pos++] - y;	    /* 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++)		    {		      float t = (float) r[i];		      if (t > 0.0 && t < 1.0)		        {			  double crossing = -(t * t * t) * (x0 - 3 * x1			                    + 3 * x2 - x3)			                    + 3 * t * t * (x0 - 2 * x1 + x2)			                    + 3 * t * (x1 - x0) + x0;			  if (crossing >= 0 && crossing <= distance)			    windingNumber += (3 * t * t * (y3 + 3 * y1			                     - 3 * y2 - y0)			                     + 6 * t * (y0 - 2 * y1 + y2)			                   + 3 * (y1 - y0) < 0) ? 1 : negative;		        }		    }	      }	    cx = xpoints[pos - 1] - (float) x;	    cy = ypoints[pos - 1] - (float) y;	    break;	  }      }    // swap coordinates back    if (useYaxis)      {	float[] swap;	swap = ypoints;	ypoints = xpoints;	xpoints = swap;      }    return (windingNumber);  }} // class GeneralPath

⌨️ 快捷键说明

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