1 package org.opentrafficsim.draw.gtu;
2
3 import java.awt.BasicStroke;
4 import java.awt.Color;
5 import java.awt.Graphics2D;
6 import java.awt.geom.Ellipse2D;
7 import java.awt.geom.Rectangle2D;
8 import java.awt.geom.RectangularShape;
9 import java.awt.image.ImageObserver;
10 import java.rmi.RemoteException;
11 import java.util.function.Supplier;
12
13 import javax.naming.NamingException;
14
15 import org.djunits.value.vdouble.scalar.Length;
16 import org.djutils.base.Identifiable;
17 import org.djutils.draw.point.OrientedPoint2d;
18 import org.opentrafficsim.base.geometry.OtsLocatable;
19 import org.opentrafficsim.base.geometry.OtsRenderable;
20 import org.opentrafficsim.draw.DrawLevel;
21 import org.opentrafficsim.draw.TextAlignment;
22 import org.opentrafficsim.draw.TextAnimation;
23 import org.opentrafficsim.draw.gtu.DefaultCarAnimation.GtuData;
24
25 import nl.tudelft.simulation.naming.context.Contextualized;
26
27
28
29
30
31
32
33
34
35
36
37 public class DefaultCarAnimation extends OtsRenderable<GtuData>
38 {
39
40 private static final long serialVersionUID = 20150000L;
41
42
43 private Text text;
44
45
46 private final int hashCode;
47
48
49 private Rectangle2D.Double rectangle;
50
51
52 private Ellipse2D.Double frontIndicator;
53
54
55 private Rectangle2D.Double leftIndicator;
56
57
58 private Rectangle2D.Double rightIndicator;
59
60
61 private Rectangle2D.Double leftBrake;
62
63
64 private Rectangle2D.Double rightBrake;
65
66
67 private RectangularShape marker;
68
69
70
71
72
73
74
75
76 public DefaultCarAnimation(final GtuData gtu, final Contextualized contextualized) throws NamingException, RemoteException
77 {
78 super(gtu, contextualized);
79 this.hashCode = gtu.hashCode();
80 this.text = new Text(gtu, gtu::getId, 0.0f, 0.0f, TextAlignment.CENTER, Color.BLACK, contextualized,
81 new TextAnimation.ContrastToBackground()
82 {
83
84 @Override
85 public Color getBackgroundColor()
86 {
87 return gtu.getColor();
88 }
89 }).setDynamic(true);
90 }
91
92
93 @Override
94 public final void paint(final Graphics2D graphics, final ImageObserver observer)
95 {
96 setRendering(graphics);
97 final GtuData gtu = getSource();
98 if (this.rectangle == null)
99 {
100
101
102 final double length = gtu.getLength().si;
103 final double lFront = gtu.getFront().si;
104 final double lRear = gtu.getRear().si;
105 final double width = gtu.getWidth().si;
106 final double w2 = width / 2;
107 final double w4 = width / 4;
108 this.rectangle = new Rectangle2D.Double(lRear, -w2, length, width);
109 this.frontIndicator = new Ellipse2D.Double(lFront - w2 - w4, -w4, w2, w2);
110 this.leftIndicator = new Rectangle2D.Double(lFront - w4, -w2, w4, w4);
111 this.rightIndicator = new Rectangle2D.Double(lFront - w4, w2 - w4, w4, w4);
112 this.leftBrake = new Rectangle2D.Double(lRear, w2 - w4, w4, w4);
113 this.rightBrake = new Rectangle2D.Double(lRear, -w2, w4, w4);
114 this.marker = gtu.getMarker();
115 }
116
117 double scale = graphics.getTransform().getDeterminant();
118
119
120 if (scale > 1)
121 {
122 Color color = gtu.getColor();
123 graphics.setColor(color);
124 BasicStroke saveStroke = (BasicStroke) graphics.getStroke();
125 graphics.setStroke(new BasicStroke(0.05f));
126 graphics.fill(this.rectangle);
127
128 graphics.setColor(Color.WHITE);
129 graphics.fill(this.frontIndicator);
130
131 if (color.equals(Color.WHITE))
132 {
133
134 graphics.setColor(Color.BLACK);
135 graphics.draw(this.frontIndicator);
136 }
137
138
139 graphics.setColor(Color.YELLOW);
140 if (gtu.leftIndicatorOn())
141 {
142 graphics.fill(this.leftIndicator);
143 if (color.equals(Color.YELLOW))
144 {
145 graphics.setColor(Color.BLACK);
146 graphics.draw(this.leftIndicator);
147 }
148 }
149 if (gtu.rightIndicatorOn())
150 {
151 graphics.fill(this.rightIndicator);
152 if (color.equals(Color.YELLOW))
153 {
154 graphics.setColor(Color.BLACK);
155 graphics.draw(this.rightIndicator);
156 }
157 }
158
159
160 if (gtu.isBrakingLightsOn())
161 {
162 graphics.setColor(Color.RED);
163 graphics.fill(this.leftBrake);
164 graphics.fill(this.rightBrake);
165 if (color.equals(Color.RED))
166 {
167 graphics.setColor(Color.BLACK);
168 graphics.draw(this.leftBrake);
169 graphics.draw(this.rightBrake);
170 }
171 }
172 graphics.setStroke(saveStroke);
173 }
174 else
175 {
176
177 graphics.setColor(gtu.getColor());
178 double w = 7.0 / Math.sqrt(scale);
179 double x = -w / 2.0;
180 this.marker.setFrame(x, x, w, w);
181 graphics.fill(this.marker);
182 }
183 resetRendering(graphics);
184 }
185
186
187 @Override
188 public void destroy(final Contextualized contextProvider)
189 {
190 super.destroy(contextProvider);
191 this.text.destroy(contextProvider);
192 }
193
194
195 @Override
196 public int hashCode()
197 {
198 return this.hashCode;
199 }
200
201
202 @Override
203 public boolean equals(final Object object)
204 {
205
206 return super.equals(object);
207 }
208
209
210
211
212
213
214
215
216
217
218
219
220 public class Text extends TextAnimation<GtuData, Text>
221 {
222
223 private static final long serialVersionUID = 20161211L;
224
225
226 private boolean isTextDestroyed = false;
227
228
229
230
231
232
233
234
235
236
237
238
239 public Text(final GtuData source, final Supplier<String> text, final float dx, final float dy,
240 final TextAlignment textAlignment, final Color color, final Contextualized contextualized)
241 throws RemoteException, NamingException
242 {
243 super(source, text, dx, dy, textAlignment, color, 1.0f, 12.0f, 50f, contextualized, TextAnimation.RENDERWHEN1);
244 }
245
246
247
248
249
250
251
252
253
254
255
256
257
258 @SuppressWarnings("parameternumber")
259 public Text(final GtuData source, final Supplier<String> text, final float dx, final float dy,
260 final TextAlignment textAlignment, final Color color, final Contextualized contextualized,
261 final TextAnimation.ContrastToBackground background) throws RemoteException, NamingException
262 {
263 super(source, text, dx, dy, textAlignment, color, 1.0f, 12.0f, 50f, contextualized, background, RENDERWHEN1);
264 }
265
266
267 @Override
268 public final String toString()
269 {
270 return "Text [isTextDestroyed=" + this.isTextDestroyed + "]";
271 }
272
273 }
274
275
276
277
278
279
280
281
282
283
284
285
286 public interface GtuData extends OtsLocatable, Identifiable
287 {
288
289
290
291
292 Color getColor();
293
294
295
296
297
298 Length getLength();
299
300
301
302
303
304 Length getWidth();
305
306
307
308
309
310 Length getFront();
311
312
313
314
315
316 Length getRear();
317
318
319
320
321
322 boolean leftIndicatorOn();
323
324
325
326
327
328 boolean rightIndicatorOn();
329
330
331
332
333
334 default RectangularShape getMarker()
335 {
336 return new Ellipse2D.Double(0, 0, 0, 0);
337 }
338
339
340
341
342
343 boolean isBrakingLightsOn();
344
345
346 @Override
347 OrientedPoint2d getLocation();
348
349
350 @Override
351 default double getZ()
352 {
353 return DrawLevel.GTU.getZ();
354 }
355 }
356
357 }