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