📄 polybase.java
字号:
if (!skip) { boolean thisPointGreaterY = DBMath.isGreaterThan(thisY, ptY); boolean lastPointGreaterY = DBMath.isGreaterThan(lastY, ptY); // doesn't intersect the horizontal line // pt[y] < s[Y] && pt[y] < e[Y] || pt[Y] > s[Y] && pt[Y] > e[Y] skip = (thisPointGreaterY && lastPointGreaterY) || (DBMath.isGreaterThan(ptY, thisY) && DBMath.isGreaterThan(ptY, lastY)); if (!skip) { // only counting half of the domain // at least one must be greater than pt[Y] and pt[X] // both X must be greater because it already checked if point is on the line. double ptX = pt.getX(); // not a vertical line. Horizontal lines won't make it to this point if (!DBMath.areEquals(thisY, lastY)) { ptX = thisPoint.getX() + (ptY - thisY) * (lastPoint.getX() - thisPoint.getX()) / (lastY - thisY); } // point must be at the right side of the point. Not checking if they are identical because // that was tested above. boolean pointGreaterX = DBMath.isGreaterThan(ptX, pt.getX()); if ((thisPointGreaterY || lastPointGreaterY) && pointGreaterX) count++; } } lastPoint = thisPoint; } boolean inside = (count != 0 && count%2 != 0); return (inside); } /** * Method to tell whether a coordinate is inside of this Poly. * This algorithm is based on angles. If the angle is 360 then the point is inside * @param pt the point in question. * @return true if the point is inside of this Poly. */// private boolean isInsideGenericPolygonOriginal(Point2D pt)// {// // general polygon containment by summing angles to vertices// double ang = 0;// Point2D lastPoint = points[points.length-1];// //if (pt.equals(lastPoint)) return true;// if (DBMath.areEquals(pt, lastPoint))// {// return true;// }// Rectangle2D box = getBounds2D();//// // The point is outside the bounding box of the polygon// if (!DBMath.pointInsideRect(pt, box))// return false;//// int lastp = DBMath.figureAngle(pt, lastPoint);// for (Point2D thisPoint : points)// {// //if (pt.equals(thisPoint)) return true;// if (DBMath.areEquals(pt, thisPoint))// {// return true;// }// // Checking if point is along polygon edge// if (DBMath.isOnLine(thisPoint, lastPoint, pt))// {// return true;// }// int thisp = DBMath.figureAngle(pt, thisPoint);// int tang = lastp - thisp;// if (tang < -1800)// tang += 3600;// if (tang > 1800)// tang -= 3600;// ang += tang;// lastp = thisp;// lastPoint = thisPoint;// }// ang = Math.abs(ang);// //boolean completeCircle = ang == 0 || ang == 3600;// boolean oldCalculation = (!(ang <= points.length));// return (oldCalculation);// //if (Math.abs(ang) <= points.length) return false;// //return true;// } public boolean isInside(Point2D pt) { if (style == Poly.Type.FILLED || style == Poly.Type.CLOSED || style == Poly.Type.CROSSED || style.isText()) { // If point is not in 2D bounding box -> is outside anyway Rectangle2D bounds2D = this.getBounds2D(); if (!DBMath.pointInRect(pt, bounds2D)) return false; // check rectangular case for containment Rectangle2D bounds = getBox(); if (bounds != null) { if (DBMath.pointInRect(pt, bounds)) return true; // special case: single point, take care of double precision error if (bounds.getWidth() == 0 && bounds.getHeight() == 0) { if (DBMath.areEquals(pt.getX(), bounds.getX()) && DBMath.areEquals(pt.getY(), bounds.getY())) return true; } return false; }// boolean method = isInsideGenericPolygonOriginal(pt); boolean method = isPointInsideCutAlgorithm(pt);// boolean method = isPointInsideArea(pt); // very slow. 3 times slower in 1 example return method; } if (style == Poly.Type.CROSS || style == Poly.Type.BIGCROSS) { if (DBMath.areEquals(getCenterX(), pt.getX()) && DBMath.areEquals(getCenterY(), pt.getY())) return true; return false; } if (style == Poly.Type.OPENED || style == Poly.Type.OPENEDT1 || style == Poly.Type.OPENEDT2 || style == Poly.Type.OPENEDT3 || style == Poly.Type.VECTORS) { // first look for trivial inclusion by being a vertex //for(int i=0; i<points.length; i++) // if (pt.equals(points[i])) return true; for (Point2D point : points) if (DBMath.areEquals(pt, point)) return true; // see if the point is on one of the edges if (style == Poly.Type.VECTORS) { for(int i=0; i<points.length; i += 2) if (DBMath.isOnLine(points[i], points[i+1], pt)) return true; } else { for(int i=1; i<points.length; i++) if (DBMath.isOnLine(points[i-1], points[i], pt)) return true; } return false; } if (style == Poly.Type.CIRCLE || style == Poly.Type.THICKCIRCLE || style == Poly.Type.DISC) { double dist = points[0].distance(points[1]); double odist = points[0].distance(pt); if (odist < dist) return true; return false; } if (style == Poly.Type.CIRCLEARC || style == Poly.Type.THICKCIRCLEARC) { // first see if the point is at the proper angle from the center of the arc int ang = DBMath.figureAngle(points[0], pt); int endangle = DBMath.figureAngle(points[0], points[1]); int startangle = DBMath.figureAngle(points[0], points[2]); double angrange; if (endangle > startangle) { if (ang < startangle || ang > endangle) return false; angrange = endangle - startangle; } else { if (ang < startangle && ang > endangle) return false; angrange = 3600 - startangle + endangle; } // now see if the point is the proper distance from the center of the arc double dist = points[0].distance(pt); double wantdist; if (ang == startangle || angrange == 0) { wantdist = points[0].distance(points[1]); } else if (ang == endangle) { wantdist = points[0].distance(points[2]); } else { double startdist = points[0].distance(points[1]); double enddist = points[0].distance(points[2]); if (enddist == startdist) wantdist = startdist; else { wantdist = startdist + (ang - startangle) / angrange * (enddist - startdist); } } //if (dist == wantdist) return true; if (DBMath.areEquals(dist, wantdist)) return true; return false; } // I give up return false; } /** * Method to tell whether a coordinates of this Poly are inside of a Rectangle2D. * @param bounds the Rectangle2D in question. * @return true if this Poly is completely inside of the bounds. */ public boolean isInside(Rectangle2D bounds) { if (style == Poly.Type.CIRCLE || style == Poly.Type.THICKCIRCLE || style == Poly.Type.DISC) { Point2D ctr = points[0]; double dx = Math.abs(ctr.getX() - points[1].getX()); double dy = Math.abs(ctr.getY() - points[1].getY()); double rad = Math.max(dx, dy); if (!DBMath.pointInRect(new Point2D.Double(ctr.getX()+rad,ctr.getY()+rad), bounds)) return false; if (!DBMath.pointInRect(new Point2D.Double(ctr.getX()-rad,ctr.getY()-rad), bounds)) return false; //if (!bounds.contains(new Point2D.Double(ctr.getX()+rad,ctr.getY()+rad))) return false; //if (!bounds.contains(new Point2D.Double(ctr.getX()-rad,ctr.getY()-rad))) return false; return true; } for (Point2D p : points) { if (!DBMath.pointInRect(p, bounds)) return false; //if (!bounds.contains(points[i])) return false; } return true; } /** Method to check if point is part of the point set that defines * the polygon * @param point * @return true if found in points set */ public boolean isPointOnCorner(Point2D point) { for (Point2D p : points) { if (DBMath.areEquals(point,p)) return (true); } return (false); } /** * Method to reduce this Poly by the proper amount presuming that it describes a port connected to an arc. * This Poly is modified in place to reduce its size. * @param pi the PortInst that describes this Poly. * @param wid the width of the arc connected to this port-poly. * This should be the base width, not the actual width stored in memory. * @param angle the angle of the arc connected to this port-poly. * If negative, do not consider arc angle. */ public void reducePortPoly(PortInst pi, double wid, int angle) { // look down to the bottom level node/port PortOriginal fp = new PortOriginal(pi);// AffineTransform trans = fp.getTransformToTop(); NodeInst ni = fp.getBottomNodeInst(); // do not reduce port if not filled if (getStyle() != Poly.Type.FILLED && getStyle() != Poly.Type.CROSSED && getStyle() != Poly.Type.DISC) return; // do not reduce port areas on polygonally defined nodes if (ni.getTrace() != null) return; // determine amount to reduce port double realWid = wid / 2; // get bounding box of port polygon Rectangle2D portBounds = getBox(); if (portBounds == null) { // special case: nonrectangular port if (getStyle() == Poly.Type.DISC) { // shrink discs double dist = points[0].distance(points[1]); dist = Math.max(0, dist-realWid); points[1].setLocation(points[0].getX() + dist, points[0].getY()); return; } // cannot handle other forms of polygon yet return; } // determine the edge and center of the port polygon double bx = portBounds.getMinX(); double ux = portBounds.getMaxX(); double by = portBounds.getMinY(); double uy = portBounds.getMaxY();// double cx = portBounds.getCenterX(); double cy = portBounds.getCenterY(); // compute the area of the nodeinst Rectangle2D r = ni.getBaseShape().getBounds2D(); double lx = r.getMinX(); double hx = r.getMaxX(); double ly = r.getMinY(); double hy = r.getMaxY();// SizeOffset so = ni.getSizeOffset();// Rectangle2D nodeBounds = ni.getBounds();// Point2D lowerLeft = new Point2D.Double(nodeBounds.getMinX()+so.getLowXOffset(), nodeBounds.getMinY()+so.getLowYOffset());// trans.transform(lowerLeft, lowerLeft);// Point2D upperRight = new Point2D.Double(nodeBounds.getMaxX()-so.getHighXOffset(), nodeBounds.getMaxY()-so.getHighYOffset());// trans.transform(upperRight, upperRight);// double lx = lowerLeft.getX(); double hx = upperRight.getX();// double ly = lowerLeft.getY(); double hy = upperRight.getY();// if (lx > hx) { double swap = lx; lx = hx; hx = swap; }// if (ly > hy) { double swap = ly; ly = hy; hy = swap; } // do not reduce in X if arc is horizontal if (angle != 0 && angle != 1800) { // determine reduced port area lx = Math.max(bx, lx + realWid); hx = Math.min(ux, hx - realWid); if (hx < lx) hx = lx = (hx + lx) / 2; // only clip in X if the port area is within of the reduced node X area if (ux >= lx && bx <= hx) { for (Point2D point : points) { double x = point.getX(); if (x < lx)x = lx; if (x > hx) x = hx; point.setLocation(x, point.getY()); } } } // do not reduce in Y if arc is vertical if (angle != 900 && angle != 2700) { // determine reduced port area ly = Math.max(by, ly + realWid); hy = Math.min(uy, hy - realWid); if (hy < ly) hy = ly = (hy + ly) / 2; // only clip in Y if the port area is inside of the reduced node Y area if (uy >= ly && by <= hy) { for (Point2D point : points) { double y = point.getY(); if (y < ly) y = ly; if (y > hy) y = hy; point.setLocation(point.getX(), y); } } } } /** * Method to rotate a text Type according to the rotation of the object on which it resides. * @param origType the original text Type. * @param eObj the ElectricObject on which the text resides. * @return the new text Type that accounts for the rotation. */ public static Poly.Type rotateType(Poly.Type origType, ElectricObject eObj) { // centered text does not rotate its anchor if (origType == Poly.Type.TEXTCENT || origType == Poly.Type.TEXTBOX) return origType; // get node this sits on NodeInst ni; if (eObj instanceof NodeInst) { ni = (NodeInst)eObj; } else if (eObj instanceof Export) { Export pp = (Export)eObj; ni = pp.getOriginalPort().getNodeInst(); } else return origType; // no need to rotate anchor if the node is not transformed int nodeAngle = ni.getAngle(); if (nodeAngle == 0 && !ni.isMirroredAboutXAxis() && !ni.isMirroredAboutYAxis()) return origType; // can only rotate anchor when node is in a manhattan orientation if ((nodeAngle%900) != 0) return origType; // determine angle of original style int origAngle = origType.getTextAngle(); if (ni.isMirroredAboutXAxis() != ni.isMirroredAboutYAxis() && ((origAngle%1800) == 0 || (origAngle%1800) == 1350)) origAngle += 1800; // determine change in angle because of node rotation Orientation orient = Orientation.fromJava(nodeAngle, ni.isMirroredAboutXAxis(), ni.isMirroredAboutYAxis()); AffineTransform trans = orient.pureRotate();// AffineTransform trans = NodeInst.pureRotate(nodeAngle, ni.isMirroredAboutXAxis(), ni.isMirroredAboutYAxis()); Point2D pt = new Point2D.Double(100, 0); trans.transform(pt, pt); int xAngle = GenMath.figureAngle(new Point2D.Double(0, 0), pt); if (ni.isMirroredAboutXAxis() != ni.isMirroredAboutYAxis() && ((origAngle%1800) == 450)) xAngle += 900; // determine new angle and style int angle = (origAngle + xAngle) % 3600;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -