1 package org.opentrafficsim.draw.network;
2
3 import java.awt.Color;
4 import java.awt.Graphics2D;
5 import java.awt.geom.Path2D;
6 import java.awt.image.ImageObserver;
7 import java.util.function.Supplier;
8
9 import org.djutils.base.Identifiable;
10 import org.djutils.draw.line.PolyLine2d;
11 import org.djutils.draw.point.DirectedPoint2d;
12 import org.djutils.draw.point.Point2d;
13 import org.opentrafficsim.draw.DrawLevel;
14 import org.opentrafficsim.draw.LineLocatable;
15 import org.opentrafficsim.draw.OtsRenderable;
16 import org.opentrafficsim.draw.PaintLine;
17 import org.opentrafficsim.draw.RenderableTextSource;
18 import org.opentrafficsim.draw.TextAlignment;
19 import org.opentrafficsim.draw.network.LinkAnimation.LinkData;
20
21 import nl.tudelft.simulation.naming.context.Contextualized;
22
23
24
25
26
27
28
29
30
31
32 public class LinkAnimation extends OtsRenderable<LinkData>
33 {
34
35 private float width;
36
37
38 private Text text;
39
40
41 private Path2D.Float path;
42
43
44 private Path2D.Float startPoint;
45
46
47 private Path2D.Float endPoint;
48
49
50 private final Color color;
51
52
53 private PolyLine2d designLine;
54
55
56 private boolean dynamic = false;
57
58
59
60
61
62
63
64 public LinkAnimation(final LinkData link, final Contextualized contextualized, final float width)
65 {
66 super(link, contextualized);
67 this.width = width;
68 this.text = new Text(link, link::getId, 0.0f, 1.5f, TextAlignment.CENTER, Color.BLACK, contextualized,
69 RenderableTextSource.RENDERWHEN10);
70 setPath();
71 this.color = getSource().isConnector() ? Color.PINK.darker() : Color.BLUE;
72 }
73
74
75
76
77
78
79 @SuppressWarnings("all")
80 public LinkAnimation setDynamic(final boolean dynamic)
81 {
82 this.dynamic = dynamic;
83 return this;
84 }
85
86 @Override
87 public final void paint(final Graphics2D graphics, final ImageObserver observer)
88 {
89 if (this.dynamic)
90 {
91 PolyLine2d designLine = getSource().getCenterLine();
92 if (!designLine.equals(this.designLine))
93 {
94 setPath();
95 }
96 }
97 setRendering(graphics);
98 double scale = Math.sqrt(graphics.getTransform().getDeterminant());
99 double factor = 2.0 / Math.min(scale, 2.0);
100 PaintLine.paintLine(graphics, this.color, factor * this.width, this.path);
101 PaintLine.paintLine(graphics, this.color, this.width / 30, this.startPoint);
102 PaintLine.paintLine(graphics, this.color, this.width / 30, this.endPoint);
103 resetRendering(graphics);
104 }
105
106
107
108
109 private void setPath()
110 {
111 this.designLine = getSource().getCenterLine();
112 this.path = PaintLine.getPath(getSource().getLocation(), this.designLine);
113 this.startPoint = getEndPoint(this.designLine.getFirst(), this.designLine.get(1));
114 this.endPoint = getEndPoint(this.designLine.getLast(), this.designLine.get(this.designLine.size() - 2));
115 }
116
117
118
119
120
121
122 private Path2D.Float getEndPoint(final Point2d endPoint, final Point2d nextPoint)
123 {
124 double dx = nextPoint.x - endPoint.x;
125 double dy = nextPoint.y - endPoint.y;
126 double length = endPoint.distance(nextPoint);
127
128 dx *= this.width / length;
129 dy *= this.width / length;
130 PolyLine2d line =
131 new PolyLine2d(new Point2d(endPoint.x - dy, endPoint.y + dx), new Point2d(endPoint.x + dy, endPoint.y - dx));
132 return PaintLine.getPath(getSource().getLocation(), line);
133 }
134
135 @Override
136 public void destroy(final Contextualized contextProvider)
137 {
138 super.destroy(contextProvider);
139 this.text.destroy(contextProvider);
140 }
141
142 @Override
143 public final String toString()
144 {
145 return "LinkAnimation [width=" + this.width + ", link=" + super.getSource() + "]";
146 }
147
148
149
150
151
152
153
154
155
156
157
158
159 public static class Text extends RenderableTextSource<LinkData, Text>
160 {
161
162
163
164
165
166
167
168
169
170
171
172 public Text(final LinkData source, final Supplier<String> text, final float dx, final float dy,
173 final TextAlignment textPlacement, final Color color, final Contextualized contextualized,
174 final ScaleDependentRendering scaleDependentRendering)
175 {
176 super(source, text, dx, dy, textPlacement, color, 2.0f, 12.0f, 50f, contextualized, null, scaleDependentRendering);
177 }
178
179 @Override
180 public final String toString()
181 {
182 return "LinkAnimation.Text []";
183 }
184 }
185
186
187
188
189
190
191
192
193
194
195 public interface LinkData extends LineLocatable, Identifiable
196 {
197 @Override
198 DirectedPoint2d getLocation();
199
200
201
202
203
204 boolean isConnector();
205
206
207
208
209
210 PolyLine2d getCenterLine();
211
212 @Override
213 default double getZ()
214 {
215 return DrawLevel.LINK.getZ();
216 }
217 }
218
219 }