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

📄 simplewirer.java

📁 The ElectricTM VLSI Design System is an open-source Electronic Design Automation (EDA) system that c
💻 JAVA
字号:
/* -*- tab-width: 4 -*- * * Electric(tm) VLSI Design System * * File: SimpleWirer.java * * Copyright (c) 2003 Sun Microsystems and Static Free Software * * Electric(tm) is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Electric(tm) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Electric(tm); see the file COPYING.  If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, Mass 02111-1307, USA. */package com.sun.electric.tool.routing;import com.sun.electric.database.geometry.GenMath;import com.sun.electric.database.geometry.PolyMerge;import com.sun.electric.database.geometry.DBMath;import com.sun.electric.database.hierarchy.Cell;import com.sun.electric.database.prototype.PortProto;import com.sun.electric.technology.ArcProto;import com.sun.electric.technology.PrimitiveNode;import com.sun.electric.technology.Layer;import com.sun.electric.technology.SizeOffset;import com.sun.electric.technology.technologies.Generic;import com.sun.electric.tool.user.User;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;/** * A Simple wiring tool for the user to draw wires. */public class SimpleWirer extends InteractiveRouter {    /* ----------------------- Router Methods ------------------------------------- */    public String toString() { return "SimpleWirer"; }    protected boolean planRoute(Route route, Cell cell, RouteElementPort endRE,                                Point2D startLoc, Point2D endLoc, Point2D clicked, PolyMerge stayInside, VerticalRoute vroute,                                boolean contactsOnEndObj, boolean extendArcHead, boolean extendArcTail, Rectangle2D contactArea) {        RouteElementPort startRE = route.getEnd();        // find port protos of startRE and endRE, and find connecting arc type        PortProto startPort = startRE.getPortProto();        PortProto endPort = endRE.getPortProto();        ArcProto useArc = getArcToUse(startPort, endPort);        // first, find location of corner of L if routing will be an L shape        Point2D cornerLoc = null;    	// see if it fits the angle increment so that a single arc can be drawn        boolean singleArc = false;    	if (useArc != null)    	{    		int inc = 10*useArc.getAngleIncrement();    		if (inc == 0) singleArc = true; else    		{    			int ang = GenMath.figureAngle(startLoc, endLoc);    			if ((ang % inc) == 0) singleArc = true;    		}    	} else    	{    		// no arc specified: allow direct if manhattan            if (startLoc.getX() == endLoc.getX() || startLoc.getY() == endLoc.getY()) singleArc = true;    	}        if (contactArea != null) {            cornerLoc = new Point2D.Double(contactArea.getCenterX(), contactArea.getCenterY());        } else {            if (singleArc)            {                // single arc                if (contactsOnEndObj)                    cornerLoc = endLoc;                else                    cornerLoc = startLoc;            } else            {                Point2D pin1 = new Point2D.Double(startLoc.getX(), endLoc.getY());                Point2D pin2 = new Point2D.Double(endLoc.getX(), startLoc.getY());                // find which pin to use                int clickedQuad = findQuadrant(endLoc, clicked);                int pin1Quad = findQuadrant(endLoc, pin1);                int pin2Quad = findQuadrant(endLoc, pin2);                int oppositeQuad = (clickedQuad + 2) % 4;                // presume pin1 by default                cornerLoc = pin1;                if (pin2Quad == clickedQuad)                {                    cornerLoc = pin2;                // same quad as pin2, use pin2                } else if (pin1Quad == clickedQuad)                {                    cornerLoc = pin1;                // same quad as pin1, use pin1                } else if (pin1Quad == oppositeQuad)                {                    cornerLoc = pin2;                // near to pin2 quad, use pin2                }                if (stayInside != null && useArc != null)                {                    // make sure the bend stays inside of the merge area                    double pinSize = useArc.getDefaultLambdaBaseWidth();                    Layer pinLayer = useArc.getLayerIterator().next();                    Rectangle2D pin1Rect = new Rectangle2D.Double(pin1.getX()-pinSize/2, pin1.getY()-pinSize/2, pinSize, pinSize);                    Rectangle2D pin2Rect = new Rectangle2D.Double(pin2.getX()-pinSize/2, pin2.getY()-pinSize/2, pinSize, pinSize);                    if (stayInside.contains(pinLayer, pin1Rect)) cornerLoc = pin1; else                        if (stayInside.contains(pinLayer, pin2Rect)) cornerLoc = pin2;                }            }        }        // never use universal arcs unless the user has selected them        if (useArc == null) {            // use universal if selected            if (User.getUserTool().getCurrentArcProto() == Generic.tech().universal_arc)                useArc = Generic.tech().universal_arc;            else {                route.add(endRE);                route.setEnd(endRE);                vroute.buildRoute(route, cell, startRE, endRE, startLoc, endLoc, cornerLoc, stayInside, contactArea);                return true;            }        }        route.add(endRE);        route.setEnd(endRE);        // startRE and endRE can be connected with an arc.  If one of them is a bisectArcPin,        // and can be replaced by the other, just replace it and we're done.        if (route.replaceBisectPin(startRE, endRE)) {            route.remove(startRE);            return true;        } else if (route.replaceBisectPin(endRE, startRE)) {            route.remove(endRE);            route.setEnd(startRE);            return true;        }        // find arc width to use        double width = getArcWidthToUse(startRE, useArc);        double width2 = getArcWidthToUse(endRE, useArc);        if (width2 > width) width = width2;        // see if we should only draw a single arc        if (singleArc) {            // draw single            RouteElement arcRE = RouteElementArc.newArc(cell, useArc, width, startRE, endRE,            	startLoc, endLoc, null, null, null, extendArcHead, extendArcTail, stayInside);            route.add(arcRE);            return true;        }        // this router only draws horizontal and vertical arcs        // if either X or Y coords are the same, create a single arc//        boolean newV = DBMath.areEquals(startLoc.getX(), endLoc.getX()) || DBMath.areEquals(startLoc.getY(), endLoc.getY());//        boolean oldV = (startLoc.getX() == endLoc.getX() || startLoc.getY() == endLoc.getY());//        if (newV != oldV)//            System.out.println("Precision problem in SimpleWireer");        if (DBMath.areEquals(startLoc.getX(), endLoc.getX()) || DBMath.areEquals(startLoc.getY(), endLoc.getY()))        {            // single arc            RouteElement arcRE = RouteElementArc.newArc(cell, useArc, width, startRE, endRE,            	startLoc, endLoc, null, null, null, extendArcHead, extendArcTail, stayInside);            route.add(arcRE);        } else {            // otherwise, create new pin and two arcs for corner            // make new pin of arc type            PrimitiveNode pn = useArc.findOverridablePinProto();            SizeOffset so = pn.getProtoSizeOffset();            double defwidth = pn.getDefWidth()-so.getHighXOffset()-so.getLowXOffset();            double defheight = pn.getDefHeight()-so.getHighYOffset()-so.getLowYOffset();            RouteElementPort pinRE = RouteElementPort.newNode(cell, pn, pn.getPort(0), cornerLoc,                    defwidth, defheight);            RouteElement arcRE1 = RouteElementArc.newArc(cell, useArc, width, startRE, pinRE,            	startLoc, cornerLoc, null, null, null, extendArcHead, extendArcTail, stayInside);            RouteElement arcRE2 = RouteElementArc.newArc(cell, useArc, width, pinRE, endRE,            	cornerLoc, endLoc, null, null, null, extendArcHead, extendArcTail, stayInside);            route.add(pinRE);            route.add(arcRE1);            route.add(arcRE2);        }        return true;    }    /**     * Determines what route quadrant pt is compared to refPoint.     * A route can be drawn vertically or horizontally so this     * method will return a number between 0 and 3, inclusive,     * where quadrants are defined based on the angle relationship     * of refPoint to pt.  Imagine a circle with <i>refPoint</i> as     * the center and <i>pt</i> a point on the circumference of the     * circle.  Then theta is the angle described by the arc refPoint->pt,     * and quadrants are defined as:     * <code>     * <p>quadrant :     angle (theta)     * <p>0 :            -45 degrees to 45 degrees     * <p>1 :            45 degress to 135 degrees     * <p>2 :            135 degrees to 225 degrees     * <p>3 :            225 degrees to 315 degrees (-45 degrees)     *     * @param refPoint reference point     * @param pt variable point     * @return which quadrant <i>pt</i> is in.     */    protected static int findQuadrant(Point2D refPoint, Point2D pt) {        // find angle        double angle = Math.atan((pt.getY()-refPoint.getY())/(pt.getX()-refPoint.getX()));        if (pt.getX() < refPoint.getX()) angle += Math.PI;        if ((angle > -Math.PI/4) && (angle <= Math.PI/4))            return 0;        else if ((angle > Math.PI/4) && (angle <= Math.PI*3/4))            return 1;        else if ((angle > Math.PI*3/4) &&(angle <= Math.PI*5/4))            return 2;        else            return 3;    }}

⌨️ 快捷键说明

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