📄 polybase.java
字号:
* @return the X center coordinate of this Poly. */ public double getCenterX() { Rectangle2D b = getBounds2D(); return b.getCenterX(); } /** * Method to return the Y center coordinate of this Poly. * @return the Y center coordinate of this Poly. */ public double getCenterY() { Rectangle2D b = getBounds2D(); return b.getCenterY(); } /** * Method to return the center of the bounding box containing this PolyBase * @return EPoint representing the center of the PolyBase bounding box. */ public EPoint getCenter() { Rectangle2D b = getBounds2D(); return new EPoint(b.getCenterX(), b.getCenterY()); } /** * Method to return the bounds of this Poly. * @return the bounds of this Poly. */ public Rectangle2D getBounds2D() { if (bounds == null) calcBounds(); return bounds; } /** * Method to return the bounds of this Poly. * Nobody really uses this, but it is necessary for the implementation of Shape. * @return the bounds of this Poly. * @deprecated this is only implemented because Poly extends Shape. You should * be using getBounds2D() instead. */ public Rectangle getBounds() { if (bounds == null) calcBounds(); Rectangle2D r = getBounds2D(); return new Rectangle((int)r.getMinX(), (int)r.getMinY(), (int)r.getWidth(), (int)r.getHeight()); } /** * Method to change the value of a point in the PolyBase. * @param pt the index of the point to change. * @param x the new X value. * @param y the new Y value. */ public void setPoint(int pt, double x, double y) { points[pt].setLocation(x, y); bounds = null; } private void calcBounds() { bounds = null; if (style == Poly.Type.CIRCLE || style == Poly.Type.THICKCIRCLE || style == Poly.Type.DISC) { double cX = points[0].getX(); double cY = points[0].getY(); double radius = points[0].distance(points[1]); double diameter = radius * 2; bounds = new Rectangle2D.Double(cX - radius, cY - radius, diameter, diameter); return; } if (style == Poly.Type.CIRCLEARC || style == Poly.Type.THICKCIRCLEARC) { bounds = GenMath.arcBBox(points[1], points[2], points[0]); return; } if (points.length > 0) { double lX = points[0].getX(); double hX = lX; double lY = points[0].getY(); double hY = lY; for (int i = 1; i < points.length; i++) { double x = points[i].getX(); double y = points[i].getY(); if (x < lX) lX = x; if (x > hX) hX = x; if (y < lY) lY = y; if (y > hY) hY = y; } bounds = new Rectangle2D.Double(lX, lY, hX-lX, hY-lY); // Back on Oct 1 //bounds = new Rectangle2D.Double(DBMath.round(lX), DBMath.round(lY), DBMath.round(hX-lX), DBMath.round(hY-lY)); } if (bounds == null) bounds = new Rectangle2D.Double(); } /** * Attempt to control rounding errors in input libraries */ public void roundPoints() { bounds = null; for (Point2D point : points) { point.setLocation(DBMath.round(point.getX()), DBMath.round(point.getY())); } } /** * Method to retrieve all loops that are part of this PolyBase, * sorted by area. * @return the List of loops. */// public List<PolyBase> getSortedLoops()// {// Collection<PolyBase> set = getPointsInArea(new Area(this), layer, true, false, null);// List<PolyBase> list = new ArrayList<PolyBase>(set);// Collections.sort(list, AREA_COMPARATOR);// return (list);// } /** * Class to compare PolyBase objects */ private static Comparator<PolyBase> AREA_COMPARATOR = new Comparator<PolyBase>() { /** * Compares PolyBase objects based on area. * This method doesn't guarantee (compare(x, y)==0) == (x.equals(y)) * @param p1 first object to be compared. * @param p2 second object to be compared. * @return Returns a negative integer, zero, or a positive integer as the * first object has smaller than, equal to, or greater area than the second. * @throws ClassCastException if the arguments' types are not PolyBase. */ public int compare(PolyBase p1, PolyBase p2) { double diff = p1.getArea() - p2.getArea(); if (diff < 0.0) return -1; if (diff > 0.0) return 1; return 0; } }; /** * Static method to get PolyBase elements associated with an Area. * @param area Java2D structure containing the geometrical information * @param layer the Layer to examine. * @param simple if true, polygons with inner loops will return in sample Poly. * @param includeLastPoint true to include the last point. * @return List of PolyBase elements. */ public static List<PolyBase> getPointsInArea(Area area, Layer layer, boolean simple, boolean includeLastPoint) { if (area == null) return null; boolean isSingular = area.isSingular(); // Complex algorithm to detect loops if (!isSingular) return (getPointsFromComplex(area, layer)); double [] coords = new double[6]; List<Point2D> pointList = new ArrayList<Point2D>(); Point2D lastMoveTo = null; List<PolyBase> toDelete = new ArrayList<PolyBase>(); List<PolyBase> polyList = new ArrayList<PolyBase>(); // Gilda: best practice note: System.arraycopy for(PathIterator pIt = area.getPathIterator(null); !pIt.isDone(); ) { int type = pIt.currentSegment(coords); if (type == PathIterator.SEG_CLOSE) { if (includeLastPoint && lastMoveTo != null) pointList.add(lastMoveTo); Point2D [] points = new Point2D[pointList.size()]; int i = 0; for(Point2D p : pointList) points[i++] = p; PolyBase poly = new PolyBase(points); poly.setLayer(layer); poly.setStyle(Poly.Type.FILLED); lastMoveTo = null; toDelete.clear(); if (!simple && !isSingular) { for (PolyBase pn : polyList) { if (pn.contains(pointList.get(0)) || poly.contains(pn.getPoints()[0])) { points = pn.getPoints(); for (i = 0; i < points.length; i++) pointList.add(points[i]); Point2D[] newPoints = new Point2D[pointList.size()]; System.arraycopy(pointList.toArray(), 0, newPoints, 0, pointList.size()); poly = new PolyBase(newPoints); toDelete.add(pn); } } } if (poly != null) polyList.add(poly); polyList.removeAll(toDelete); pointList.clear(); } else if (type == PathIterator.SEG_MOVETO || type == PathIterator.SEG_LINETO) { Point2D pt = new Point2D.Double(coords[0], coords[1]); pointList.add(pt); if (type == PathIterator.SEG_MOVETO) lastMoveTo = pt; } pIt.next(); } return polyList; } // Creating a tree for finding the loops public static class PolyBaseTree { List<PolyBaseTree> sons; PolyBase poly; PolyBaseTree(PolyBase p) { poly = p; sons = new ArrayList<PolyBaseTree>(); } public List<PolyBaseTree> getSons() {return sons;} public PolyBase getPoly() {return poly;} void getLoops(int level, Stack<PolyBase> stack) { // Starting of a new polygon if (level%2== 0) { stack.push(poly); } else { PolyBase top = stack.pop(); Point2D [] points = new Point2D[top.getPoints().length+poly.getPoints().length + 2]; System.arraycopy(top.getPoints(), 0, points, 0, top.getPoints().length); // Adding the first point at the end to close the first loop points[top.getPoints().length] = (Point2D)top.getPoints()[0].clone(); System.arraycopy(poly.getPoints(), 0, points, top.getPoints().length+1, poly.getPoints().length); points[points.length-1] = (Point2D)poly.getPoints()[0].clone(); PolyBase p = new PolyBase(points); p.setLayer(poly.getLayerOrPseudoLayer()); // they are supposed to belong to the same layer stack.push(p); } level++; for (PolyBaseTree t : sons) t.getLoops(level, stack); } boolean add(PolyBaseTree t) { if (!poly.contains(t.poly.getPoints()[0])) { // Belong to another root return false; } if (sons.size() == 0) { double a = poly.getArea(); double b = t.poly.getArea(); sons.add(t); if (a < b) { assert(false); System.out.println("Should this happen"); PolyBase c = t.poly; t.poly = poly; poly = c; } } else { for (PolyBaseTree b : sons) { PolyBase pn = b.poly; if (pn.contains(t.poly.getPoints()[0])) { return (b.add(t)); } // test very expensive. else if (Job.getDebug() && t.poly.contains(pn.getPoints()[0])) { assert(false); System.out.println(" Bad happen"); } } sons.add(t); } return true; } } // This assumes the algorithm starts with external loop public static List<PolyBaseTree> getPolyTrees(Area area, Layer layer) { List<PolyBase> list = getLoopsFromArea(area, layer); List<PolyBaseTree> roots = getTreesFromLoops(list); return roots; } // Get trees from loops public static List<PolyBaseTree> getTreesFromLoops(List<PolyBase> list) { List<PolyBaseTree> roots = new ArrayList<PolyBaseTree>(); // areas are sorted from min to max // Build the hierarchy with loops for (int i = list.size()-1; i > -1; i--) { PolyBaseTree t = new PolyBaseTree(list.get(i)); // Check all possible roots boolean added = false; for (PolyBaseTree r : roots) { if (r.add(t)) { added = true; break; } } if (!added) roots.add(t); } return roots; } // Get Loops public static List<PolyBase> getLoopsFromArea(Area area, Layer layer) { if (area == null) return null; double [] coords = new double[6]; List<Point2D> pointList = new ArrayList<Point2D>(); List<PolyBase> list = new ArrayList<PolyBase>(); for(PathIterator pIt = area.getPathIterator(null); !pIt.isDone(); ) { int type = pIt.currentSegment(coords); if (type == PathIterator.SEG_CLOSE) { Point2D [] points = new Point2D[pointList.size()]; System.arraycopy(pointList.toArray(), 0, points, 0, pointList.size());// int i = 0;// for(Point2D p : pointList)// points[i++] = p; PolyBase poly = new PolyBase(points); poly.setLayer(layer); poly.setStyle(Poly.Type.FILLED); list.add(poly); pointList.clear(); } else if (type == PathIterator.SEG_MOVETO || type == PathIterator.SEG_LINETO) { Point2D pt = new Point2D.Double(coords[0], coords[1]); pointList.add(pt); } pIt.next(); } Collections.sort(list, AREA_COMPARATOR); return list; } // This assumes the algorithm starts with external loop public static List<PolyBase> getPointsFromComplex(Area area, Layer layer) { List<PolyBase> list = getLoopsFromArea(area, layer); List<PolyBaseTree> roots = getTreesFromLoops(list); list.clear(); // get loops from all tree roots. Even loops start a new poly for (PolyBaseTree r : roots) { int count = 0; Stack<PolyBase> s
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -