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 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 double getPosition() {
64 public List<RoutePoint> getPoints() {
65 if(RouteGraph.RETURN_UNMODIFIABLE_COLLECTIONS)
66 return Collections.unmodifiableList(points);
71 void addPoint(RoutePoint link) {
76 for(RoutePoint point : points)
77 point.removeFromOther(this);
80 void setPointPositions() {
82 for(RoutePoint point : points)
86 for(RoutePoint point : points)
92 Collections.sort(points, isHorizontal
93 ? RoutePoint.X_COMPARATOR
94 : RoutePoint.Y_COMPARATOR);
97 public boolean isNear(double x2, double y2, double tolerance) {
99 ? Math.abs(y2-position) <= tolerance
100 && points.get(0).x <= x2
101 && x2 <= points.get(points.size()-1).x
102 : Math.abs(x2-position) <= tolerance
103 && points.get(0).y <= y2
104 && y2 <= points.get(points.size()-1).y;
107 public void print(PrintStream out) {
112 for(RoutePoint point : points) {
113 out.print(" ("+point.x+","+point.y+")");
115 out.print(" (data=" + data + ")");
119 void setLocation(double x, double y) {
126 public double getLength() {
128 return points.get(points.size()-1).x - points.get(0).x;
130 return points.get(points.size()-1).y - points.get(0).y;
133 boolean isConnectedToPeristentLine() {
134 for(RoutePoint point : points)
135 if(point instanceof RouteLink) {
136 RouteLink link = (RouteLink)point;
138 if(!link.b.isTransient())
142 if(!link.a.isTransient())
149 public RoutePoint getBegin() {
150 return points.get(0);
153 public RoutePoint getEnd() {
154 return points.get(points.size()-1);
157 public boolean isTransient() {
158 return terminal != null;
161 RouteLine copy(THashMap<Object, Object> map) {
162 RouteLine copy = (RouteLine)map.get(this);
164 copy = new RouteLine(isHorizontal, position);
167 copy.nextTransient = nextTransient == null ? null : nextTransient.copy(map);
168 copy.terminal = terminal == null ? null : terminal.copy(map);
169 for(RoutePoint point : points)
170 copy.points.add(point.copy(map));
175 public Collection<RouteLine> getPersistentNeighbors() {
176 ArrayList<RouteLine> lines = new ArrayList<RouteLine>();
177 for(RoutePoint point : points)
178 if(point instanceof RouteLink) {
179 RouteLink link = (RouteLink)point;
180 RouteLine line = link.getOther(this);
181 if(!line.isTransient())
187 public RouteTerminal getTerminal() {
191 public boolean beginsWithTerminal() {
192 RoutePoint begin = points.get(0);
193 if(begin == terminal)
195 else if(begin instanceof RouteLink) {
196 RouteLink link = (RouteLink)begin;
198 return link.b.hasTerminal(link, terminal);
200 return link.a.hasTerminal(link, terminal);
206 private boolean hasTerminal(RouteLink oldLink, RouteTerminal terminal) {
207 RoutePoint begin = points.get(0);
208 RoutePoint end = points.get(1);
209 if(begin == terminal || end == terminal)
211 if(begin instanceof RouteLink && begin != oldLink) {
212 RouteLink link = (RouteLink)begin;
214 return link.b.hasTerminal(link, terminal);
216 return link.a.hasTerminal(link, terminal);
218 else if(end instanceof RouteLink && end != oldLink) {
219 RouteLink link = (RouteLink)end;
221 return link.b.hasTerminal(link, terminal);
223 return link.a.hasTerminal(link, terminal);
229 public boolean isDegenerated() {
230 if(points.size() <= 1)
233 return points.get(0).x == points.get(points.size()-1).x;
235 return points.get(0).y == points.get(points.size()-1).y;
238 public void collectSegments(ArrayList<Segment> segments) {
239 RoutePoint p0 = points.get(0);
240 for(int i=1;i<points.size();++i) {
241 RoutePoint p1 = points.get(i);
242 segments.add(new Segment(p0, p1));