1 /*******************************************************************************
\r
2 * Copyright (c) 2011 Association for Decentralized Information Management in
\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
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.diagram.connection;
\r
14 import gnu.trove.map.hash.THashMap;
\r
16 import java.io.PrintStream;
\r
17 import java.io.Serializable;
\r
18 import java.util.ArrayList;
\r
19 import java.util.Collection;
\r
20 import java.util.Collections;
\r
21 import java.util.List;
\r
23 import org.simantics.diagram.connection.segments.Segment;
\r
25 public class RouteLine implements RouteNode, Serializable {
\r
26 private static final long serialVersionUID = -7256429294500809465L;
\r
29 boolean isHorizontal;
\r
33 ArrayList<RoutePoint> points = new ArrayList<RoutePoint>(4);
\r
34 RouteLine nextTransient;
\r
35 RouteTerminal terminal;
\r
37 RouteLine(boolean isHorizontal, double position) {
\r
38 this.isHorizontal = isHorizontal;
\r
39 this.position = position;
\r
43 public void setData(Object data) {
\r
48 public Object getData() {
\r
52 public boolean isHorizontal() {
\r
53 return isHorizontal;
\r
56 public boolean isHidden() {
\r
60 public double getPosition() {
\r
64 public List<RoutePoint> getPoints() {
\r
65 if(RouteGraph.RETURN_UNMODIFIABLE_COLLECTIONS)
\r
66 return Collections.unmodifiableList(points);
\r
71 void addPoint(RoutePoint link) {
\r
76 for(RoutePoint point : points)
\r
77 point.removeFromOther(this);
\r
80 void setPointPositions() {
\r
82 for(RoutePoint point : points)
\r
86 for(RoutePoint point : points)
\r
92 Collections.sort(points, isHorizontal
\r
93 ? RoutePoint.X_COMPARATOR
\r
94 : RoutePoint.Y_COMPARATOR);
\r
97 public boolean isNear(double x2, double y2, double tolerance) {
\r
98 return isHorizontal
\r
99 ? Math.abs(y2-position) <= tolerance
\r
100 && points.get(0).x <= x2
\r
101 && x2 <= points.get(points.size()-1).x
\r
102 : Math.abs(x2-position) <= tolerance
\r
103 && points.get(0).y <= y2
\r
104 && y2 <= points.get(points.size()-1).y;
\r
107 public void print(PrintStream out) {
\r
112 for(RoutePoint point : points) {
\r
113 out.print(" ("+point.x+","+point.y+")");
\r
115 out.print(" (data=" + data + ")");
\r
119 void setLocation(double x, double y) {
\r
126 public double getLength() {
\r
128 return points.get(points.size()-1).x - points.get(0).x;
\r
130 return points.get(points.size()-1).y - points.get(0).y;
\r
133 boolean isConnectedToPeristentLine() {
\r
134 for(RoutePoint point : points)
\r
135 if(point instanceof RouteLink) {
\r
136 RouteLink link = (RouteLink)point;
\r
137 if(link.a == this) {
\r
138 if(!link.b.isTransient())
\r
142 if(!link.a.isTransient())
\r
149 public RoutePoint getBegin() {
\r
150 return points.get(0);
\r
153 public RoutePoint getEnd() {
\r
154 return points.get(points.size()-1);
\r
157 public boolean isTransient() {
\r
158 return terminal != null;
\r
161 RouteLine copy(THashMap<Object, Object> map) {
\r
162 RouteLine copy = (RouteLine)map.get(this);
\r
164 copy = new RouteLine(isHorizontal, position);
\r
165 map.put(this, copy);
\r
167 copy.nextTransient = nextTransient == null ? null : nextTransient.copy(map);
\r
168 copy.terminal = terminal == null ? null : terminal.copy(map);
\r
169 for(RoutePoint point : points)
\r
170 copy.points.add(point.copy(map));
\r
175 public Collection<RouteLine> getPersistentNeighbors() {
\r
176 ArrayList<RouteLine> lines = new ArrayList<RouteLine>();
\r
177 for(RoutePoint point : points)
\r
178 if(point instanceof RouteLink) {
\r
179 RouteLink link = (RouteLink)point;
\r
180 RouteLine line = link.getOther(this);
\r
181 if(!line.isTransient())
\r
187 public RouteTerminal getTerminal() {
\r
191 public boolean beginsWithTerminal() {
\r
192 RoutePoint begin = points.get(0);
\r
193 if(begin == terminal)
\r
195 else if(begin instanceof RouteLink) {
\r
196 RouteLink link = (RouteLink)begin;
\r
198 return link.b.hasTerminal(link, terminal);
\r
200 return link.a.hasTerminal(link, terminal);
\r
206 private boolean hasTerminal(RouteLink oldLink, RouteTerminal terminal) {
\r
207 RoutePoint begin = points.get(0);
\r
208 RoutePoint end = points.get(1);
\r
209 if(begin == terminal || end == terminal)
\r
211 if(begin instanceof RouteLink && begin != oldLink) {
\r
212 RouteLink link = (RouteLink)begin;
\r
214 return link.b.hasTerminal(link, terminal);
\r
216 return link.a.hasTerminal(link, terminal);
\r
218 else if(end instanceof RouteLink && end != oldLink) {
\r
219 RouteLink link = (RouteLink)end;
\r
221 return link.b.hasTerminal(link, terminal);
\r
223 return link.a.hasTerminal(link, terminal);
\r
229 public boolean isDegenerated() {
\r
230 if(points.size() <= 1)
\r
233 return points.get(0).x == points.get(points.size()-1).x;
\r
235 return points.get(0).y == points.get(points.size()-1).y;
\r
238 public void collectSegments(ArrayList<Segment> segments) {
\r
239 RoutePoint p0 = points.get(0);
\r
240 for(int i=1;i<points.size();++i) {
\r
241 RoutePoint p1 = points.get(i);
\r
242 segments.add(new Segment(p0, p1));
\r