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.geometry.OTSGeometryException;
15  import org.opentrafficsim.core.geometry.OTSLine3D;
16  import org.opentrafficsim.core.geometry.OTSPoint3D;
17  import org.opentrafficsim.core.gtu.GTUType;
18  import org.opentrafficsim.core.network.LongitudinalDirectionality;
19  import org.opentrafficsim.draw.core.PaintPolygons;
20  import org.opentrafficsim.road.network.lane.Lane;
21  
22  import nl.tudelft.simulation.dsol.animation.D2.Renderable2D;
23  import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
24  import nl.tudelft.simulation.language.d3.DirectedPoint;
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  public class LaneAnimationOD extends Renderable2D implements Serializable
36  {
37      
38      private static final long serialVersionUID = 20141017L;
39  
40      
41      private final Color color;
42  
43      
44  
45  
46  
47  
48  
49  
50      public LaneAnimationOD(final Lane source, final SimulatorInterface.TimeDoubleUnit simulator, final Color color)
51              throws NamingException, RemoteException
52      {
53          super(source, simulator);
54          this.color = color;
55      }
56  
57      
58  
59  
60  
61  
62  
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)); 
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  
88  
89  
90  
91  
92  
93  
94  
95      private static void paintArrow(final Graphics2D graphics, final Color color, final DirectedPoint ref, final OTSLine3D line,
96              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 = new Point2d(start.x + len * Math.cos(start.getRotZ()), start.y + len * Math.sin(start.getRotZ()));
108             path.lineTo(end.x - ref.x, -end.y + ref.y);
109             graphics.draw(path);
110 
111             if (dir.equals(LongitudinalDirectionality.DIR_PLUS) || dir.equals(LongitudinalDirectionality.DIR_BOTH))
112             {
113                 path = new Path2D.Double();
114                 path.moveTo(end.x - ref.x, -end.y + ref.y);
115                 Point2d ar1 = new Point2d(end.x + ar * Math.cos(start.getRotZ() + 0.75 * Math.PI),
116                         end.y + ar * Math.sin(start.getRotZ() + 0.75 * Math.PI));
117                 path.lineTo(ar1.x - ref.x, -ar1.y + ref.y);
118                 path.moveTo(end.x - ref.x, -end.y + ref.y);
119                 Point2d ar2 = new Point2d(end.x + ar * Math.cos(start.getRotZ() + 1.25 * Math.PI),
120                         end.y + ar * Math.sin(start.getRotZ() + 1.25 * Math.PI));
121                 path.lineTo(ar2.x - ref.x, -ar2.y + ref.y);
122                 graphics.draw(path);
123             }
124 
125             if (dir.equals(LongitudinalDirectionality.DIR_MINUS) || dir.equals(LongitudinalDirectionality.DIR_BOTH))
126             {
127                 path = new Path2D.Double();
128                 path.moveTo(start.x - ref.x, -start.y + ref.y);
129                 Point2d ar1 = new Point2d(start.x + ar * Math.cos(start.getRotZ() + 0.25 * Math.PI),
130                         start.y + ar * Math.sin(start.getRotZ() + 0.25 * Math.PI));
131                 path.lineTo(ar1.x - ref.x, -ar1.y + ref.y);
132                 path.moveTo(start.x - ref.x, -start.y + ref.y);
133                 Point2d ar2 = new Point2d(start.x + ar * Math.cos(start.getRotZ() - 0.25 * Math.PI),
134                         start.y + ar * Math.sin(start.getRotZ() - 0.25 * Math.PI));
135                 path.lineTo(ar2.x - ref.x, -ar2.y + ref.y);
136                 graphics.draw(path);
137             }
138 
139         }
140         catch (OTSGeometryException exception)
141         {
142             exception.printStackTrace();
143         }
144     }
145 
146     
147     @Override
148     public final void paint(final Graphics2D graphics, final ImageObserver observer)
149     {
150         Lane lane = (Lane) getSource();
151         PaintPolygons.paintMultiPolygon(graphics, this.color, lane.getLocation(), lane.getContour(), true);
152         
153         paintLine(graphics, Color.white, lane.getLocation(), lane.getContour());
154         paintArrow(graphics, Color.yellow, lane.getLocation(), lane.getCenterLine(), 0.25,
155                 lane.getLaneType().getDirectionality(GTUType.VEHICLE));
156         paintArrow(graphics, Color.green, lane.getLocation(), lane.getCenterLine(), 0.50,
157                 lane.getLaneType().getDirectionality(GTUType.VEHICLE));
158         paintArrow(graphics, Color.blue, lane.getLocation(), lane.getCenterLine(), 0.75,
159                 lane.getLaneType().getDirectionality(GTUType.VEHICLE));
160     }
161 
162     
163     @Override
164     public final String toString()
165     {
166         return "LaneAnimationOD [color=" + this.color + "]";
167     }
168 }