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