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

📄 interactiverouter.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
            PortInst pi = ((NodeInst)obj).findClosestPortInst(clicked);            if (pi == null) return null;            obj = pi;        }        if (obj instanceof PortInst) {            PortInst pi = (PortInst)obj;            NodeInst ni = pi.getNodeInst();            PortProto pp = pi.getPortProto();            boolean compressPort = false;            if (!ni.isCellInstance()) compressPort = true;            Poly poly = ni.getShapeOfPort(pp, clicked, compressPort, arcWidth); // this is for multi-site ports            return poly;        }        if (obj instanceof ArcInst) {            // make poly out of possible connecting points on arc            ArcInst arc = (ArcInst)obj;            Point2D [] points = new Point2D[2];            points[0] = arc.getHeadLocation();            points[1] = arc.getTailLocation();            Poly poly = new Poly(points);            return poly;        }        return null;    }    /**     * If drawing to/from an ArcInst, we may connect to some     * point along the arc.  This may bisect the arc, in which case     * we delete the current arc, add in a pin at the appropriate     * place, and create 2 new arcs to the old arc head/tail points.     * The bisection point depends on where the user point, but it     * is always a point on the arc.     * <p>     * Note that this method adds the returned RouteElement to the     * route, and updates the route if the arc is bisected.     * This method should NOT add the returned RouteElement to the route.     * @param route the route so far     * @param arc the arc to draw from/to     * @param point point on or near arc     * @param stayInside the area in which to route (null if not applicable).     * @return a RouteElement holding the new pin at the bisection     * point, or a RouteElement holding an existingPortInst if     * drawing from either end of the ArcInst.     */    protected RouteElementPort findArcConnectingPoint(Route route, ArcInst arc, Point2D point, PolyMerge stayInside) {        EPoint head = arc.getHeadLocation();        EPoint tail = arc.getTailLocation();        RouteElementPort headRE = RouteElementPort.existingPortInst(arc.getHeadPortInst(), head);        RouteElementPort tailRE = RouteElementPort.existingPortInst(arc.getTailPortInst(), tail);        RouteElementPort startRE = null;        // find extents of wire        double minX, minY, maxX, maxY;        Point2D minXpin = null, minYpin = null;        if (head.getX() < tail.getX()) {            minX = head.getX(); maxX = tail.getX(); minXpin = head;        } else {            minX = tail.getX(); maxX = head.getX(); minXpin = tail;        }        if (head.getY() < tail.getY()) {            minY = head.getY(); maxY = tail.getY(); minYpin = head;        } else {            minY = tail.getY(); maxY = head.getY(); minYpin = tail;        }        // for efficiency purposes, we are going to assume the arc is        // either vertical or horizontal for bisecting the arc        if (head.getX() == tail.getX()) {            // line is vertical, see if point point bisects            if (point.getY() > minY && point.getY() < maxY) {                Point2D location = new Point2D.Double(head.getX(), point.getY());                startRE = bisectArc(route, arc, location, stayInside);            }            // not within Y bounds, choose closest pin            else if (point.getY() <= minY) {                if (minYpin == head) startRE = headRE; else startRE = tailRE;            } else {                if (minYpin == head) startRE = tailRE; else startRE = headRE;            }        }        // check if arc is horizontal        else if (head.getY() == tail.getY()) {            // line is horizontal, see if point bisects            if (point.getX() > minX && point.getX() < maxX) {                Point2D location = new Point2D.Double(point.getX(), head.getY());                startRE = bisectArc(route, arc, location, stayInside);            }            // not within X bounds, choose closest pin            else if (point.getX() <= minX) {                if (minXpin == head) startRE = headRE; else startRE = tailRE;            } else {                if (minXpin == head) startRE = tailRE; else startRE = headRE;            }        }        // arc is not horizontal or vertical, draw from closest pin        else {            double headDist = point.distance(head);            double tailDist = point.distance(tail);            if (headDist < tailDist)                startRE = headRE;            else                startRE = tailRE;        }        //route.add(startRE);           // DON'T ADD!!        return startRE;    }    /**     * Splits an arc at bisectPoint and updates the route to reflect the change.     * This method should NOT add the returned RouteElement to the route.     *     * @param route the current route     * @param arc the arc to split     * @param bisectPoint point on arc from which to split it     * @param stayInside the area in which to route (null if not applicable).     * @return the RouteElement from which to continue the route     */    protected RouteElementPort bisectArc(Route route, ArcInst arc, Point2D bisectPoint, PolyMerge stayInside) {        Cell cell = arc.getParent();        EPoint head = arc.getHeadLocation();        EPoint tail = arc.getTailLocation();        // determine pin type to use if bisecting arc        PrimitiveNode pn = arc.getProto().findOverridablePinProto();        SizeOffset so = pn.getProtoSizeOffset();        double width = pn.getDefWidth()-so.getHighXOffset()-so.getLowXOffset();        double height = pn.getDefHeight()-so.getHighYOffset()-so.getLowYOffset();        // make new pin        RouteElementPort newPinRE = RouteElementPort.newNode(cell, pn, pn.getPort(0),                bisectPoint, width, height);        newPinRE.setBisectArcPin(true);        // make dummy end pins        RouteElementPort headRE = RouteElementPort.existingPortInst(arc.getHeadPortInst(), head);        RouteElementPort tailRE = RouteElementPort.existingPortInst(arc.getTailPortInst(), tail);        headRE.setShowHighlight(false);        tailRE.setShowHighlight(false);        // put name on longer arc        String name1 = null;        String name2 = null;        if (head.distance(bisectPoint) > tail.distance(bisectPoint))            name1 = arc.getName();        else            name2 = arc.getName();        // add two arcs to rebuild old startArc        RouteElement newHeadArcRE = RouteElementArc.newArc(cell, arc.getProto(), arc.getLambdaBaseWidth(), headRE, newPinRE,                head, bisectPoint, name1, arc.getTextDescriptor(ArcInst.ARC_NAME), arc, true, true, stayInside);        RouteElement newTailArcRE = RouteElementArc.newArc(cell, arc.getProto(), arc.getLambdaBaseWidth(), newPinRE, tailRE,                bisectPoint, tail, name2, arc.getTextDescriptor(ArcInst.ARC_NAME), arc, true, true, stayInside);        newHeadArcRE.setShowHighlight(false);        newTailArcRE.setShowHighlight(false);        // delete old arc        RouteElement deleteArcRE = RouteElementArc.deleteArc(arc);        // add new stuff to route        route.add(deleteArcRE);        //route.add(newPinRE);          // DON'T ADD!!        route.add(headRE);        route.add(tailRE);        route.add(newHeadArcRE);        route.add(newTailArcRE);        return newPinRE;    }    // ------------------------- Spatial Dimension Calculations -------------------------    /**     * Get closest value to clicked within a range from min to max     */    protected static double getClosestValue(double min, double max, double clicked) {        if (clicked >= max) {            return max;        } else if (clicked <= min) {            return min;        } else {            return clicked;        }    }    /**     * Gets the closest orthogonal point from the startPoint to the clicked point.     * This is used when the user clicks in space and the router draws only a single     * arc towards the clicked point in one dimension.     * @param startPoint start point of the arc     * @param clicked where the user clicked     * @return an end point to draw to from start point to make a single arc segment.     */    protected static Point2D getClosestOrthogonalPoint(Point2D startPoint, Point2D clicked) {        Point2D newPoint;        if (Math.abs(startPoint.getX() - clicked.getX()) < Math.abs(startPoint.getY() - clicked.getY())) {            // draw horizontally            newPoint = new Point2D.Double(startPoint.getX(), clicked.getY());        } else {            // draw vertically            newPoint = new Point2D.Double(clicked.getX(), startPoint.getY());        }        return newPoint;    }    /**     * Use to find the closest point to clicked to route a wire from startPoint.     * This point will be at an angel from startPoint which is a multiple of     * angleIncrement.  If stayInside and useArc are not null, then the two possible     * closest points will be determined by if they reside inside stayInside,     * rather than the closest point.     * @param startPoint     * @param clicked     * @param angleIncrement     * @return the closest point to clicked to route a wire.     */    protected static Point2D getClosestAngledPoint(Point2D startPoint, Point2D clicked,                                                   int angleIncrement) {        angleIncrement = Math.abs(angleIncrement);        if (angleIncrement == 0) return clicked;        // don't really have to call this for angleIncr of 90 as general purpose        // code below does right thing, but it's a lot faster        if (angleIncrement == 90) return getClosestOrthogonalPoint(startPoint, clicked);        double angleInc = angleIncrement * Math.PI / 180;        // calculate angle        double x = clicked.getX()-startPoint.getX();        double y = clicked.getY()-startPoint.getY();        double angle = Math.atan2(y,x);        //System.out.println("angle is "+angle);        // find closest two angle increments        double nearest1 = (int)(angle / angleInc) * angleInc;        double nearest2 = (angle<0) ? nearest1 - angleInc : nearest1 + angleInc;        //System.out.println("nearest1, nearest2 are "+nearest1+" and "+ nearest2);        Point2D n1, n2;        // two points on line are candidates: one uses clicked X, other uses clickedY        double tan1 = Math.tan(nearest1);        if (tan1 == 0) tan1 = 0.000001;        //System.out.println("tan1 is "+tan1);        Point2D n1_1 = new Point2D.Double(x, x*tan1);        Point2D n1_2 = new Point2D.Double(y/tan1, y);        //System.out.println("Point1's: "+n1_1+", "+n1_2);        // take whichever is shorter        if (n1_1.distance(x,y) < n1_2.distance(x,y))            n1 = n1_1;        else            n1 = n1_2;        // same for second angle        double tan2 = Math.tan(nearest2);        if (tan2 == 0) tan2 = 0.000001;        //System.out.println("tan2 is "+tan2);        Point2D n2_1 = new Point2D.Double(x, x*tan2);        Point2D n2_2 = new Point2D.Double(y/tan2, y);        //System.out.println("Point2's: "+n2_1+", "+n2_2);        if (n2_1.distance(x,y) < n2_2.distance(x,y))            n2 = n2_1;        else            n2 = n2_2;        //System.out.println("Point1: "+n1);        //System.out.println("Point2: "+n2);        double xfinal, yfinal;        // of the points on the two angles, take closest to clicked        if (n2.distance(x,y) < n1.distance(x,y)) {            xfinal = DBMath.round(n2.getX() + startPoint.getX());            yfinal = DBMath.round(n2.getY() + startPoint.getY());        } else {            xfinal = DBMath.round(n1.getX() + startPoint.getX());            yfinal = DBMath.round(n1.getY() + startPoint.getY());        }        return new Point2D.Double(xfinal, yfinal);    }    protected boolean withinBounds(double point, double bound1, double bound2) {        double min, max;        if (bound1 < bound2) {            min = bound1; max = bound2;        } else {            min = bound2; max = bound1;        }        return ((point >= min) && (point <= max));    }    /**     * Returns true if point is on the line segment, false otherwise.     */    protected boolean onSegment(Point2D point, Line2D line) {        double minX, minY, maxX, maxY;        Point2D head = line.getP1();        Point2D tail = line.getP2();        if (head.getX() < tail.getX()) {            minX = head.getX(); maxX = tail.getX();        } else {            minX = tail.getX(); maxX = head.getX();        }        if (head.getY() < tail.getY()) {            minY = head.getY(); maxY = tail.getY();        } else {            minY = tail.getY(); maxY = head.getY();        }        if ((point.getX() >= minX) && (point.getX() <= maxX) &&            (point.getY() >= minY) && (point.getY() <= maxY))            return true;        return false;    }}

⌨️ 快捷键说明

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