25
25
package com.sun.electric.tool.routing;
27
27
import com.sun.electric.database.EditingPreferences;
28
import com.sun.electric.database.geometry.*;
28
import com.sun.electric.database.geometry.DBMath;
29
import com.sun.electric.database.geometry.Dimension2D;
30
import com.sun.electric.database.geometry.EPoint;
31
import com.sun.electric.database.geometry.GenMath;
32
import com.sun.electric.database.geometry.Poly;
33
import com.sun.electric.database.geometry.PolyMerge;
29
34
import com.sun.electric.database.hierarchy.Cell;
30
35
import com.sun.electric.database.hierarchy.Export;
36
import com.sun.electric.database.prototype.NodeProto;
31
37
import com.sun.electric.database.prototype.PortProto;
32
import com.sun.electric.database.prototype.NodeProto;
33
import com.sun.electric.database.topology.*;
38
import com.sun.electric.database.topology.ArcInst;
39
import com.sun.electric.database.topology.Connection;
40
import com.sun.electric.database.topology.NodeInst;
41
import com.sun.electric.database.topology.PortInst;
34
42
import com.sun.electric.database.variable.ElectricObject;
35
import com.sun.electric.technology.*;
43
import com.sun.electric.technology.ArcProto;
44
import com.sun.electric.technology.Layer;
45
import com.sun.electric.technology.PrimitiveNode;
46
import com.sun.electric.technology.SizeOffset;
36
47
import com.sun.electric.technology.technologies.Artwork;
48
import com.sun.electric.tool.Job;
37
49
import com.sun.electric.tool.JobException;
38
import com.sun.electric.tool.Job;
39
50
import com.sun.electric.tool.user.CircuitChangeJobs;
40
import com.sun.electric.tool.user.Highlight2;
51
import com.sun.electric.tool.user.Highlight;
41
52
import com.sun.electric.tool.user.Highlighter;
42
53
import com.sun.electric.tool.user.ui.EditWindow;
43
import com.sun.electric.tool.user.ui.ClickZoomWireListener;
45
55
import java.awt.geom.Line2D;
46
56
import java.awt.geom.Point2D;
47
57
import java.awt.geom.Rectangle2D;
48
58
import java.util.ArrayList;
59
import java.util.Iterator;
49
60
import java.util.List;
50
import java.util.Iterator;
53
63
* An Interactive Router has several methods that build on Router
134
144
public void makeRoute(EditWindow wnd, Cell cell, ElectricObject startObj, ElectricObject endObj, Point2D clicked) {
135
145
if (!started) startInteractiveRoute(wnd);
136
146
// plan the route
137
Route route = planRoute(cell, startObj, endObj, clicked, null, true, true);
147
Route route = planRoute(cell, startObj, endObj, clicked, null, true, true, null, null);
138
148
// restore highlights at start of planning, so that
139
149
// they will correctly show up if this job is undone.
140
150
wnd.clearHighlighting();
173
183
ArcProto startArc = vroute.getStartArc();
174
184
ArcProto endArc = vroute.getEndArc();
176
ContactSize sizer = new ContactSize(startPort, null, startLoc, startLoc, startLoc, startArc, endArc, false);
186
EditingPreferences ep = EditingPreferences.getThreadEditingPreferences();
187
ContactSize sizer = new ContactSize(startPort, null, startLoc, startLoc, startLoc, startArc, endArc, false, ep.fatWires);
177
188
Rectangle2D contactArea = sizer.getContactSize();
178
189
Dimension2D contactSize = new Dimension2D.Double(contactArea.getWidth(), contactArea.getHeight());
179
190
int startAngle = sizer.getStartAngle();
270
281
* if the user is drawing to empty space.
271
282
* @param clicked the point where the user clicked
272
283
* @param stayInside the area in which to route (null if not applicable).
273
* @param extendArcHead true to use default arc extension; false to force no arc extension.
274
* @param extendArcTail true to use default arc extension; false to force no arc extension.
275
* @return a List of RouteElements denoting route
277
public Route planRoute(Cell cell, ElectricObject startObj, ElectricObject endObj, Point2D clicked, PolyMerge stayInside,
278
boolean extendArcHead, boolean extendArcTail) {
279
return planRoute(cell, startObj, endObj, clicked, stayInside, extendArcHead, extendArcTail, null);
283
* Plan a route from startObj to endObj, taking into account
284
* where the user clicked in the cell.
285
* @param cell the cell in which to create the arc
286
* @param startObj a PortInst or ArcInst from which to start the route
287
* @param endObj a PortInst or ArcInst to end the route on. May be null
288
* if the user is drawing to empty space.
289
* @param clicked the point where the user clicked
290
* @param stayInside the area in which to route (null if not applicable).
291
* @param extendArcHead true to use default arc extension; false to force no arc extension.
292
* @param extendArcTail true to use default arc extension; false to force no arc extension.
293
* @return a List of RouteElements denoting route
295
public Route planRoute(Cell cell, ElectricObject startObj, ElectricObject endObj, Point2D clicked, PolyMerge stayInside,
296
boolean extendArcHead, boolean extendArcTail, Rectangle2D contactArea) {
284
* @param extendArcHead true to use default arc extension; false to force no arc extension. (head connects to startObj).
285
* @param extendArcTail true to use default arc extension; false to force no arc extension. (tail connects to endObj).
287
* @param alignment edge alignment factors (null for no alignment).
288
* @return a List of RouteElements denoting route
290
public Route planRoute(Cell cell, ElectricObject startObj, ElectricObject endObj, Point2D clicked, PolyMerge stayInside,
291
boolean extendArcHead, boolean extendArcTail, Rectangle2D contactArea, Dimension2D alignment)
298
293
EditingPreferences ep = cell.getEditingPreferences();
299
294
Route route = new Route(); // hold the route
300
295
if (cell == null) return route;
336
336
double startArcWidth = 0;
337
337
double endArcWidth = 0;
339
if (!ClickZoomWireListener.theOne.getUseFatWiringMode()) {
340
340
// if not using fat wiring mode, determine arc sizes now, and
341
341
// start and end points based off of arc sizes and startObj and endObj port sizes
342
startArcWidth = getArcWidthToUse(startObj, startArc, 0, true);
343
endArcWidth = (endObj == null) ? startArcWidth : getArcWidthToUse(endObj, endArc, 0, true);
342
startArcWidth = getArcWidthToUse(startObj, startArc, 0, true, ep.fatWires);
343
endArcWidth = (endObj == null) ? startArcWidth : getArcWidthToUse(endObj, endArc, 0, true, ep.fatWires);
344
344
if (startArc == endArc) {
345
345
if (startArcWidth > endArcWidth) endArcWidth = startArcWidth;
346
346
if (endArcWidth > startArcWidth) startArcWidth = endArcWidth;
363
363
// arc(s) should connect
364
364
Point2D startPoint = new Point2D.Double(0, 0);
365
365
Point2D endPoint = new Point2D.Double(0,0);
366
getConnectingPoints(startObj, endObj, clicked, startPoint, endPoint, startPoly, endPoly, startArc, endArc);
366
getConnectingPoints(startObj, endObj, clicked, startPoint, endPoint, startPoly, endPoly,
367
startArc, endArc, alignment, ep.fatWires);
368
369
PortInst existingStartPort = null;
369
370
PortInst existingEndPort = null;
483
490
// create arc between startRE and start of vertical route
484
491
addConnectingArc(route, cell, startRE, vertRoute.getStart(), startPoint, cornerLoc, startArc,
485
startArcWidth, startAngle, extendArcHead, extendArcTail, stayInside);
492
startArcWidth, startAngle, extendArcHead, extendArcTail, stayInside, alignment);
487
494
// replace endpoints if possible (remove redundant pins), endRE
488
495
if (route.replacePin(endRE, vertRoute.getEnd(), stayInside)) {
519
526
defwidth, defheight);
520
527
route.add(pinRE);
521
528
addConnectingArc(route, cell, startRE, pinRE, startPoint, cornerLoc, startArc,
522
startArcWidth, startAngle, extendArcHead, extendArcTail, stayInside);
529
startArcWidth, startAngle, extendArcHead, extendArcTail, stayInside, alignment);
523
530
addConnectingArc(route, cell, endRE, pinRE, endPoint, cornerLoc, endArc,
524
endArcWidth, endAngle, extendArcHead, extendArcTail, stayInside);
531
endArcWidth, endAngle, extendArcHead, extendArcTail, stayInside, alignment);
609
616
* @param endPoly valid port site on endObj
610
617
* @param startArc the arc type to connect to startObj
611
618
* @param endArc the arc type to connect to endObj
619
* @param fatWiringMode true to make arcs as wide as their connecting nodes.
613
621
protected static void getConnectingPoints(ElectricObject startObj, ElectricObject endObj, Point2D clicked,
614
622
Point2D startPoint, Point2D endPoint, Poly startPoly, Poly endPoly,
615
ArcProto startArc, ArcProto endArc) {
623
ArcProto startArc, ArcProto endArc, Dimension2D alignment, boolean fatWiringMode) {
625
if (alignment == null) alignment = new Dimension2D.Double(0, 0);
617
626
/* Point2D[] points = startPoly.getPoints();
618
627
System.out.print("StartPoly: ");
619
628
for (int i=0; i<points.length; i++) {
643
// just go by bounds for now
644
Rectangle2D startBounds = startPoly.getBounds2D();
645
// default is center point
646
startPoint.setLocation(startBounds.getCenterX(), startBounds.getCenterY());
652
// default is center point, aligned to grid
653
Rectangle2D startBounds = new Rectangle2D.Double(startPoly.getBounds2D().getX(), startPoly.getBounds2D().getY(),
654
startPoly.getBounds2D().getWidth(), startPoly.getBounds2D().getHeight());
655
getAlignedCenter(startBounds, alignment, startPoint);
648
657
// if startObj is arc inst
649
658
if (startObj instanceof ArcInst) {
651
660
// if nothing to connect to, clicked will determine connecting point on startPoly
652
661
// endPoint will be location of new pin
653
x = getClosestValue(startBounds.getMinX(), startBounds.getMaxX(), clicked.getX());
654
y = getClosestValue(startBounds.getMinY(), startBounds.getMaxY(), clicked.getY());
662
x = getClosestValue(startBounds.getMinX(), startBounds.getMaxX(), clicked.getX(), alignment.getWidth());
663
y = getClosestValue(startBounds.getMinY(), startBounds.getMaxY(), clicked.getY(), alignment.getHeight());
655
664
startPoint.setLocation(x, y);
670
Rectangle2D endBounds = endPoly.getBounds2D();
671
endPoint.setLocation(endBounds.getCenterX(), endBounds.getCenterY());
679
Rectangle2D endBounds = new Rectangle2D.Double(endPoly.getBounds2D().getX(), endPoly.getBounds2D().getY(),
680
endPoly.getBounds2D().getWidth(), endPoly.getBounds2D().getHeight());
681
getAlignedCenter(endBounds, alignment, endPoint);
673
683
if (endObj instanceof ArcInst) {
675
685
// if nothing to connect to, clicked will determine connecting point on startPoly
676
686
// endPoint will be location of new pin
677
x = getClosestValue(endBounds.getMinX(), endBounds.getMaxX(), clicked.getX());
678
y = getClosestValue(endBounds.getMinY(), endBounds.getMaxY(), clicked.getY());
687
x = getClosestValue(endBounds.getMinX(), endBounds.getMaxX(), clicked.getX(), alignment.getWidth());
688
y = getClosestValue(endBounds.getMinY(), endBounds.getMaxY(), clicked.getY(), alignment.getHeight());
679
689
endPoint.setLocation(x, y);
694
704
if (startArc == endArc && startObjBounds.intersects(endObjBounds))
695
705
objsOverlap = true;
707
// grid align if needed
708
Point2D startCenter = new Point2D.Double(startBounds.getCenterX(), startBounds.getCenterY());
709
Point2D endCenter = new Point2D.Double(endBounds.getCenterX(), endBounds.getCenterY());
710
gridAlignWithinBounds(startCenter, startBounds, alignment);
711
gridAlignWithinBounds(endCenter, endBounds, alignment);
697
713
// normally we route center to center (for PortInsts) in fat wiring mode,
698
714
// but if the objects overlap (both ports and objects themselves, then we will route directly
699
715
if (!objsOverlap || !overlapX) {
700
716
// center X on both objects (if they are port insts)
701
717
if (startObj instanceof PortInst) {
702
startBounds.setRect(startBounds.getCenterX(), startBounds.getY(), 0, startBounds.getHeight());
718
startBounds.setRect(startCenter.getX(), startBounds.getY(), 0, startBounds.getHeight());
704
720
if (endObj instanceof PortInst) {
705
endBounds.setRect(endBounds.getCenterX(), endBounds.getY(), 0, endBounds.getHeight());
721
endBounds.setRect(endCenter.getX(), endBounds.getY(), 0, endBounds.getHeight());
708
724
if (!objsOverlap || !overlapY) {
709
725
// center Y on both objects (if they are port insts)
710
726
if (startObj instanceof PortInst) {
711
startBounds.setRect(startBounds.getX(), startBounds.getCenterY(), startBounds.getWidth(), 0);
727
startBounds.setRect(startBounds.getX(), startCenter.getY(), startBounds.getWidth(), 0);
713
729
if (endObj instanceof PortInst) {
714
endBounds.setRect(endBounds.getX(), endBounds.getCenterY(), endBounds.getWidth(), 0);
730
endBounds.setRect(endBounds.getX(), endCenter.getY(), endBounds.getWidth(), 0);
717
733
// recalculate overlaps in case bounds have changed
777
792
endPoint.setLocation(endPoint.getX(), endBounds.getMinY());
795
if (alignment.getWidth() > 0 && alignment.getHeight() > 0) {
796
if (startPoint.getX() % alignment.getWidth() != 0 || endPoint.getX() % alignment.getWidth() != 0 ||
797
startPoint.getY() % alignment.getHeight() != 0 || endPoint.getY() % alignment.getHeight() != 0) {
798
System.out.println("start and end points not aligned");
804
* Grid align the point within the confine of bounds. This assumes the point is already within the bounds.
805
* @param pt the point to align
806
* @param bounds the bounds within to align
807
* @param alignment the alignment
809
private static void gridAlignWithinBounds(Point2D pt, Rectangle2D bounds, Dimension2D alignment)
811
if (alignment == null) return;
812
double x = pt.getX();
813
double y = pt.getY();
814
if (alignment.getWidth() > 0) {
815
double xfloor = Math.floor(x/alignment.getWidth()) * alignment.getWidth();
816
double xceil = Math.ceil(x/alignment.getWidth()) * alignment.getWidth();
817
if (xfloor >= bounds.getMinX() && xfloor <= bounds.getMaxX()) {
819
} else if (xceil >= bounds.getMinX() && xceil <= bounds.getMaxX()) {
823
if (alignment.getHeight() > 0) {
824
double yfloor = Math.floor(y/alignment.getHeight()) * alignment.getHeight();
825
double yceil = Math.ceil(y/alignment.getHeight()) * alignment.getHeight();
826
if (yfloor >= bounds.getMinY() && yfloor <= bounds.getMaxY()) {
828
} else if (yceil >= bounds.getMinY() && yceil <= bounds.getMaxY()) {
832
pt.setLocation(x, y);
836
* Method to find the center of a Rectangle, grid aligned, and to grid-align the rectangle.
837
* @param bounds the rectangle to evaluate and align.
838
* @param alignment the alignment in X and Y.
839
* @param ctr the center point is stored here.
841
private static void getAlignedCenter(Rectangle2D bounds, Dimension2D alignment, Point2D ctr)
843
double cX = bounds.getCenterX();
844
double cY = bounds.getCenterY();
845
if (alignment != null)
847
if (alignment.getWidth() > 0)
849
double xx = cX / alignment.getWidth();
850
long xxL = Math.round(xx);
853
double newX = xxL * alignment.getWidth();
854
if (newX >= bounds.getMinX() && newX <= bounds.getMaxX()) cX = newX;
856
double lX = Math.ceil(bounds.getMinX() / alignment.getWidth()) * alignment.getWidth();
857
double hX = Math.floor(bounds.getMaxX() / alignment.getWidth()) * alignment.getWidth();
858
if (lX <= bounds.getMaxX() && hX >= bounds.getMinX())
859
bounds.setRect(lX, bounds.getMinY(), hX-lX, bounds.getHeight());
861
if (alignment.getHeight() > 0)
863
double yy = cY / alignment.getHeight();
864
long yyL = Math.round(yy);
867
double newY = yyL * alignment.getHeight();
868
if (newY >= bounds.getMinY() && newY <= bounds.getMaxY()) cY = newY;
870
double lY = Math.ceil(bounds.getMinY() / alignment.getHeight()) * alignment.getHeight();
871
double hY = Math.floor(bounds.getMaxY() / alignment.getHeight()) * alignment.getHeight();
872
if (lY <= bounds.getMaxY() && hY >= bounds.getMinY())
873
bounds.setRect(bounds.getMinX(), lY, bounds.getWidth(), hY-lY);
876
ctr.setLocation(cX, cY);
783
880
* Get the intersection point of the two line segments, or null if none
784
* @param line1 line 1
785
* @param line2 line 2
881
* @param points1 An array of two points that define line 1
882
* @param points2 An array of two points that define line 2
786
883
* @return the intersection point, or null if none
788
public static Point2D getIntersection(Line2D line1, Line2D line2) {
885
public static Point2D getIntersection(Point2D [] points1, Point2D [] points2) {
886
// Checking if line1 is not a singular point
887
if (DBMath.areEquals(points1[0], points1[1]) || DBMath.areEquals(points2[0], points2[1]))
890
System.out.println("Line is a singular point in InteractiveRouter.getIntersection");
893
Line2D line1 = new Line2D.Double(points1[0], points1[1]);
894
Line2D line2 = new Line2D.Double(points2[0], points2[1]);
789
896
if (!line1.intersectsLine(line2))
791
898
double [] co1 = getLineCoeffs(line1);
792
899
double [] co2 = getLineCoeffs(line2);
793
900
// det = A1*B2 - A2*B1
794
902
double det = co1[0]*co2[1] - co2[0]*co1[1];
795
// if det == 0, lines are parallel, but already checked by intersection check above
905
// lines are parallel. Since they already passed the "intersection" test, they must meet at an end
906
if (points1[0].getX() == points2[0].getX() && points1[0].getY() == points2[0].getY()) return points1[0];
907
if (points1[0].getX() == points2[1].getX() && points1[0].getY() == points2[1].getY()) return points1[0];
908
if (points1[1].getX() == points2[0].getX() && points1[1].getY() == points2[0].getY()) return points1[1];
909
if (points1[1].getX() == points2[1].getX() && points1[1].getY() == points2[1].getY()) return points1[1];
796
913
// x = (B2*C1 - B1*C2)/det
797
914
double x = (co2[1]*co1[2] - co1[1]*co2[2])/det;
798
916
// y = (A1*C2 - A2*C1)/det
799
917
double y = (co1[0]*co2[2] - co2[0]*co1[2])/det;
800
918
return new Point2D.Double(x, y);
954
1072
* @param arc the arc to draw from/to
955
1073
* @param connectingPoint point on or near arc
956
1074
* @param stayInside the area in which to route (null if not applicable).
1075
* @param alignment if non-null, alignment to align to
957
1076
* @return a RouteElement holding the new pin at the bisection
958
1077
* point, or a RouteElement holding an existingPortInst if
959
1078
* drawing from either end of the ArcInst.
961
protected RouteElementPort findArcConnectingPoint(Route route, ArcInst arc, Point2D connectingPoint, PolyMerge stayInside) {
1080
protected RouteElementPort findArcConnectingPoint(Route route, ArcInst arc, Point2D connectingPoint, PolyMerge stayInside, Dimension2D alignment) {
963
1082
EPoint head = arc.getHeadLocation();
964
1083
EPoint tail = arc.getTailLocation();
1015
1135
name2 = nameToUse;
1017
1137
// add two arcs to rebuild old startArc
1138
boolean extendArcFromHeadSide = getExtendArcEnd(newPinRE, bisectPoint, arc.getLambdaBaseWidth(), arc.getProto(),
1139
arc.getAngle(), arc.isTailExtended(), alignment);
1140
boolean extendArcFromTailSide = getExtendArcEnd(newPinRE, bisectPoint, arc.getLambdaBaseWidth(), arc.getProto(),
1141
arc.getAngle(), arc.isHeadExtended(), alignment);
1018
1142
RouteElement newHeadArcRE = RouteElementArc.newArc(cell, arc.getProto(), arc.getLambdaBaseWidth(), headRE, newPinRE,
1019
head, bisectPoint, name1, arc.getTextDescriptor(ArcInst.ARC_NAME), arc, arc.isHeadExtended(), arc.isTailExtended(), stayInside);
1143
head, bisectPoint, name1, arc.getTextDescriptor(ArcInst.ARC_NAME), arc, arc.isHeadExtended(), extendArcFromHeadSide, stayInside);
1020
1144
RouteElement newTailArcRE = RouteElementArc.newArc(cell, arc.getProto(), arc.getLambdaBaseWidth(), newPinRE, tailRE,
1021
bisectPoint, tail, name2, arc.getTextDescriptor(ArcInst.ARC_NAME), arc, arc.isHeadExtended(), arc.isTailExtended(), stayInside);
1145
bisectPoint, tail, name2, arc.getTextDescriptor(ArcInst.ARC_NAME), arc, extendArcFromTailSide, arc.isTailExtended(), stayInside);
1022
1146
newHeadArcRE.setShowHighlight(false);
1023
1147
newTailArcRE.setShowHighlight(false);
1024
1148
// delete old arc
1036
1160
protected static Point2D getCornerLocation(Point2D startLoc, Point2D endLoc, Point2D clicked, ArcProto startArc, ArcProto endArc,
1037
1161
boolean contactsOnEndObj, PolyMerge stayInside, Rectangle2D contactArea,
1038
1162
Poly startPolyFull, Poly endPolyFull, EditingPreferences ep) {
1163
// connection point specified by contactArea
1164
if (contactArea != null) {
1165
return new Point2D.Double(contactArea.getCenterX(), contactArea.getCenterY());
1039
1168
// if startArc and endArc are the same, see if we can connect directly with whatever angle increment is on the arc
1040
1169
boolean singleArc = false;
1041
1170
if (startArc == endArc) {
1129
1253
protected static void addConnectingArc(Route route, Cell cell, RouteElementPort startRE, RouteElementPort endRE,
1130
1254
Point2D startPoint, Point2D endPoint,
1131
1255
ArcProto arc, double width, int arcAngle, boolean extendArcHead,
1132
boolean extendArcTail, PolyMerge stayInside) {
1256
boolean extendArcTail, PolyMerge stayInside, Dimension2D alignment) {
1134
if (extendArcHead) extendArcHead = getExtendArcEnd(startRE, width, arc, arcAngle, extendArcHead);
1135
if (extendArcTail) extendArcTail = getExtendArcEnd(endRE, width, arc, arcAngle, extendArcTail);
1258
if (extendArcHead) extendArcHead = getExtendArcEnd(startRE, startPoint, width, arc, arcAngle, extendArcHead, alignment);
1259
if (extendArcTail) extendArcTail = getExtendArcEnd(endRE, endPoint, width, arc, arcAngle, extendArcTail, alignment);
1136
1260
RouteElementArc reArc = RouteElementArc.newArc(cell, arc, width, startRE, endRE, startPoint, endPoint,
1137
1261
null, null, null, extendArcHead, extendArcTail, stayInside);
1138
1262
reArc.setArcAngle(arcAngle);
1139
1263
route.add(reArc);
1142
protected static boolean getExtendArcEnd(RouteElementPort re, double arcWidth, ArcProto arc, int arcAngle, boolean defExtends) {
1266
protected static boolean getExtendArcEnd(RouteElementPort re, Point2D point, double arcWidth, ArcProto arc, int arcAngle, boolean defExtends, Dimension2D alignment) {
1143
1267
NodeProto np = re.getNodeProto();
1144
1268
if (np == null) return defExtends;
1152
1276
// if (pn.getFunction() == PrimitiveNode.Function.PIN) {
1153
1277
// checkAttachedArcs = true;
1155
if (pn.getFunction() == PrimitiveNode.Function.CONTACT) {
1279
if (pn.getFunction().isContact()) {
1156
1280
Dimension2D size = re.getNodeSize();
1157
1281
if (arcAngle % 1800 == 0) {
1282
if (arcWidth > size.getWidth()) return false;
1284
if ((arcAngle+900) % 1800 == 0) {
1158
1285
if (arcWidth > size.getHeight()) return false;
1160
if ((arcAngle+900) % 1800 == 0) {
1161
if (arcWidth > size.getWidth()) return false;
1289
if (alignment != null) {
1290
if (arcAngle % 1800 == 0) {
1292
if (isNumberAligned(point.getX(), alignment.getWidth()) &&
1293
!isNumberAligned(point.getX() + arcWidth/2, alignment.getWidth()))
1295
if (!isNumberAligned(point.getX(), alignment.getWidth()) &&
1296
isNumberAligned(point.getX() + arcWidth/2, alignment.getWidth()))
1299
if ((arcAngle+900) % 1800 == 0) {
1301
if (isNumberAligned(point.getY(), alignment.getHeight()) &&
1302
!isNumberAligned(point.getY() + arcWidth/2, alignment.getHeight()))
1304
if (!isNumberAligned(point.getY(), alignment.getHeight()) &&
1305
isNumberAligned(point.getY() + arcWidth/2, alignment.getHeight()))
1166
1311
if (checkAttachedArcs && re.getPortInst() != null) {
1167
1312
double attachedWidth = getArcWidthToUse(re.getPortInst(), arc, arcAngle);