]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.g2d/src/org/simantics/g2d/routing/algorithm2/Router2.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / routing / algorithm2 / Router2.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.g2d.routing.algorithm2;\r
13 \r
14 import java.awt.geom.AffineTransform;\r
15 import java.awt.geom.Path2D;\r
16 import java.awt.geom.PathIterator;\r
17 import java.awt.geom.Rectangle2D;\r
18 import java.util.Arrays;\r
19 \r
20 import org.simantics.g2d.routing.Constants;\r
21 import org.simantics.g2d.routing.IGraphModel;\r
22 import org.simantics.g2d.routing.IRouter;\r
23 import org.simantics.g2d.routing.Terminal;\r
24 \r
25 public class Router2 implements IRouter {\r
26 \r
27     static int getSomeDirection(int mask) {\r
28         if(mask == 0)\r
29             return 0;\r
30         int result = 0;\r
31         while((mask & 1) == 0) {\r
32             ++result;\r
33             mask >>= 1;\r
34         }\r
35         return result;\r
36     }\r
37     \r
38     @Override\r
39     public void update(IGraphModel model) {\r
40         LocalRouter localRouter = new LocalRouter(false);\r
41         for(Object c : model.getConnections()) {\r
42             Terminal begin = model.getBeginTerminal(c);        \r
43             Terminal end = model.getEndTerminal(c);\r
44             double[] points = model.getRoutePoints(c);\r
45             \r
46             if(begin == null) {\r
47                 if(points.length < 2)\r
48                         continue;\r
49                         begin = new Terminal(points[0], points[1], 0x1, Terminal.ZEROS, \r
50                                 new Rectangle2D.Double(points[0], points[1], 0.0, 0.0));\r
51                         points = Arrays.copyOfRange(points, 2, points.length);\r
52                 }\r
53                 if(end == null) {\r
54                         if(points.length < 2)\r
55                         continue;\r
56                         end = new Terminal(points[points.length-2], points[points.length-1], 0xf, Terminal.ZEROS,\r
57                                 new Rectangle2D.Double(points[points.length-2], points[points.length-1], 0.0, 0.0));\r
58                         points = Arrays.copyOf(points, points.length-2);\r
59                 }\r
60 \r
61                 double bestLength = Double.POSITIVE_INFINITY;\r
62                 Path2D bestPath = null;\r
63                 \r
64                 for(int sDir : Constants.POSSIBLE_DIRECTIONS[begin.directions])\r
65                         for(int tDir : Constants.POSSIBLE_DIRECTIONS[end.directions]) {\r
66                                 localRouter.sx = begin.x;\r
67                                 localRouter.sy = begin.y;\r
68                                 localRouter.aMinX = begin.parentObstacle.getMinX();\r
69                                 localRouter.aMinY = begin.parentObstacle.getMinY();\r
70                                 localRouter.aMaxX = begin.parentObstacle.getMaxX();\r
71                                 localRouter.aMaxY = begin.parentObstacle.getMaxY();\r
72                                 localRouter.sourceDirection = sDir;\r
73 \r
74                                 localRouter.tx = end.x;\r
75                                 localRouter.ty = end.y;\r
76                                 localRouter.bMinX = end.parentObstacle.getMinX();\r
77                                 localRouter.bMinY = end.parentObstacle.getMinY();\r
78                                 localRouter.bMaxX = end.parentObstacle.getMaxX();\r
79                                 localRouter.bMaxY = end.parentObstacle.getMaxY();\r
80                                 localRouter.targetDirection = tDir;\r
81 \r
82                                 localRouter.route();\r
83 \r
84                                 double length = pathLength(localRouter.path);\r
85                                 if(length < bestLength) {\r
86                                         bestLength = length;\r
87                                         bestPath = localRouter.path;\r
88                                 }  \r
89                         }\r
90             \r
91                 if(bestPath != null)\r
92                         model.setPath(c, bestPath);\r
93         }\r
94     }\r
95     \r
96     final static AffineTransform IDENTITY = new AffineTransform();\r
97 \r
98     static double pathLength(Path2D path) {\r
99         double length = 0.0;\r
100         PathIterator it = path.getPathIterator(IDENTITY);\r
101         double[] temp = new double[6];\r
102         double x=0.0, y=0.0;\r
103         double bendCount = 0.0;\r
104         while(!it.isDone()) {\r
105                 bendCount += 1.0;\r
106                 if(it.currentSegment(temp) != PathIterator.SEG_MOVETO)\r
107                         length += Math.abs(x - temp[0] + y - temp[1]);\r
108                 x = temp[0];\r
109                         y = temp[1];\r
110                         it.next();\r
111         }\r
112         return length * (6.0 + bendCount);\r
113     }\r
114     \r
115 }\r