View Javadoc
1   package org.opentrafficsim.road.gtu.animation;
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.Rectangle2D;
8   import java.awt.image.ImageObserver;
9   import java.io.Serializable;
10  import java.rmi.RemoteException;
11  
12  import javax.naming.NamingException;
13  
14  import nl.tudelft.simulation.dsol.animation.D2.Renderable2D;
15  
16  import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
17  import org.opentrafficsim.core.gtu.animation.GTUColorer;
18  import org.opentrafficsim.core.gtu.animation.IDGTUColorer;
19  import org.opentrafficsim.road.gtu.lane.LaneBasedIndividualGTU;
20  
21  /**
22   * Draw a car.
23   * <p>
24   * Copyright (c) 2013-2016 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
25   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
26   * <p>
27   * @version $Revision: 1401 $, $LastChangedDate: 2015-09-14 01:33:02 +0200 (Mon, 14 Sep 2015) $, by $Author: averbraeck $,
28   *          initial version 29 dec. 2014 <br>
29   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
30   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
31   */
32  public class DefaultCarAnimation extends Renderable2D implements Serializable
33  {
34      /** */
35      private static final long serialVersionUID = 20150000L;
36      
37      /** The GTUColorer that determines the fill color for the car. */
38      private GTUColorer gtuColorer;
39  
40      /**
41       * Construct the DefaultCarAnimation for a LaneBasedIndividualCar.
42       * @param source the Car to draw
43       * @param simulator the simulator to schedule on
44       * @throws NamingException in case of registration failure of the animation
45       * @throws RemoteException on communication failure
46       */
47      public DefaultCarAnimation(final LaneBasedIndividualGTU source, final OTSSimulatorInterface simulator)
48          throws NamingException, RemoteException
49      {
50          this(source, simulator, null);
51      }
52  
53      /**
54       * Construct the DefaultCarAnimation for a LaneBasedIndividualCar.
55       * @param source the Car to draw
56       * @param simulator the simulator to schedule on
57       * @param gtuColorer GTUColorer; the GTUColorer that determines what fill color to use
58       * @throws NamingException in case of registration failure of the animation
59       * @throws RemoteException on communication failure
60       */
61      public DefaultCarAnimation(final LaneBasedIndividualGTU source, final OTSSimulatorInterface simulator,
62          final GTUColorer gtuColorer) throws NamingException, RemoteException
63      {
64          super(source, simulator);
65          if (null == gtuColorer)
66          {
67              this.gtuColorer = new IDGTUColorer();
68          }
69          else
70          {
71              this.gtuColorer = gtuColorer;
72          }
73      }
74  
75      /**
76       * Replace the GTUColorer.
77       * @param newGTUColorer GTUColorer; the GTUColorer to use from now on
78       */
79      public final void setGTUColorer(final GTUColorer newGTUColorer)
80      {
81          this.gtuColorer = newGTUColorer;
82      }
83  
84      /** {@inheritDoc} */
85      @Override
86      public final void paint(final Graphics2D graphics, final ImageObserver observer)
87      {
88          final LaneBasedIndividualGTU car = (LaneBasedIndividualGTU) getSource();
89  
90          if (car.isDestroyed())
91          {
92              try
93              {
94                  destroy();
95              }
96              catch (Exception e)
97              {
98                  System.err.println("GTU: " + car.toString());
99                  e.printStackTrace();
100             }
101         }
102 
103         final double length = car.getLength().getSI();
104         final double l2 = length / 2;
105         final double width = car.getWidth().getSI();
106         final double w2 = width / 2;
107         final double w4 = width / 4;
108         graphics.setColor(this.gtuColorer.getColor(car));
109         BasicStroke saveStroke = (BasicStroke) graphics.getStroke();
110         graphics.setStroke(new BasicStroke(0));
111         Rectangle2D rectangle = new Rectangle2D.Double(-l2, -w2, length, width);
112         graphics.draw(rectangle);
113         graphics.fill(rectangle);
114         // Draw a white disk at the front to indicate which side faces forward
115         graphics.setColor(Color.WHITE);
116         Ellipse2D.Double frontIndicator = new Ellipse2D.Double(l2 - w2 - w4, -w4, w2, w2);
117         graphics.draw(frontIndicator);
118         graphics.fill(frontIndicator);
119 
120         graphics.setColor(Color.YELLOW);
121         if (car.getTurnIndicatorStatus() != null && car.getTurnIndicatorStatus().isLeftOrBoth())
122         {
123             Rectangle2D.Double leftIndicator = new Rectangle2D.Double(l2 - w4, -w2, w4, w4);
124             graphics.fill(leftIndicator);
125         }
126         
127         if (car.getTurnIndicatorStatus() != null && car.getTurnIndicatorStatus().isRightOrBoth())
128         {
129             Rectangle2D.Double rightIndicator = new Rectangle2D.Double(l2 - w4, w2 - w4, w4, w4);
130             graphics.fill(rightIndicator);            
131         }
132         
133         graphics.setColor(Color.RED);
134         if (car.getAcceleration().si < -0.5) // TODO this could be a property of a GTU 
135         {
136             Rectangle2D.Double leftBrake = new Rectangle2D.Double(-l2, w2 - w4, w4, w4);
137             Rectangle2D.Double rightBrake = new Rectangle2D.Double(-l2, -w2, w4, w4);
138             graphics.setColor(Color.RED);
139             graphics.fill(leftBrake);
140             graphics.fill(rightBrake);
141         }
142         graphics.setStroke(saveStroke);
143     }
144 
145     /** {@inheritDoc} */
146     @Override
147     public final String toString()
148     {
149         return this.getSource().toString();
150     }
151 
152 }