📄 arc2d.java
字号:
} double normy = (y - getY()) / ellh - 0.5; double distSq = (normx * normx + normy * normy); if (distSq >= 0.25) { return false; } double angExt = Math.abs(getAngleExtent()); if (angExt >= 360.0) { return true; } boolean inarc = containsAngle(-Math.toDegrees(Math.atan2(normy, normx))); if (type == PIE) { return inarc; } // CHORD and OPEN behave the same way if (inarc) { if (angExt >= 180.0) { return true; } // point must be outside the "pie triangle" } else { if (angExt <= 180.0) { return false; } // point must be inside the "pie triangle" } // The point is inside the pie triangle iff it is on the same // side of the line connecting the ends of the arc as the center. double angle = Math.toRadians(-getAngleStart()); double x1 = Math.cos(angle); double y1 = Math.sin(angle); angle += Math.toRadians(-getAngleExtent()); double x2 = Math.cos(angle); double y2 = Math.sin(angle); boolean inside = (Line2D.relativeCCW(x1, y1, x2, y2, x, y) * Line2D.relativeCCW(x1, y1, x2, y2, 0, 0) >= 0); return inarc ? !inside : inside; } /** * Determines whether or not the interior of the arc intersects * the interior of the specified rectangle. * * @param x, y The coordinates of the rectangle's upper left corner. * (Specified in double precision.) * @param w The width of the rectangle. (Specified in double precision.) * @param h The height of the rectangle. (Specified in double precision.) * * @return <CODE>true</CODE> if the arc intersects the rectangle, * <CODE>false</CODE> if the arc doesn't intersect the rectangle. */ public boolean intersects(double x, double y, double w, double h) { /* * REMIND: Verify correct handling of "upside down angles". */ /* Change around so that is really works this time We check each of the four line segments for intersection with an ellipse of the same radius as the imaginary arc. We then compute the angle of the intersections and call included angle to find out if the intersection is within the arc itself - Aaron Muderick */ double intersect_angle; double yint, xint; //if there are any points of the rect in the arc then return true; if (contains(x, y) || contains(x + w, y) || contains(x, y + h) || contains(x + w, y + h)) return true; //we need to translate the arc and the rect so that we can do //quadrant checking x = x - (getX() + (getWidth()/2)); y = (y - (getY() + (getHeight()/2))) * (-1); //find out the squash ratio double squash = getWidth()/getHeight(); if (((x*x)/((getWidth()/2)*(getWidth()/2)) < 1)) { if ((x == 0) && ((((getHeight()/2) >= (y-h)) && ((getHeight()/2) <= y)) || ((((-1) * (getHeight()/2)) >= (y-h)) && (((-1) * (getHeight()/2) <= y))))) { if (containsAngle(Math.PI/2)) { return true; } if (containsAngle(Math.PI*(3/2))) { return true; } } yint = Math.abs(Math.sqrt((1-((x*x)/((getWidth()/2)*(getWidth()/2)))) *((getHeight()/2)*(getHeight()/2)))); intersect_angle = Math.abs(Math.atan((yint*squash)/x)); if ((x > 0) && (((yint >= (y-h)) && (yint <= y)) || ((((-1) * yint) >= (y-h)) && (((-1) * yint) <= y)))) { if (containsAngle(intersect_angle/Math.PI * 180)) { return true; } if (containsAngle((((2*Math.PI) - intersect_angle)/Math.PI) * 180)) { return true; } } if ((x < 0) && (((yint >= (y-h)) && (yint <= y)) || ((((-1) * yint) >= (y-h)) && (((-1) * yint) <= y)))){ if (containsAngle((((Math.PI) - intersect_angle)/Math.PI) * 180)) { return true; } if (containsAngle(((Math.PI + intersect_angle)/Math.PI) * 180)) { return true; } } } if ((((x+w)*(x+w))/((getWidth()/2)*(getWidth()/2)) < 1)) { if (((x+w) == 0) && ((((getHeight()/2) >= (y-h)) && ((getHeight()/2) <= y)) || ((((-1) * (getHeight()/2)) >= (y-h)) && (((-1) * (getHeight()/2) <= y))))) { if (containsAngle(Math.PI/2)) { return true; } if (containsAngle(Math.PI*(3/2))) { return true; } } yint = Math.abs(Math.sqrt((1-(((x+w)*(x+w)) /((getWidth()/2)*(getWidth()/2)))) *((getHeight()/2)*(getHeight()/2)))); intersect_angle = Math.abs(Math.atan((yint*squash)/(x+w))); if (((x+w) > 0) && (((yint >= (y-h)) && (yint <= y)) || ((((-1) * yint) >= (y-h)) && (((-1) * yint) <= y)))) { if (containsAngle((intersect_angle/Math.PI) * 180)) { return true; } if (containsAngle((((2*Math.PI) - intersect_angle)/Math.PI) * 180)) { return true; } } if (((x+w) < 0) && (((yint >= (y-h)) && (yint <= y)) || ((((-1) * yint) >= (y-h)) && (((-1) * yint) <= y)))) { if (containsAngle((((Math.PI) - intersect_angle)/Math.PI) * 180)) { return true; } if (containsAngle(((Math.PI + intersect_angle)/Math.PI) * 180)) { return true; } } } if (((y*y)/((getHeight()/2)*(getHeight()/2)) < 1)) { if ((y == 0) && ((((getWidth()/2) >= x) && ((getWidth()/2) <= (x+w))) || ((((-1) * (getWidth()/2)) >= x) && (((-1) * (getWidth()/2)) <= (x+w))))) { if (containsAngle(Math.PI)) { return true; } if (containsAngle(Math.PI*2)) { return true; } } xint = Math.abs(Math.sqrt((1-((y*y) /((getHeight()/2) *(getHeight()/2)))) *((getWidth()/2)*(getWidth()/2)))); intersect_angle = Math.abs(Math.atan(y/(xint/squash))); if ((y > 0) && (((xint >= x) && (xint <= (x+w))) || ((((-1) * xint) >= x) && (((-1) * xint) <= (x+w))))) { if (containsAngle((intersect_angle)/Math.PI * 180)) { return true; } if (containsAngle(((Math.PI) - intersect_angle)/Math.PI * 180)) { return true; } } if ((y < 0) && (((xint >= x) && (xint <= (x+w))) || ((((-1) * xint) >= x) && (((-1) * xint) <= (x+w))))) { if (containsAngle(((Math.PI*2) - intersect_angle)/Math.PI * 180)) { return true; } if (containsAngle((Math.PI + intersect_angle)/Math.PI * 180)) { return true; } } } if ((((y-h)*(y-h))/((getHeight()/2)*(getHeight()/2)) < 1)) { if (((y-h) == 0) && ((((getWidth()/2) >= x) && ((getWidth()/2) <= (x+w))) || ((((-1) * (getWidth()/2)) >= x) && (((-1) * (getWidth()/2)) <= (x+w))))) { if (containsAngle(Math.PI)) { return true; } if (containsAngle(Math.PI*2)) { return true; } } xint = Math.abs(Math.sqrt((1-(((y-h)*(y-h)) /((getHeight()/2)*(getHeight()/2)))) *((getWidth()/2)*(getWidth()/2)))); intersect_angle = Math.abs(Math.atan((y-h)/(xint/squash))); if (((y-h) > 0) && (((xint >= x) && (xint <= (x+w))) || ((((-1) * xint) >= x) && (((-1) * xint) <= (x+w))))) { if (containsAngle(intersect_angle/Math.PI * 180)) { return true; } if (containsAngle(((Math.PI) - intersect_angle)/Math.PI * 180)) { return true; } } if (((y-h) < 0) && (((xint >= x) && (xint <= (x+w))) || ((((-1) * xint) >= x) && (((-1) * xint) <= (x+w))))) { if (containsAngle(((Math.PI*2) - intersect_angle)/Math.PI * 180)) { return true; } if (containsAngle((Math.PI + intersect_angle)/Math.PI * 180)) { return true; } } } return false; } /** * Determine whether or not the interior of the arc entirely contains * the specified rectangle. * * @param x, y The coordinates of the rectangle's upper left corner. * (Specified in double precision.) * @param w The width of the rectangle. (Specified in double precision.) * @param h The height of the rectangle. (Specified in double precision.) * * @return <CODE>true</CODE> if the arc contains the rectangle, * <CODE>false</CODE> if the arc doesn't contain the rectangle. */ public boolean contains(double x, double y, double w, double h) { return contains(x, y, w, h, null); } /** * Determine whether or not the interior of the arc entirely contains * the specified rectangle. * * @param r The <CODE>Rectangle2D</CODE> to test. * * @return <CODE>true</CODE> if the arc contains the rectangle, * <CODE>false</CODE> if the arc doesn't contain the rectangle. */ public boolean contains(Rectangle2D r) { return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight(), r); } private boolean contains(double x, double y, double w, double h, Rectangle2D origrect) { if (!(contains(x, y) && contains(x + w, y) && contains(x, y + h) && contains(x + w, y + h))) { return false; } // If the shape is convex then we have done all the testing // we need. Only PIE arcs can be concave and then only if // the angular extents are greater than 180 degrees. if (type != PIE || getAngleExtent() <= 180.0) { return true; } // For a PIE shape we have an additional test for the case where // the angular extents are greater than 180 degrees and all four // rectangular corners are inside the shape but one of the // rectangle edges spans across the "missing wedge" of the arc. // We can test for this case by checking if the rectangle intersects // either of the pie angle segments. if (origrect == null) { origrect = new Rectangle2D.Double(x, y, w, h); } double halfW = getWidth() / 2.0; double halfH = getHeight() / 2.0; double xc = getX() + halfW; double yc = getY() + halfH; double angle = Math.toRadians(-getAngleStart()); double xe = xc + halfW * Math.cos(angle); double ye = yc + halfH * Math.sin(angle); if (origrect.intersectsLine(xc, yc, xe, ye)) { return false; } angle += Math.toRadians(-getAngleExtent()); xe = xc + halfW * Math.cos(angle); ye = yc + halfH * Math.sin(angle); return !origrect.intersectsLine(xc, yc, xe, ye); } /** * Returns an iteration object that defines the boundary of the * arc. * This iterator is multithread safe. * <code>Arc2D</code> guarantees that * modifications to the geometry of the arc * do not affect any iterations of that geometry that * are already in process. * * @param at an optional <CODE>AffineTransform</CODE> to be applied * to the coordinates as they are returned in the iteration, or null * if the untransformed coordinates are desired. * * @return A <CODE>PathIterator</CODE> that defines the arc's boundary. */ public PathIterator getPathIterator(AffineTransform at) { return new ArcIterator(this, at); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -