View Javadoc
1   package org.opentrafficsim.core.gtu.animation;
2   
3   import java.awt.Color;
4   import java.io.Serializable;
5   import java.util.ArrayList;
6   import java.util.Collections;
7   import java.util.List;
8   
9   import org.djunits.value.vdouble.scalar.Acceleration;
10  import org.opentrafficsim.core.gtu.GTU;
11  
12  /**
13   * Color GTUs based on their current acceleration.
14   * <p>
15   * Copyright (c) 2013-2017 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
16   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
17   * <p>
18   * @version $Revision: 3570 $, $LastChangedDate: 2017-04-29 12:51:08 +0200 (Sat, 29 Apr 2017) $, by $Author: averbraeck $,
19   *          initial version 29 mei 2015 <br>
20   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
21   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
22   */
23  public class AccelerationGTUColorer implements GTUColorer, Serializable
24  {
25      /** */
26      private static final long serialVersionUID = 201500001L;
27  
28      /** The legend. */
29      private final ArrayList<LegendEntry> legend;
30  
31      /** The deceleration that corresponds to the first entry in the legend. */
32      private final Acceleration maximumDeceleration;
33  
34      /** The deceleration that corresponds to the last entry in the legend. */
35      private final Acceleration maximumAcceleration;
36  
37      /** Negative scale part of the range of colors (excluding the zero value). */
38      private static Color[] decelerationColors = { Color.MAGENTA, Color.RED, Color.ORANGE, Color.YELLOW };
39  
40      /** Positive scale part of the range of colors (including the zero value). */
41      private static Color[] accelerationColors = { Color.YELLOW, Color.GREEN, Color.BLUE };
42  
43      /**
44       * Construct a new AccelerationGTUColorer.
45       * @param maximumDeceleration Acceleration; the deceleration (negative acceleration) that corresponds to the first (red)
46       *            legend entry
47       * @param maximumAcceleration Acceleration; the deceleration that corresponds to the last (blue) legend entry
48       */
49      public AccelerationGTUColorer(final Acceleration maximumDeceleration, final Acceleration maximumAcceleration)
50      {
51          this.maximumDeceleration = maximumDeceleration;
52          this.maximumAcceleration = maximumAcceleration;
53          this.legend = new ArrayList<>(6);
54          for (int index = 0; index < decelerationColors.length - 1; index++)
55          {
56              double ratio = index * 1.0 / (decelerationColors.length - 1);
57              Acceleration acceleration = Acceleration.interpolate(this.maximumDeceleration, Acceleration.ZERO, ratio);
58              this.legend.add(new LegendEntry(decelerationColors[index], acceleration.toString(),
59                      "deceleration" + acceleration.toString()));
60          }
61          for (int index = 0; index < accelerationColors.length; index++)
62          {
63              double ratio = index * 1.0 / (accelerationColors.length - 1);
64              Acceleration acceleration = Acceleration.interpolate(Acceleration.ZERO, this.maximumAcceleration, ratio);
65              this.legend.add(new LegendEntry(accelerationColors[index], acceleration.toString(),
66                      "acceleration" + acceleration.toString()));
67          }
68      }
69  
70      /** {@inheritDoc} */
71      @Override
72      public final Color getColor(final GTU gtu)
73      {
74          Acceleration acceleration = gtu.getAcceleration();
75          double ratio;
76          if (acceleration.getSI() < 0)
77          {
78              ratio = decelerationColors.length - 1
79                      - acceleration.getSI() / this.maximumDeceleration.getSI() * (decelerationColors.length - 1);
80          }
81          else
82          {
83              ratio = acceleration.getSI() / this.maximumAcceleration.getSI() * (accelerationColors.length - 1)
84                      + decelerationColors.length - 1;
85          }
86          if (ratio <= 0)
87          {
88              return this.legend.get(0).getColor();
89          }
90          if (ratio >= this.legend.size() - 1)
91          {
92              return this.legend.get(this.legend.size() - 1).getColor();
93          }
94          // Interpolate
95          int floor = (int) Math.floor(ratio);
96          return ColorInterpolator.interpolateColor(this.legend.get(floor).getColor(), this.legend.get(floor + 1).getColor(),
97                  ratio - floor);
98      }
99  
100     /** {@inheritDoc} */
101     @Override
102     public final List<LegendEntry> getLegend()
103     {
104         return Collections.unmodifiableList(this.legend);
105     }
106 
107     /** {@inheritDoc} */
108     @Override
109     public final String toString()
110     {
111         return "Acceleration";
112     }
113 
114 }