View Javadoc
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.Stroke;
7   import java.awt.geom.Path2D;
8   import java.awt.image.ImageObserver;
9   import java.rmi.RemoteException;
10  import java.util.List;
11  import java.util.Set;
12  
13  import javax.naming.NamingException;
14  
15  import org.djunits.unit.LengthUnit;
16  import org.djunits.value.vdouble.scalar.Length;
17  import org.djutils.draw.point.Point2d;
18  import org.opentrafficsim.draw.PaintPolygons;
19  import org.opentrafficsim.draw.road.AbstractLineAnimation.LaneBasedObjectData;
20  import org.opentrafficsim.draw.road.ConflictAnimation.ConflictData;
21  
22  import nl.tudelft.simulation.naming.context.Contextualized;
23  
24  /**
25   * Animate a conflict.
26   * <p>
27   * Copyright (c) 2013-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
28   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
29   * </p>
30   * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
31   * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
32   * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
33   */
34  public class ConflictAnimation extends AbstractLineAnimation<ConflictData>
35  {
36  
37      /** */
38      private static final long serialVersionUID = 20161207L;
39  
40      /** Drawable paths. */
41      private final Set<Path2D.Float> paths;
42  
43      /**
44       * @param source ConflictData; the conflict to draw
45       * @param contextualized Contextualized; context provider
46       * @throws NamingException in case of registration failure of the animation
47       * @throws RemoteException on communication failure
48       */
49      public ConflictAnimation(final ConflictData source, final Contextualized contextualized)
50              throws NamingException, RemoteException
51      {
52          super(source, contextualized, .9, new Length(0.5, LengthUnit.SI));
53          // geometry of area (not the line) is absolute; pre-transform geometry to fit rotation of source
54          this.paths = this.getSource().getContour() == null ? null
55                  : PaintPolygons.getPaths(getSource().getLocation(), getSource().getContour());
56      }
57  
58      /** {@inheritDoc} */
59      @Override
60      public final void paint(final Graphics2D graphics, final ImageObserver observer)
61      {
62          // paint the bar that represents the line where the conflict starts, like any other AbstractLineAnimation
63          Color fillColor = getSource().getColor();
64          graphics.setColor(fillColor);
65          super.paint(graphics, observer);
66  
67          // paint the additional area with dashed lines
68          Stroke oldStroke = graphics.getStroke();
69          BasicStroke stroke;
70          float factor = getSource().isPermitted() ? .5f : 1f;
71          if (getSource().isCrossing())
72          {
73              stroke = new BasicStroke(.1f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 1.0f,
74                      new float[] {factor * 1.0f, factor * 2.0f}, 0.0f);
75          }
76          else
77          {
78              stroke = new BasicStroke(.1f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 1.0f,
79                      new float[] {factor * 1.0f, factor * 0.95f, factor * 0.1f, factor * 0.95f}, 0.0f);
80          }
81          graphics.setStroke(stroke);
82          if (this.paths != null)
83          {
84              setRendering(graphics);
85              PaintPolygons.paintPaths(graphics, fillColor, this.paths, false);
86              resetRendering(graphics);
87          }
88          graphics.setStroke(oldStroke);
89      }
90  
91      /** {@inheritDoc} */
92      @Override
93      public final String toString()
94      {
95          return "ConflictAnimation [getSource()=" + getSource() + "]";
96      }
97  
98      /**
99       * ConflictData provides the information required to draw a conflict.
100      * <p>
101      * Copyright (c) 2023-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
102      * <br>
103      * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
104      * </p>
105      * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
106      */
107     public interface ConflictData extends LaneBasedObjectData
108     {
109         /**
110          * Returns the conflict color.
111          * @return Color; conflict color.
112          */
113         Color getColor();
114 
115         /**
116          * Returns the contour.
117          * @return List&lt;Point2d&gt;; points.
118          */
119         List<Point2d> getContour();
120 
121         /**
122          * Whether the conflict is a crossing.
123          * @return boolean; whether the conflict is a crossing.
124          */
125         boolean isCrossing();
126 
127         /**
128          * Whether the conflict is a permitted conflict.
129          * @return boolean; whether the conflict is a permitted conflict.
130          */
131         boolean isPermitted();
132     }
133 
134 }