1 package org.opentrafficsim.draw.road;
2
3 import java.awt.BasicStroke;
4 import java.awt.Color;
5 import java.awt.Graphics2D;
6 import java.awt.geom.Path2D;
7 import java.awt.image.ImageObserver;
8 import java.rmi.RemoteException;
9 import java.util.Set;
10
11 import javax.naming.NamingException;
12
13 import org.djutils.draw.line.PolyLine2d;
14 import org.opentrafficsim.base.geometry.OtsLocatable;
15 import org.opentrafficsim.base.geometry.OtsRenderable;
16 import org.opentrafficsim.draw.DrawLevel;
17 import org.opentrafficsim.draw.PaintPolygons;
18 import org.opentrafficsim.draw.road.CrossSectionElementAnimation.CrossSectionElementData;
19
20 import nl.tudelft.simulation.naming.context.Contextualized;
21
22 /**
23 * Draws cross section elements (those that are not defined more specifically).
24 * <p>
25 * Copyright (c) 2013-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
26 * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
27 * </p>
28 * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
29 * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
30 * @param <L> cross section element data type
31 */
32 public class CrossSectionElementAnimation<L extends CrossSectionElementData> extends OtsRenderable<L>
33 {
34 /** */
35 private static final long serialVersionUID = 20141017L;
36
37 /** The animation color. */
38 private final Color color;
39
40 /** Drawable paths. */
41 private final Set<Path2D.Float> paths;
42
43 /**
44 * @param source L; cross section element
45 * @param contextualized Contextualized; context provider
46 * @param color Color; the color to draw the shoulder with
47 * @throws NamingException ne
48 * @throws RemoteException on communication failure
49 */
50 public CrossSectionElementAnimation(final L source, final Contextualized contextualized, final Color color)
51 throws NamingException, RemoteException
52 {
53 super(source, contextualized);
54 this.color = color;
55 this.paths = PaintPolygons.getPaths(getSource().getBounds().asPolygon().getPointList());
56 }
57
58 /** {@inheritDoc} */
59 @Override
60 public void paint(final Graphics2D graphics, final ImageObserver observer)
61 {
62 setRendering(graphics);
63 PaintPolygons.paintPaths(graphics, this.color, this.paths, true);
64 // drawing some extra width by painting the edge (i.e. fill = false) prevents anti-alias lines between adjacent elements
65 double scale = Math.min(Math.max(3.0 / graphics.getTransform().getDeterminant(), 0.1), 0.5);
66 graphics.setStroke(new BasicStroke((float) scale, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER));
67 PaintPolygons.paintPaths(graphics, this.color, this.paths, false);
68 resetRendering(graphics);
69 }
70
71 /** {@inheritDoc} */
72 @Override
73 public String toString()
74 {
75 return "CrossSectionElementAnimation [source = " + getSource().toString() + ", color=" + this.color + "]";
76 }
77
78 /**
79 * CrossSectionElementData provides the information required to draw a cross section element.
80 * <p>
81 * Copyright (c) 2023-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
82 * <br>
83 * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
84 * </p>
85 * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
86 */
87 public interface CrossSectionElementData extends OtsLocatable
88 {
89 /**
90 * Returns the center line.
91 * @return PolyLine2d; center line.
92 */
93 PolyLine2d getCenterLine();
94
95 /**
96 * Return the id of the link.
97 * @return String; link id.
98 */
99 String getLinkId();
100 }
101
102 /**
103 * ShoulderData provides the information required to draw a shoulder.
104 * <p>
105 * Copyright (c) 2023-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
106 * <br>
107 * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
108 * </p>
109 * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
110 */
111 public interface ShoulderData extends CrossSectionElementData
112 {
113 /** {@inheritDoc} */
114 @Override
115 default public double getZ()
116 {
117 return DrawLevel.SHOULDER.getZ();
118 }
119 }
120 }