View Javadoc
1   package org.opentrafficsim.animation.road;
2   
3   import java.awt.Graphics2D;
4   import java.awt.geom.Rectangle2D;
5   import java.awt.image.ImageObserver;
6   
7   import org.djunits.value.vdouble.scalar.Length;
8   import org.djutils.base.Identifiable;
9   import org.djutils.draw.point.DirectedPoint2d;
10  import org.opentrafficsim.animation.DrawLevel;
11  import org.opentrafficsim.animation.LineLocatable;
12  import org.opentrafficsim.animation.OtsRenderableLabeled;
13  import org.opentrafficsim.animation.RenderableTextSource;
14  import org.opentrafficsim.animation.road.AbstractLineAnimation.LaneBasedObjectData;
15  
16  import nl.tudelft.simulation.naming.context.Contextualized;
17  
18  /**
19   * Abstract class for objects that draw a line perpendicular on the lane.
20   * <p>
21   * Copyright (c) 2013-2026 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
22   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
23   * </p>
24   * @author Alexander Verbraeck
25   * @author Peter Knoppers
26   * @author Wouter Schakel
27   * @param <L> source type
28   * @param <T> text renderable type
29   */
30  public abstract class AbstractLineAnimation<L extends LaneBasedObjectData, T extends RenderableTextSource<L, T>>
31          extends OtsRenderableLabeled<L, T>
32  {
33  
34      /** Width for which rectangle was determined. */
35      private final Length width;
36  
37      /** Last length for which the rectangle was determined. */
38      private double lastLength = Double.NaN;
39  
40      /** Rectangle to draw. */
41      private Rectangle2D rectangle = new Rectangle2D.Double(0.0, 0.0, 0.0, 0.0);
42  
43      /**
44       * Construct the line animation. This constructor uses an empty prefix for the label.
45       * @param source source
46       * @param contextualized context provider
47       * @param width line width
48       */
49      public AbstractLineAnimation(final L source, final Contextualized contextualized, final Length width)
50      {
51          this(source, contextualized, width, "");
52      }
53  
54      /**
55       * Construct the line animation.
56       * @param source source
57       * @param contextualized context provider
58       * @param width line width
59       * @param prefix label prefix
60       */
61      public AbstractLineAnimation(final L source, final Contextualized contextualized, final Length width, final String prefix)
62      {
63          super(source, contextualized, prefix);
64          this.width = width;
65      }
66  
67      @Override
68      @SuppressWarnings("checkstyle:designforextension")
69      public void paint(final Graphics2D graphics, final ImageObserver observer)
70      {
71          setRendering(graphics);
72          double length = getSource().getLine().getLength();
73          if (length != this.lastLength)
74          {
75              double halfLength = .5 * length;
76              this.lastLength = length;
77              this.rectangle = new Rectangle2D.Double(-.5 * this.width.si, -halfLength, this.width.si, 2 * halfLength);
78          }
79          graphics.fill(this.rectangle);
80          resetRendering(graphics);
81      }
82  
83      /**
84       * Object data to draw a lane based object.
85       */
86      public interface LaneBasedObjectData extends LineLocatable, Identifiable
87      {
88  
89          /**
90           * Returns the width of the lane.
91           * @return width of the lane.
92           */
93          Length getLaneWidth();
94  
95          @Override
96          DirectedPoint2d getLocation();
97  
98          @Override
99          default double getZ()
100         {
101             return DrawLevel.OBJECT.getZ();
102         }
103 
104     }
105 
106 }