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