1 package org.opentrafficsim.core.network.animation;
2
3 import java.awt.Color;
4 import java.awt.Graphics2D;
5 import java.awt.image.ImageObserver;
6 import java.io.Serializable;
7 import java.rmi.RemoteException;
8
9 import javax.naming.NamingException;
10
11 import org.opentrafficsim.core.animation.ClonableRenderable2DInterface;
12 import org.opentrafficsim.core.animation.TextAlignment;
13 import org.opentrafficsim.core.animation.TextAnimation;
14 import org.opentrafficsim.core.geometry.OTSGeometryException;
15 import org.opentrafficsim.core.geometry.OTSLine3D;
16 import org.opentrafficsim.core.geometry.OTSPoint3D;
17 import org.opentrafficsim.core.logger.SimLogger;
18 import org.opentrafficsim.core.network.Link;
19
20 import nl.tudelft.simulation.dsol.animation.Locatable;
21 import nl.tudelft.simulation.dsol.animation.D2.Renderable2D;
22 import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
23 import nl.tudelft.simulation.language.d2.Angle;
24 import nl.tudelft.simulation.language.d3.DirectedPoint;
25
26
27
28
29
30
31
32
33
34
35
36 public class LinkAnimation extends Renderable2D<Link> implements ClonableRenderable2DInterface<Link>, Serializable
37 {
38
39 private static final long serialVersionUID = 20140000L;
40
41
42 private float width;
43
44
45 private Text text;
46
47
48
49
50
51
52
53
54 public LinkAnimation(final Link link, final SimulatorInterface.TimeDoubleUnit simulator, final float width)
55 throws NamingException, RemoteException
56 {
57 super(link, simulator);
58 this.width = width;
59 this.text = new Text(link, link.getId(), 0.0f, 1.5f, TextAlignment.CENTER, Color.BLACK, simulator);
60 }
61
62
63 @Override
64 public final void paint(final Graphics2D graphics, final ImageObserver observer) throws RemoteException
65 {
66 Color color = getSource().getLinkType().isConnector() ? Color.BLUE : Color.RED;
67 OTSLine3D designLine = getSource().getDesignLine();
68 PaintLine.paintLine(graphics, color, this.width, getSource().getLocation(), designLine);
69
70 try
71 {
72 drawEndPoint(designLine.getFirst(), designLine.get(1), graphics);
73 drawEndPoint(designLine.getLast(), designLine.get(designLine.size() - 2), graphics);
74 }
75 catch (OTSGeometryException exception)
76 {
77
78 SimLogger.always().error(exception);
79 }
80 }
81
82
83
84
85
86
87
88
89 private void drawEndPoint(final OTSPoint3D endPoint, final OTSPoint3D nextPoint, final Graphics2D graphics)
90 {
91
92 double dx = nextPoint.x - endPoint.x;
93 double dy = nextPoint.y - endPoint.y;
94 double length = endPoint.distanceSI(nextPoint);
95
96 dx *= this.width / length;
97 dy *= this.width / length;
98 try
99 {
100 OTSLine3D line = new OTSLine3D(new OTSPoint3D(endPoint.x - dy, endPoint.y + dx, endPoint.z),
101 new OTSPoint3D(endPoint.x + dy, endPoint.y - dx, endPoint.z));
102 PaintLine.paintLine(graphics, getSource().getLinkType().isConnector() ? Color.BLUE : Color.RED, this.width / 30,
103 getSource().getLocation(), line);
104 }
105 catch (OTSGeometryException exception)
106 {
107 SimLogger.always().error(exception);
108 }
109 catch (RemoteException exception)
110 {
111 SimLogger.always().error(exception);
112 }
113 }
114
115
116 @Override
117 public final void destroy() throws NamingException
118 {
119 super.destroy();
120 this.text.destroy();
121 }
122
123
124 @Override
125 @SuppressWarnings("checkstyle:designforextension")
126 public ClonableRenderable2DInterface<Link> clone(final Link newSource, final SimulatorInterface.TimeDoubleUnit newSimulator)
127 throws NamingException, RemoteException
128 {
129
130 return new LinkAnimation(newSource, newSimulator, this.width);
131 }
132
133
134 @Override
135 public final String toString()
136 {
137 return "LinkAnimation [width=" + this.width + ", link=" + super.getSource() + "]";
138 }
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153 public class Text extends TextAnimation
154 {
155
156 private static final long serialVersionUID = 20161211L;
157
158
159
160
161
162
163
164
165
166
167
168
169 public Text(final Locatable source, final String text, final float dx, final float dy,
170 final TextAlignment textPlacement, final Color color, final SimulatorInterface.TimeDoubleUnit simulator)
171 throws RemoteException, NamingException
172 {
173 super(source, text, dx, dy, textPlacement, color, simulator);
174 }
175
176
177 @Override
178 @SuppressWarnings("checkstyle:designforextension")
179 public DirectedPoint getLocation() throws RemoteException
180 {
181
182 DirectedPoint p = ((Link) getSource()).getDesignLine().getLocationFractionExtended(0.5);
183 double a = Angle.normalizePi(p.getRotZ());
184 if (a > Math.PI / 2.0 || a < -0.99 * Math.PI / 2.0)
185 {
186 a += Math.PI;
187 }
188 return new DirectedPoint(p.x, p.y, Double.MAX_VALUE, 0.0, 0.0, a);
189 }
190
191
192 @Override
193 @SuppressWarnings("checkstyle:designforextension")
194 public TextAnimation clone(final Locatable newSource, final SimulatorInterface.TimeDoubleUnit newSimulator)
195 throws RemoteException, NamingException
196 {
197 return new Text(newSource, getText(), getDx(), getDy(), getTextAlignment(), getColor(), newSimulator);
198 }
199
200
201 @Override
202 public final String toString()
203 {
204 return "LinkAnimation.Text []";
205 }
206 }
207
208 }