1 package org.opentrafficsim.animation;
2
3 import java.awt.Color;
4
5 /**
6 * List of colors to use for various legends.
7 * <p>
8 * Copyright (c) 2023-2026 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
9 * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
10 * </p>
11 * @author Peter Knoppers
12 * @author Wouter Schakel
13 */
14 public final class Colors
15 {
16
17 /** OTS blue (#0066c4). */
18 public static final Color OTS_BLUE = new Color(0, 102, 196);
19
20 /** 3-color scale from green to red. */
21 public static final Color[] GREEN_RED = new Color[] {Color.GREEN, Color.YELLOW, Color.RED};
22
23 /** 5-color scale from green to red with dark edges. */
24 public static final Color[] GREEN_RED_DARK =
25 new Color[] {Color.GREEN.darker(), Color.GREEN, Color.YELLOW, Color.RED, Color.RED.darker()};
26
27 /** 6-color scale from magenta, through red-green, to blue. */
28 public static final Color[] ULTRA =
29 new Color[] {Color.MAGENTA, Color.RED, Color.ORANGE, Color.YELLOW, Color.GREEN, Color.BLUE};
30
31 /** 10-color scale for enumeration. */
32 public static final Color[] ENUMERATE = new Color[] {Color.BLACK, new Color(0xa5, 0x2a, 0x2a), Color.RED, Color.ORANGE,
33 Color.YELLOW, Color.GREEN, Color.BLUE, Color.MAGENTA, Color.GRAY, Color.WHITE};
34
35 /** Names of the enumerated colors. */
36 public static final String[] ENUMERATE_NAMES =
37 new String[] {"black", "brown", "red", "orange", "yellow", "green", "blue", "magenta", "gray", "white"};
38
39 /**
40 * Constructor.
41 */
42 private Colors()
43 {
44 //
45 }
46
47 /**
48 * Reverses the color array.
49 * @param colors array of colors
50 * @return reversed color array
51 */
52 public static Color[] reverse(final Color[] colors)
53 {
54 Color[] out = new Color[colors.length];
55 for (int i = 0; i < colors.length; i++)
56 {
57 out[colors.length - i - 1] = colors[i];
58 }
59 return out;
60 }
61
62 /**
63 * Creates an array of {@code n} colors with varying hue.
64 * @param n number of colors.
65 * @return array of {@code n} colors with varying hue
66 */
67 public static Color[] hue(final int n)
68 {
69 Color[] out = new Color[n];
70 for (int i = 0; i < n; i++)
71 {
72 out[i] = new Color(Color.HSBtoRGB(((float) i) / n, 1.0f, 1.0f));
73 }
74 return out;
75 }
76
77 /**
78 * Returns a color for the index. Modulo is applied for indices outside of the normal range.
79 * @param index index.
80 * @return color for index.
81 */
82 public static Color getEnumerated(final int index)
83 {
84 return ENUMERATE[mod(index)];
85 }
86
87 /**
88 * Returns the name of a color for the index. Modulo is applied for indices outside of the normal range.
89 * @param index index.
90 * @return name of color for index.
91 */
92 public static String nameEnumerated(final int index)
93 {
94 return ENUMERATE_NAMES[mod(index)];
95 }
96
97 /**
98 * Returns the modulo of the index given the number of colors we have.
99 * @param index index.
100 * @return index in range of colors.
101 */
102 private static int mod(final int index)
103 {
104 return Math.abs(index % ENUMERATE.length);
105 }
106
107 /**
108 * Returns a color from an array, where the used index is determined based on the id. If the last character of the id is a
109 * digit, that value is used. Otherwise it is the absolute hash code of the id. The modulo of either of these values given
110 * the number of colors is the index in the array of the color returned.
111 * @param id object id
112 * @param colors colors to select from
113 * @return color
114 */
115 public static Color getIdColor(final String id, final Color[] colors)
116 {
117 return colors[Character.isDigit(id.charAt(id.length() - 1)) ? id.charAt(id.length() - 1) - '0'
118 : Math.abs(id.hashCode()) % colors.length];
119 }
120
121 }