View Javadoc
1   package org.opentrafficsim.road.network.factory.opendrive;
2   
3   import java.awt.BasicStroke;
4   import java.awt.Color;
5   import java.awt.Graphics2D;
6   import java.awt.geom.Path2D;
7   import java.awt.image.ImageObserver;
8   import java.io.Serializable;
9   import java.rmi.RemoteException;
10  
11  import javax.naming.NamingException;
12  import javax.vecmath.Point2d;
13  
14  import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
15  import org.opentrafficsim.core.geometry.OTSGeometryException;
16  import org.opentrafficsim.core.geometry.OTSLine3D;
17  import org.opentrafficsim.core.geometry.OTSPoint3D;
18  import org.opentrafficsim.core.gtu.GTUType;
19  import org.opentrafficsim.core.network.LongitudinalDirectionality;
20  import org.opentrafficsim.core.network.animation.PaintPolygons;
21  import org.opentrafficsim.road.network.lane.Lane;
22  
23  import nl.tudelft.simulation.dsol.animation.D2.Renderable2D;
24  import nl.tudelft.simulation.language.d3.DirectedPoint;
25  
26  /**
27   * <p>
28   * Copyright (c) 2013-2016 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
29   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
30   * <p>
31   * $LastChangedDate: 2015-09-14 01:33:02 +0200 (Mon, 14 Sep 2015) $, @version $Revision: 1401 $, by $Author: averbraeck $,
32   * initial version Oct 17, 2014 <br>
33   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
34   */
35  public class LaneAnimationOD extends Renderable2D implements Serializable
36  {
37      /** */
38      private static final long serialVersionUID = 20141017L;
39      
40      /** Color of the lane. */
41      private final Color color;
42  
43      /**
44       * @param source s
45       * @param simulator s
46       * @param color color of the lane.
47       * @throws NamingException ne
48       * @throws RemoteException on communication failure
49       */
50      public LaneAnimationOD(final Lane source, final OTSSimulatorInterface simulator, final Color color)
51          throws NamingException, RemoteException
52      {
53          super(source, simulator);
54          this.color = color;
55      }
56  
57      /**
58       * Paint a road stripe.
59       * @param graphics Graphics2D; the graphics context
60       * @param color Color; the color of the road stripe
61       * @param referencePoint DirectedPoint; offset of the reference point of the lane from the origin
62       * @param line OTSLine3D; the coordinates of the center line of the stripe
63       */
64      public static void paintLine(final Graphics2D graphics, final Color color, final DirectedPoint referencePoint,
65          final OTSLine3D line)
66      {
67          graphics.setColor(color);
68          graphics.setStroke(new BasicStroke(0.1f)); // width of the stripe is 0.1m
69          Path2D.Double path = new Path2D.Double();
70          boolean start = true;
71          for (OTSPoint3D point : line.getPoints())
72          {
73              if (start)
74              {
75                  path.moveTo(point.x - referencePoint.x, -point.y + referencePoint.y);
76                  start = false;
77              }
78              else
79              {
80                  path.lineTo(point.x - referencePoint.x, -point.y + referencePoint.y);
81              }
82          }
83          graphics.draw(path);
84      }
85  
86      /**
87       * Draw one arrow on the lane at a specified relative position in a specified color.
88       * @param graphics Graphics2D; the graphics context
89       * @param color Color; the color of the arrow
90       * @param ref DirectedPoint; offset of the reference point of the lane from the origin
91       * @param line OTSLine3D; the coordinates of the center line of the lane
92       * @param fraction double; the relative position on the lane
93       * @param dir LongitudinalDirectionality; the driving direction of the lane
94       */
95      private static void paintArrow(final Graphics2D graphics, final Color color, final DirectedPoint ref,
96          final OTSLine3D line, final double fraction, final LongitudinalDirectionality dir)
97      {
98          try
99          {
100             double len = 3.0;
101             double ar = 0.5;
102             DirectedPoint start = line.getLocationFraction(fraction);
103             graphics.setColor(color);
104             graphics.setStroke(new BasicStroke(0.2f));
105             Path2D.Double path = new Path2D.Double();
106             path.moveTo(start.x - ref.x, -start.y + ref.y);
107             Point2d end =
108                 new Point2d(start.x + len * Math.cos(start.getRotZ()), start.y + len * Math.sin(start.getRotZ()));
109             path.lineTo(end.x - ref.x, -end.y + ref.y);
110             graphics.draw(path);
111 
112             if (dir.equals(LongitudinalDirectionality.DIR_PLUS) || dir.equals(LongitudinalDirectionality.DIR_BOTH))
113             {
114                 path = new Path2D.Double();
115                 path.moveTo(end.x - ref.x, -end.y + ref.y);
116                 Point2d ar1 =
117                     new Point2d(end.x + ar * Math.cos(start.getRotZ() + 0.75 * Math.PI), end.y + ar
118                         * Math.sin(start.getRotZ() + 0.75 * Math.PI));
119                 path.lineTo(ar1.x - ref.x, -ar1.y + ref.y);
120                 path.moveTo(end.x - ref.x, -end.y + ref.y);
121                 Point2d ar2 =
122                     new Point2d(end.x + ar * Math.cos(start.getRotZ() + 1.25 * Math.PI), end.y + ar
123                         * Math.sin(start.getRotZ() + 1.25 * Math.PI));
124                 path.lineTo(ar2.x - ref.x, -ar2.y + ref.y);
125                 graphics.draw(path);
126             }
127 
128             if (dir.equals(LongitudinalDirectionality.DIR_MINUS) || dir.equals(LongitudinalDirectionality.DIR_BOTH))
129             {
130                 path = new Path2D.Double();
131                 path.moveTo(start.x - ref.x, -start.y + ref.y);
132                 Point2d ar1 =
133                     new Point2d(start.x + ar * Math.cos(start.getRotZ() + 0.25 * Math.PI), start.y + ar
134                         * Math.sin(start.getRotZ() + 0.25 * Math.PI));
135                 path.lineTo(ar1.x - ref.x, -ar1.y + ref.y);
136                 path.moveTo(start.x - ref.x, -start.y + ref.y);
137                 Point2d ar2 =
138                     new Point2d(start.x + ar * Math.cos(start.getRotZ() - 0.25 * Math.PI), start.y + ar
139                         * Math.sin(start.getRotZ() - 0.25 * Math.PI));
140                 path.lineTo(ar2.x - ref.x, -ar2.y + ref.y);
141                 graphics.draw(path);
142             }
143 
144         }
145         catch (OTSGeometryException exception)
146         {
147             exception.printStackTrace();
148         }
149     }
150 
151     /** {@inheritDoc} */
152     @Override
153     public final void paint(final Graphics2D graphics, final ImageObserver observer)
154     {
155         Lane lane = (Lane) getSource();
156         PaintPolygons.paintMultiPolygon(graphics, this.color, lane.getLocation(), lane.getContour(), true);
157         // paintLine(graphics, Color.yellow, lane.getLocation(), lane.getCenterLine());
158         paintLine(graphics, Color.white, lane.getLocation(), lane.getContour());
159         paintArrow(graphics, Color.yellow, lane.getLocation(), lane.getCenterLine(), 0.25,
160             lane.getDirectionality(GTUType.ALL));
161         paintArrow(graphics, Color.green, lane.getLocation(), lane.getCenterLine(), 0.50,
162             lane.getDirectionality(GTUType.ALL));
163         paintArrow(graphics, Color.blue, lane.getLocation(), lane.getCenterLine(), 0.75,
164             lane.getDirectionality(GTUType.ALL));
165     }
166 
167     /** {@inheritDoc} */
168     @Override
169     public final String toString()
170     {
171         return "LaneAnimationOD [color=" + this.color + "]";
172     }
173 }