1616 */
1717public class ColorMap {
1818 private final boolean overrideModeGreater ;
19- private final List < LerpSegment > segments ;
19+ private final NavigableMap < Float , LerpSegment > segments ;
2020 private final NavigableMap <Float , Color > overridePoints ;
2121 private final Color base ;
2222
23- private ColorMap (Color base , boolean overrideModeGreater , List <LerpSegment > segments , NavigableMap <Float , Color > overridePoints ) {
23+ private final float min ;
24+ private final float max ;
25+ private Color [] lookup ;
26+ private float resolution ;
27+
28+ private ColorMap (Color base , boolean overrideModeGreater , List <LerpSegment > segments , NavigableMap <Float , Color > overridePoints , float resolution ) {
29+ this .min = Math .round (segments .getFirst ().start / resolution ) * resolution ;
30+ this .max = Math .round (segments .getLast ().end / resolution ) * resolution ;
31+
2432 this .base = base ;
2533 this .overrideModeGreater = overrideModeGreater ;
26- this .segments = segments ;
34+ this .segments = new TreeMap <>();
35+ for (LerpSegment seg : segments ) {
36+ this .segments .put (seg .start , seg );
37+ }
2738 this .overridePoints = overridePoints ;
39+
40+ recomputeLookups (resolution );
2841 }
2942
3043 /**
@@ -33,7 +46,7 @@ private ColorMap(Color base, boolean overrideModeGreater, List<LerpSegment> segm
3346 * @since 0.14.15.6
3447 */
3548 public float minValue () {
36- return segments . getFirst (). start ;
49+ return min ;
3750 }
3851
3952 /**
@@ -42,26 +55,65 @@ public float minValue() {
4255 * @since 0.14.15.6
4356 */
4457 public float maxValue () {
45- return segments .getLast ().end ;
58+ return max ;
59+ }
60+
61+ /**
62+ * Recomputes the lookup table with the given resolution.
63+ * @param resolution The new resolution
64+ * @since 0.14.16.1
65+ */
66+ public void recomputeLookups (float resolution ) {
67+ this .resolution = resolution ;
68+ int size = (int ) (((max - min ) / resolution ) + 1 );
69+ this .lookup = new Color [size ];
70+
71+ for (int i = 0 ; i < size ; i ++) {
72+ float val = min + i * resolution ;
73+ lookup [i ] = getAccurate (val );
74+ }
4675 }
4776
4877 /**
49- * Gets the {@link Color} for the specific value
78+ * Retrieves the color value using the closest value from the lookup table.
79+ * If you need the accurate value, use {@link #getAccurate(float)} instead
80+ * @param val The value to get a color for
81+ * @return The approximate color for this value
82+ * @since 0.14.16.1
83+ * @see #getAccurate(float)
84+ */
85+ public Color get (float val ) {
86+ float newVal = Math .round (val / resolution ) * resolution ;
87+ if (newVal <= min ) return lookup [0 ];
88+ if (newVal >= max ) return lookup [lookup .length - 1 ];
89+ int idx = (int ) ((newVal - min ) / resolution );
90+ return lookup [idx ];
91+ }
92+
93+ /**
94+ * Gets the {@link Color} for the specific value.
95+ * <br>
96+ * This method is <strong>SLOWER</strong> and oftentimes the same as {@link #get(float)}.
97+ * Use that instead if you only need the approximate value
5098 * @param val The value to get the {@link Color} of
5199 * @return The {@link Color} for the given value
52100 * @since 0.14.15.6
101+ * @see #get(float)
53102 */
54- public Color get (float val ) {
103+ public Color getAccurate (float val ) {
55104 Color currentColor = base ;
56105
57106 Map .Entry <Float , Color > override = overridePoints .floorEntry (val );
58107 if (override != null ) {
59108 currentColor = override .getValue ();
60109 }
61110
62- for (LerpSegment seg : segments ) {
63- if (val >= seg .start && (overrideModeGreater ? val <= seg .end : val < seg .end )) {
111+ Map .Entry <Float , LerpSegment > entry = segments .floorEntry (val );
112+ if (entry != null ) {
113+ LerpSegment seg = entry .getValue ();
114+ if (overrideModeGreater ? val <= seg .end : val < seg .end ) {
64115 float delta = (val - seg .start ) / (seg .end - seg .start );
116+ delta = delta > 1 ? 1 : delta < 0 ? 0 : delta ;
65117 return lerp (delta , seg .from , seg .to );
66118 }
67119 }
@@ -78,7 +130,6 @@ public Color get(float val) {
78130 * @since 0.14.15.6
79131 */
80132 public static Color lerp (float delta , Color c1 , Color c2 ) {
81- delta = Math .max (0.0F , Math .min (1.0F , delta ));
82133 float r = c1 .getRed () + delta * (c2 .getRed () - c1 .getRed ());
83134 float g = c1 .getGreen () + delta * (c2 .getGreen () - c1 .getGreen ());
84135 float b = c1 .getBlue () + delta * (c2 .getBlue () - c1 .getBlue ());
@@ -104,7 +155,7 @@ public static class Builder {
104155 private final NavigableMap <Float , Color > overridePoints = new TreeMap <>();
105156 private final Color base ;
106157 private boolean overrideModeGreater = false ;
107- private float lastThreshold = Float .NEGATIVE_INFINITY ;
158+ private float lastThreshold = Float .NEGATIVE_INFINITY , resolution = 0.1F ;
108159 private Color lastColor ;
109160
110161 private Builder (Color base ) {
@@ -122,6 +173,18 @@ public static Builder of(Color base) {
122173 return new Builder (base );
123174 }
124175
176+ /**
177+ * Sets the step size between each value in the lookup table.
178+ * A value too small may be storing the same color multiple times!
179+ * @param resolution The resolution of the lookup table. Default 0.1F
180+ * @return This {@link Builder}
181+ * @since 0.14.16.1
182+ */
183+ public Builder lookupResolution (float resolution ) {
184+ this .resolution = resolution ;
185+ return this ;
186+ }
187+
125188 /**
126189 * Use in cases where you want overrides to only apply when the value is greater, but not equal to the threshold.
127190 * Used in {@link ColorMaps#POSITIVE_VELOCITY} and {@link ColorMaps#NEGATIVE_VELOCITY}
@@ -182,7 +245,7 @@ public ColorMap build(Color finalColor, float finalThreshold) {
182245 else overridePoints .put (finalThreshold , finalColor );
183246
184247 segments .add (new LerpSegment (lastThreshold , lastColor , finalThreshold , finalColor ));
185- return new ColorMap (base , overrideModeGreater , segments , overridePoints );
248+ return new ColorMap (base , overrideModeGreater , segments , overridePoints , resolution );
186249 }
187250 }
188251}
0 commit comments