View Javadoc
1   package org.opentrafficsim.draw.network;
2   
3   import java.awt.BasicStroke;
4   import java.awt.Color;
5   import java.awt.Graphics2D;
6   import java.awt.geom.Ellipse2D;
7   import java.awt.geom.GeneralPath;
8   import java.awt.geom.Path2D;
9   import java.awt.image.ImageObserver;
10  import java.io.Serializable;
11  import java.rmi.RemoteException;
12  
13  import javax.naming.NamingException;
14  
15  import org.opentrafficsim.core.dsol.OtsSimulatorInterface;
16  import org.opentrafficsim.core.geometry.Bounds;
17  import org.opentrafficsim.core.geometry.DirectedPoint;
18  import org.opentrafficsim.core.network.Node;
19  import org.opentrafficsim.draw.core.TextAlignment;
20  import org.opentrafficsim.draw.core.TextAnimation;
21  
22  import nl.tudelft.simulation.dsol.animation.Locatable;
23  import nl.tudelft.simulation.dsol.animation.D2.Renderable2D;
24  import nl.tudelft.simulation.dsol.animation.D2.Renderable2DInterface;
25  import nl.tudelft.simulation.introspection.DelegateIntrospection;
26  import nl.tudelft.simulation.naming.context.Contextualized;
27  
28  /**
29   * <p>
30   * Copyright (c) 2013-2023 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
31   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
32   * </p>
33   * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
34   */
35  @SuppressWarnings("rawtypes")
36  public class NodeAnimation extends Renderable2D<NodeAnimation.ElevatedNode>
37          implements Renderable2DInterface<NodeAnimation.ElevatedNode>, Serializable
38  {
39      /** */
40      private static final long serialVersionUID = 20140000L;
41  
42      /** the Text object to destroy when the animation is destroyed. */
43      private Text text;
44  
45      /** Ensure that node animations are slightly above lane surface. */
46      public static final double ZOFFSET = 0.01;
47  
48      /**
49       * @param node Node; n
50       * @param simulator OtsSimulatorInterface; s
51       * @throws NamingException when animation context cannot be found.
52       * @throws RemoteException on communication failure
53       */
54      public NodeAnimation(final Node node, final OtsSimulatorInterface simulator) throws NamingException, RemoteException
55      {
56          super(new ElevatedNode(node), simulator);
57          this.text = new Text(node, node.getId(), 0.0f, 3.0f, TextAlignment.CENTER, Color.BLACK, simulator,
58                  TextAnimation.RENDERWHEN10);
59      }
60  
61      /** {@inheritDoc} */
62      @Override
63      public final void paint(final Graphics2D graphics, final ImageObserver observer)
64      {
65          graphics.setColor(Color.BLACK);
66          graphics.setStroke(new BasicStroke(0.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
67          graphics.draw(new Ellipse2D.Double(-0.5, -0.5, 1.0, 1.0));
68          double direction = getSource().getLocation().getZ();
69          if (!Double.isNaN(direction))
70          {
71              GeneralPath arrow = new GeneralPath(Path2D.WIND_EVEN_ODD, 3);
72              arrow.moveTo(0.5, -0.5);
73              arrow.lineTo(2, 0);
74              arrow.lineTo(0.5, 0.5);
75              graphics.draw(arrow);
76          }
77      }
78  
79      /** {@inheritDoc} */
80      @Override
81      public void destroy(final Contextualized contextProvider)
82      {
83          super.destroy(contextProvider);
84          this.text.destroy(contextProvider);
85      }
86  
87      /** {@inheritDoc} */
88      @Override
89      public final String toString()
90      {
91          return "NodeAnimation [node=" + super.getSource() + "]";
92      }
93  
94      /** Class for elevating the node for animation purposes. */
95      public static class ElevatedNode implements Locatable, DelegateIntrospection
96      {
97          /** the node for introspection. */
98          private final Node node;
99  
100         /** the location of the node to which the animation belongs. */
101         private DirectedPoint location;
102 
103         /** the bounds of the node to which the animation belongs. */
104         private Bounds bounds;
105 
106         /**
107          * @param node Node; the node to which the animation belongs
108          */
109         public ElevatedNode(final Node node)
110         {
111             this.node = node;
112             DirectedPoint p = node.getLocation();
113             this.location = new DirectedPoint(p.x, p.y, p.z + ZOFFSET, p.getRotX(), p.getRotY(), p.getRotZ());
114             this.bounds = node.getBounds();
115         }
116 
117         /** {@inheritDoc} */
118         @Override
119         public DirectedPoint getLocation()
120         {
121             return this.location;
122         }
123 
124         /**
125          * @return node
126          */
127         public Node getNode()
128         {
129             return this.node;
130         }
131 
132         /** {@inheritDoc} */
133         @Override
134         public Bounds getBounds() throws RemoteException
135         {
136             return this.bounds;
137         }
138 
139         /** {@inheritDoc} */
140         @Override
141         public Object getParentIntrospectionObject()
142         {
143             return this.node;
144         }
145 
146     }
147 
148     /**
149      * Text animation for the Node. Separate class to be able to turn it on and off...
150      * <p>
151      * Copyright (c) 2013-2023 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
152      * <br>
153      * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
154      * </p>
155      * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
156      * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
157      * @author <a href="https://dittlab.tudelft.nl">Wouter Schakel</a>
158      */
159     public class Text extends TextAnimation
160     {
161         /** */
162         private static final long serialVersionUID = 20161211L;
163 
164         /**
165          * @param source Locatable; the object for which the text is displayed
166          * @param text String; the text to display
167          * @param dx float; the horizontal movement of the text, in meters
168          * @param dy float; the vertical movement of the text, in meters
169          * @param textPlacement TextAlignment; where to place the text
170          * @param color Color; the color of the text
171          * @param simulator OtsSimulatorInterface; the simulator
172          * @param scaleDependentRendering ScaleDependendentRendering; size limiter for text animation
173          * @throws NamingException when animation context cannot be created or retrieved
174          * @throws RemoteException - when remote context cannot be found
175          */
176         @SuppressWarnings("checkstyle:parameternumber")
177         public Text(final Locatable source, final String text, final float dx, final float dy,
178                 final TextAlignment textPlacement, final Color color, final OtsSimulatorInterface simulator,
179                 final ScaleDependentRendering scaleDependentRendering) throws RemoteException, NamingException
180         {
181             super(source, text, dx, dy, textPlacement, color, 2.0f, 12.0f, 50f, simulator, scaleDependentRendering);
182             setFlip(false);
183             setRotate(false);
184         }
185 
186         /** {@inheritDoc} */
187         @Override
188         public final String toString()
189         {
190             return "NodeAnimation.Text []";
191         }
192     }
193 
194 }