📄 polybase.java
字号:
// FALLTHROUGH } if (localStyle == Poly.Type.CLOSED) { // check outline of description double bestDist = Double.MAX_VALUE; Point2D bestPoint = new Point2D.Double(); for(int i=0; i<points.length; i++) { int lastI; if (i == 0) lastI = points.length-1; else lastI = i-1; Point2D pc = DBMath.closestPointToSegment(points[lastI], points[i], pt); double dist = pc.distance(pt); if (dist > bestDist) continue; bestDist = dist; bestPoint.setLocation(pc); } return bestPoint; } if (localStyle == Poly.Type.OPENED || localStyle == Poly.Type.OPENEDT1 || localStyle == Poly.Type.OPENEDT2 || localStyle == Poly.Type.OPENEDT3) { // check outline of description double bestDist = Double.MAX_VALUE; Point2D bestPoint = new Point2D.Double(); for(int i=1; i<points.length; i++) { Point2D pc = DBMath.closestPointToSegment(points[i-1], points[i], pt); double dist = pc.distance(pt); if (dist > bestDist) continue; bestDist = dist; bestPoint.setLocation(pc); } return bestPoint; } if (localStyle == Poly.Type.VECTORS) { // check outline of description double bestDist = Double.MAX_VALUE; Point2D bestPoint = new Point2D.Double(); for(int i=0; i<points.length; i += 2) { Point2D pc = DBMath.closestPointToSegment(points[i], points[i+1], pt); double dist = pc.distance(pt); if (dist > bestDist) continue; bestDist = dist; bestPoint.setLocation(pc); } return bestPoint; } // presume single-point polygon and use the center Rectangle2D bounds = getBounds2D(); return new Point2D.Double(bounds.getCenterX(), bounds.getCenterY()); } /** * Method to tell whether a point is inside of this Poly. * This method is a requirement of the Shape implementation. * @param x the X coordinate of the point. * @param y the Y coordinate of the point. * @return true if the point is inside the Poly. */ public boolean contains(double x, double y) { return isInside(new Point2D.Double(x, y)); } /** * Method to tell whether a point is inside of this Poly. * This method is a requirement of the Shape implementation. * @param p the point. * @return true if the point is inside the Poly. */ public boolean contains(Point2D p) { return isInside(p); } /** * Method to tell whether a rectangle is inside of this Poly. * This method is a requirement of the Shape implementation. * @param lX the X corner of the rectangle. * @param lY the Y corner of the rectangle. * @param w the width of the rectangle. * @param h the height of the rectangle. * @return true if the rectangle is inside the Poly. */ public boolean contains(double lX, double lY, double w, double h) { // first ensure all rectangle corners are inside of the polygon double hX = lX + w; double hY = lY + h; if (!isInside(new Point2D.Double(lX, lY)) || !isInside(new Point2D.Double(hX, lY)) || !isInside(new Point2D.Double(lX, hY)) || !isInside(new Point2D.Double(hX, hY))) return false; // because nonconvex polygons may pierce rectangle, check all edges for(int i=0; i<points.length; i++) { // get a polygon edge int last = i-1; if (last < 0) last = points.length-1; Point2D thisPt = new Point2D.Double(points[i].getX(), points[i].getY()); Point2D lastPt = new Point2D.Double(points[last].getX(), points[last].getY()); // if the edge is completely outside of the rectangle, it is OK boolean invisible = GenMath.clipLine(lastPt, thisPt, lX, hX, lY, hY); if (invisible) continue; // if the polygon edge line was not completely clipped, it must sit on the rectangle edge if (lastPt.getX() == thisPt.getX()) { if (lastPt.getY() == thisPt.getY()) { if (thisPt.getX() <= lX || thisPt.getX() >= hX || thisPt.getY() <= lY || thisPt.getY() >= hY) continue; } else { if (thisPt.getX() <= lX || thisPt.getX() >= hX) continue; } } if (lastPt.getY() == thisPt.getY()) { if (thisPt.getY() <= lY || thisPt.getY() >= hY) continue; } // polygon edge is inside of rectangle: no containment return false; } // all edges pass: rectangle is contained return true; } /** * Method to tell whether a rectangle is inside of this Poly. * This method is a requirement of the Shape implementation. * @param r the rectangle. * @return true if the rectangle is inside the Poly. */ public boolean contains(Rectangle2D r) { return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight()); } /** * Method to tell whether a rectangle intersects this Poly. * This method is a requirement of the Shape implementation. * THIS METHOD HAS NOT BEEN WRITTEN YET!!! * @param x the X corner of the rectangle. * @param y the Y corner of the rectangle. * @param w the width of the rectangle. * @param h the height of the rectangle. * @return true if the rectangle intersects the Poly. */ public boolean intersects(double x, double y, double w, double h) { throw new Error("intersects method not implemented in Poly.intersects()"); //return false; } /** * Method to tell whether a rectangle intersects this Poly. * This method is a requirement of the Shape implementation. * THIS METHOD HAS NOT BEEN WRITTEN YET!!! * @param r the rectangle. * @return true if the rectangle intersects the Poly. */ public boolean intersects(Rectangle2D r) { return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight()); } /** * Method to tell whether this Poly intersects another one. * @param polyOther the other Poly to test. * @return true if polygons intersect (that is, if any of their lines intersect). */ public boolean intersects(PolyBase polyOther) { // quit now if bounding boxes don't overlap Rectangle2D thisBounds = getBounds2D(); Rectangle2D otherBounds = polyOther.getBounds2D(); if (thisBounds.getMaxX() < otherBounds.getMinX() || otherBounds.getMaxX() < thisBounds.getMinX() || thisBounds.getMaxY() < otherBounds.getMinY() || otherBounds.getMaxY() < thisBounds.getMinY()) return false; // check each line in this Poly int count = points.length; for(int i=0; i<count; i++) { Point2D p; if (i == 0) { if (style == Poly.Type.OPENED || style == Poly.Type.OPENEDT1 || style == Poly.Type.OPENEDT2 || style == Poly.Type.OPENEDT3 || style == Poly.Type.VECTORS) continue; p = points[count-1]; } else { p = points[i-1]; } Point2D t = points[i]; if (style == Poly.Type.VECTORS && (i&1) != 0) i++; if (p.getX() == t.getX() && p.getY() == t.getY()) continue; // compare this line with the other Poly if (Math.min(p.getX(),t.getX()) > otherBounds.getMaxX() || Math.max(p.getX(),t.getX()) < otherBounds.getMinX() || Math.min(p.getY(),t.getY()) > otherBounds.getMaxY() || Math.max(p.getY(),t.getY()) < otherBounds.getMinY()) continue; if (polyOther.lineIntersect(p, t)) return true; } return false; } /** * Method to return true if the line segment from (px1,py1) to (tx1,ty1) * intersects any line in polygon "poly" */ private boolean lineIntersect(Point2D p1, Point2D t1) { int count = points.length; for(int i=0; i<count; i++) { Point2D p2; if (i == 0) { if (style == Poly.Type.OPENED || style == Poly.Type.OPENEDT1 || style == Poly.Type.OPENEDT2 || style == Poly.Type.OPENEDT3 || style == Poly.Type.VECTORS) continue; p2 = points[count-1]; } else { p2 = points[i-1]; } Point2D t2 = points[i]; if (style == Poly.Type.VECTORS && (i&1) != 0) i++; // simple test: if it hit one of the points, it is an intersection if (t2.getX() == p1.getX() && t2.getY() == p1.getY()) return true; if (t2.getX() == t1.getX() && t2.getY() == t1.getY()) return true; // ignore zero-size segments if (p2.getX() == t2.getX() && p2.getY() == t2.getY()) continue; // special case: this line is vertical if (p2.getX() == t2.getX()) { // simple bounds check if (Math.min(p1.getX(),t1.getX()) > p2.getX() || Math.max(p1.getX(),t1.getX()) < p2.getX()) continue; if (p1.getX() == t1.getX()) { if (Math.min(p1.getY(),t1.getY()) > Math.max(p2.getY(),t2.getY()) || Math.max(p1.getY(),t1.getY()) < Math.min(p2.getY(),t2.getY())) continue; return true; } if (p1.getY() == t1.getY()) { if (Math.min(p2.getY(),t2.getY()) > p1.getY() || Math.max(p2.getY(),t2.getY()) < p1.getY()) continue; return true; } int ang = DBMath.figureAngle(p1, t1); Point2D inter = DBMath.intersect(p2, 900, p1, ang); if (inter == null) continue; if (inter.getX() != p2.getX() || inter.getY() < Math.min(p2.getY(),t2.getY()) || inter.getY() > Math.max(p2.getY(),t2.getY())) continue; return true; } // special case: this line is horizontal if (p2.getY() == t2.getY()) { // simple bounds check if (Math.min(p1.getY(),t1.getY()) > p2.getY() || Math.max(p1.getY(),t1.getY()) < p2.getY()) continue; if (p1.getY() == t1.getY()) { if (Math.min(p1.getX(),t1.getX()) > Math.max(p2.getX(),t2.getX()) || Math.max(p1.getX(),t1.getX()) < Math.min(p2.getX(),t2.getX())) continue; return true; } if (p1.getX() == t1.getX()) { if (Math.min(p2.getX(),t2.getX()) > p1.getX() || Math.max(p2.getX(),t2.getX()) < p1.getX()) continue; return true; } int ang = DBMath.figureAngle(p1, t1); Point2D inter = DBMath.intersect(p2, 0, p1, ang); if (inter == null) continue; if (inter.getY() != p2.getY() || inter.getX() < Math.min(p2.getX(),t2.getX()) || inter.getX() > Math.max(p2.getX(),t2.getX())) continue; return true; } // simple bounds check if (Math.min(p1.getX(),t1.getX()) > Math.max(p2.getX(),t2.getX()) || Math.max(p1.getX(),t1.getX()) < Math.min(p2.getX(),t2.getX()) || Math.min(p1.getY(),t1.getY()) > Math.max(p2.getY(),t2.getY()) || Math.max(p1.getY(),t1.getY()) < Math.min(p2.getY(),t2.getY())) continue; // general case of line intersection int ang1 = DBMath.figureAngle(p1, t1); int ang2 = DBMath.figureAngle(p2, t2); Point2D inter = DBMath.intersect(p2, ang2, p1, ang1); if (inter == null) continue; if (inter.getX() < Math.min(p2.getX(),t2.getX()) || inter.getX() > Math.max(p2.getX(),t2.getX()) || inter.getY() < Math.min(p2.getY(),t2.getY()) || inter.getY() > Math.max(p2.getY(),t2.getY()) || inter.getX() < Math.min(p1.getX(),t1.getX()) || inter.getX() > Math.max(p1.getX(),t1.getX()) || inter.getY() < Math.min(p1.getY(),t1.getY()) || inter.getY() > Math.max(p1.getY(),t1.getY())) continue; return true; } return false; } /** * Method to compute the perimeter of this Poly. * @return the perimeter of this Poly. */ public double getPerimeter() { double perim = 0; int start = 0; if (style == Poly.Type.OPENED || style == Poly.Type.OPENEDT1 || style == Poly.Type.OPENEDT2 || style == Poly.Type.OPENEDT3) start = 1; for(int i=start; i<points.length; i++) { int j = i - 1; if (j < 0) j = points.length - 1; perim += points[i].distance(points[j]); } return perim; } /** * Method to compute longest edge. * @return the longest edge in this PolyBase. */ public double getMaxLength() { double max = 0; int start = 0; if (style == Poly.Type.OPENED || style == Poly.Type.OPENEDT1 || style == Poly.Type.OPENEDT2 || style == Poly.Type.OPENEDT3) start = 1; for(int i=start; i<points.length; i++) { int j = i - 1; if (j < 0) j = points.length - 1; double distance = points[i].distance(points[j]); if (max < distance) max = distance; } return max; } /** * Method to compute the area of this Poly. * @return the area of this Poly. Return always a positive number */ public double getArea() { if (style == Poly.Type.FILLED || style == Poly.Type.CLOSED || style == Poly.Type.CROSSED || style.isText()) { Rectangle2D bounds = getBox(); if (bounds != null) { double area = GenMath.getArea(bounds); /* now determine the sign of the area */// double sign = 0;// if (points[0].getX() == points[1].getX())// {// /* first line is vertical */// sign = (points[2].getX() - points[1].getX()) * (points[1].getY() - points[0].getY());// } else// {// /* first line is horizontal */// sign = (points[1].getX() - points[0].getX()) * (points[1].getY() - points[2].getY());// } //if (sign < 0) area = -area; return Math.abs(area); } return GenMath.getAreaOfPoints(points); } return 0; } /** * Method to return the X center coordinate of this Poly.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -