FastLED 3.9.15
Loading...
Searching...
No Matches

◆ fill_gradient() [4/4]

template<typename T>
void fl::fill_gradient ( T * targetArray,
u16 startpos,
CHSV startcolor,
u16 endpos,
CHSV endcolor,
TGradientDirectionCode directionCode = SHORTEST_HUES )

Fill a range of LEDs with a smooth HSV gradient between two HSV colors.

This function can write the gradient colors either:

  1. Into an array of CRGBs (e.g., an leds[] array, or a CRGB palette)
  2. Into an array of CHSVs (e.g. a CHSV palette).

In the case of writing into a CRGB array, the gradient is computed in HSV space, and then HSV values are converted to RGB as they're written into the CRGB array.

Parameters
targetArraya pointer to the color array to fill
startposthe starting position in the array
startcolorthe starting color for the gradient
endposthe ending position in the array
endcolorthe end color for the gradient
directionCodethe direction to travel around the color wheel

Definition at line 87 of file fill.h.

89 {
90 // if the points are in the wrong order, straighten them
91 if (endpos < startpos) {
92 u16 t = endpos;
93 CHSV tc = endcolor;
94 endcolor = startcolor;
95 endpos = startpos;
96 startpos = t;
97 startcolor = tc;
98 }
99
100 // If we're fading toward black (val=0) or white (sat=0),
101 // then set the endhue to the starthue.
102 // This lets us ramp smoothly to black or white, regardless
103 // of what 'hue' was set in the endcolor (since it doesn't matter)
104 if (endcolor.value == 0 || endcolor.saturation == 0) {
105 endcolor.hue = startcolor.hue;
106 }
107
108 // Similarly, if we're fading in from black (val=0) or white (sat=0)
109 // then set the starthue to the endhue.
110 // This lets us ramp smoothly up from black or white, regardless
111 // of what 'hue' was set in the startcolor (since it doesn't matter)
112 if (startcolor.value == 0 || startcolor.saturation == 0) {
113 startcolor.hue = endcolor.hue;
114 }
115
116 saccum87 huedistance87;
117 saccum87 satdistance87;
118 saccum87 valdistance87;
119
120 satdistance87 = (endcolor.sat - startcolor.sat) << 7;
121 valdistance87 = (endcolor.val - startcolor.val) << 7;
122
123 fl::u8 huedelta8 = endcolor.hue - startcolor.hue;
124
125 if (directionCode == SHORTEST_HUES) {
126 directionCode = FORWARD_HUES;
127 if (huedelta8 > 127) {
128 directionCode = BACKWARD_HUES;
129 }
130 }
131
132 if (directionCode == LONGEST_HUES) {
133 directionCode = FORWARD_HUES;
134 if (huedelta8 < 128) {
135 directionCode = BACKWARD_HUES;
136 }
137 }
138
139 if (directionCode == FORWARD_HUES) {
140 huedistance87 = huedelta8 << 7;
141 } else /* directionCode == BACKWARD_HUES */
142 {
143 huedistance87 = (fl::u8)(256 - huedelta8) << 7;
144 huedistance87 = -huedistance87;
145 }
146
147 u16 pixeldistance = endpos - startpos;
148 i16 divisor = pixeldistance ? pixeldistance : 1;
149
150#if FASTLED_USE_32_BIT_GRADIENT_FILL
151 // Use higher precision 32 bit math for new micros.
152 i32 huedelta823 = (huedistance87 * 65536) / divisor;
153 i32 satdelta823 = (satdistance87 * 65536) / divisor;
154 i32 valdelta823 = (valdistance87 * 65536) / divisor;
155
156 huedelta823 *= 2;
157 satdelta823 *= 2;
158 valdelta823 *= 2;
159 u32 hue824 = static_cast<u32>(startcolor.hue) << 24;
160 u32 sat824 = static_cast<u32>(startcolor.sat) << 24;
161 u32 val824 = static_cast<u32>(startcolor.val) << 24;
162 for (u16 i = startpos; i <= endpos; ++i) {
163 targetArray[i] = CHSV(hue824 >> 24, sat824 >> 24, val824 >> 24);
164 hue824 += huedelta823;
165 sat824 += satdelta823;
166 val824 += valdelta823;
167 }
168#else
169 // Use 8-bit math for older micros.
170 saccum87 huedelta87 = huedistance87 / divisor;
171 saccum87 satdelta87 = satdistance87 / divisor;
172 saccum87 valdelta87 = valdistance87 / divisor;
173
174 huedelta87 *= 2;
175 satdelta87 *= 2;
176 valdelta87 *= 2;
177
178 accum88 hue88 = startcolor.hue << 8;
179 accum88 sat88 = startcolor.sat << 8;
180 accum88 val88 = startcolor.val << 8;
181 for (u16 i = startpos; i <= endpos; ++i) {
182 targetArray[i] = CHSV(hue88 >> 8, sat88 >> 8, val88 >> 8);
183 hue88 += huedelta87;
184 sat88 += satdelta87;
185 val88 += valdelta87;
186 }
187#endif // defined(__AVR__)
188}
static uint32_t t
Definition Luminova.h:54
#define saccum87
ANSI: signed short _Accum.
Definition fill.h:19
unsigned char u8
Definition int.h:17
@ SHORTEST_HUES
Hue goes whichever way is shortest.
@ LONGEST_HUES
Hue goes whichever way is longest.
@ FORWARD_HUES
Hue always goes clockwise around the color wheel.
@ BACKWARD_HUES
Hue always goes counter-clockwise around the color wheel.
u16 accum88
ANSI: unsigned short _Accum. 8 bits int, 8 bits fraction.
Definition int.h:70
Representation of an HSV pixel (hue, saturation, value (aka brightness)).
Definition hsv.h:15

References BACKWARD_HUES, FORWARD_HUES, LONGEST_HUES, saccum87, SHORTEST_HUES, and t.

Referenced by fill_gradient(), fill_gradient(), and fill_gradient().

+ Here is the caller graph for this function: