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