1 /*******************************************************************************
2 * Copyright (c) 2011 Association for Decentralized Information Management in
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.diagram.connection;
14 import gnu.trove.map.hash.THashMap;
16 import java.io.PrintStream;
17 import java.io.Serializable;
18 import java.util.ArrayList;
19 import java.util.Collection;
20 import java.util.Collections;
21 import java.util.List;
23 import org.simantics.diagram.connection.segments.Segment;
25 public class RouteLine implements RouteNode, Serializable {
26 private static final long serialVersionUID = -7256429294500809465L;
33 ArrayList<RoutePoint> points = new ArrayList<RoutePoint>(4);
34 RouteLine nextTransient;
35 RouteTerminal terminal;
37 public RouteLine(boolean isHorizontal, double position) {
38 this.isHorizontal = isHorizontal;
39 this.position = position;
43 public void setData(Object data) {
48 public Object getData() {
52 public boolean isHorizontal() {
56 public boolean isHidden() {
60 public void setHidden(boolean hidden) {
64 public double getPosition() {
68 public List<RoutePoint> getPoints() {
69 if(RouteGraph.RETURN_UNMODIFIABLE_COLLECTIONS)
70 return Collections.unmodifiableList(points);
75 public void addPoint(RoutePoint link) {
80 for(RoutePoint point : points)
81 point.removeFromOther(this);
84 public void setPointPositions() {
86 for(RoutePoint point : points)
90 for(RoutePoint point : points)
95 public void sortPoints() {
96 Collections.sort(points, isHorizontal
97 ? RoutePoint.X_COMPARATOR
98 : RoutePoint.Y_COMPARATOR);
101 public boolean isNear(double x2, double y2, double tolerance) {
103 ? Math.abs(y2-position) <= tolerance
104 && points.get(0).x - tolerance <= x2
105 && x2 <= points.get(points.size()-1).x + tolerance
106 : Math.abs(x2-position) <= tolerance
107 && points.get(0).y - tolerance <= y2
108 && y2 <= points.get(points.size()-1).y + tolerance;
111 public void print(PrintStream out) {
116 for(RoutePoint point : points) {
117 out.print(" ("+point.x+","+point.y+")");
119 out.print(" (data=" + data + ")");
123 void setLocation(double x, double y) {
130 public double getLength() {
132 return points.get(points.size()-1).x - points.get(0).x;
134 return points.get(points.size()-1).y - points.get(0).y;
137 boolean isConnectedToPeristentLine() {
138 for(RoutePoint point : points)
139 if(point instanceof RouteLink) {
140 RouteLink link = (RouteLink)point;
142 if(!link.b.isTransient())
146 if(!link.a.isTransient())
153 public RoutePoint getBegin() {
154 return points.get(0);
157 public RoutePoint getEnd() {
158 return points.get(points.size()-1);
161 public boolean isTransient() {
162 return terminal != null;
165 public RouteLine copy(THashMap<Object, Object> map) {
166 RouteLine copy = (RouteLine)map.get(this);
168 copy = new RouteLine(isHorizontal, position);
171 copy.nextTransient = nextTransient == null ? null : nextTransient.copy(map);
172 copy.terminal = terminal == null ? null : terminal.copy(map);
173 for(RoutePoint point : points)
174 copy.points.add(point.copy(map));
179 public Collection<RouteLine> getPersistentNeighbors() {
180 ArrayList<RouteLine> lines = new ArrayList<RouteLine>();
181 for(RoutePoint point : points)
182 if(point instanceof RouteLink) {
183 RouteLink link = (RouteLink)point;
184 RouteLine line = link.getOther(this);
185 if(!line.isTransient())
191 public void removeRouteTerminals() {
192 points.removeIf(p -> p instanceof RouteTerminal);
195 public RouteTerminal getTerminal() {
199 public void setTerminal(RouteTerminal terminal) {
200 this.terminal = terminal;
203 public RouteLine getNextTransient() {
204 return nextTransient;
207 public boolean beginsWithTerminal() {
208 RoutePoint begin = points.get(0);
209 if(begin == terminal)
211 else if(begin instanceof RouteLink) {
212 RouteLink link = (RouteLink)begin;
214 return link.b.hasTerminal(link, terminal);
216 return link.a.hasTerminal(link, terminal);
222 private boolean hasTerminal(RouteLink oldLink, RouteTerminal terminal) {
223 RoutePoint begin = points.get(0);
224 RoutePoint end = points.get(1);
225 if(begin == terminal || end == terminal)
227 if(begin instanceof RouteLink && begin != oldLink) {
228 RouteLink link = (RouteLink)begin;
230 return link.b.hasTerminal(link, terminal);
232 return link.a.hasTerminal(link, terminal);
234 else if(end instanceof RouteLink && end != oldLink) {
235 RouteLink link = (RouteLink)end;
237 return link.b.hasTerminal(link, terminal);
239 return link.a.hasTerminal(link, terminal);
245 public boolean isDegenerated() {
246 if(points.size() <= 1)
249 return points.get(0).x == points.get(points.size()-1).x;
251 return points.get(0).y == points.get(points.size()-1).y;
254 public void collectSegments(ArrayList<Segment> segments) {
255 RoutePoint p0 = points.get(0);
256 for(int i=1;i<points.size();++i) {
257 RoutePoint p1 = points.get(i);
258 segments.add(new Segment(p0, p1));