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

◆ fill_gradient() [4/4]

template<typename T>
void fill_gradient ( T * targetArray,
uint16_t startpos,
CHSV startcolor,
uint16_t 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 189 of file colorutils.h.

193{
194 // if the points are in the wrong order, straighten them
195 if( endpos < startpos ) {
196 uint16_t t = endpos;
197 CHSV tc = endcolor;
198 endcolor = startcolor;
199 endpos = startpos;
200 startpos = t;
201 startcolor = tc;
202 }
203
204 // If we're fading toward black (val=0) or white (sat=0),
205 // then set the endhue to the starthue.
206 // This lets us ramp smoothly to black or white, regardless
207 // of what 'hue' was set in the endcolor (since it doesn't matter)
208 if( endcolor.value == 0 || endcolor.saturation == 0) {
209 endcolor.hue = startcolor.hue;
210 }
211
212 // Similarly, if we're fading in from black (val=0) or white (sat=0)
213 // then set the starthue to the endhue.
214 // This lets us ramp smoothly up from black or white, regardless
215 // of what 'hue' was set in the startcolor (since it doesn't matter)
216 if( startcolor.value == 0 || startcolor.saturation == 0) {
217 startcolor.hue = endcolor.hue;
218 }
219
220 saccum87 huedistance87;
221 saccum87 satdistance87;
222 saccum87 valdistance87;
223
224 satdistance87 = (endcolor.sat - startcolor.sat) << 7;
225 valdistance87 = (endcolor.val - startcolor.val) << 7;
226
227 uint8_t huedelta8 = endcolor.hue - startcolor.hue;
228
229 if( directionCode == SHORTEST_HUES ) {
230 directionCode = FORWARD_HUES;
231 if( huedelta8 > 127) {
232 directionCode = BACKWARD_HUES;
233 }
234 }
235
236 if( directionCode == LONGEST_HUES ) {
237 directionCode = FORWARD_HUES;
238 if( huedelta8 < 128) {
239 directionCode = BACKWARD_HUES;
240 }
241 }
242
243 if( directionCode == FORWARD_HUES) {
244 huedistance87 = huedelta8 << 7;
245 }
246 else /* directionCode == BACKWARD_HUES */
247 {
248 huedistance87 = (uint8_t)(256 - huedelta8) << 7;
249 huedistance87 = -huedistance87;
250 }
251
252 uint16_t pixeldistance = endpos - startpos;
253 int16_t divisor = pixeldistance ? pixeldistance : 1;
254
255 #if FASTLED_USE_32_BIT_GRADIENT_FILL
256 // Use higher precision 32 bit math for new micros.
257 int32_t huedelta823 = (huedistance87 * 65536) / divisor;
258 int32_t satdelta823 = (satdistance87 * 65536) / divisor;
259 int32_t valdelta823 = (valdistance87 * 65536) / divisor;
260
261 huedelta823 *= 2;
262 satdelta823 *= 2;
263 valdelta823 *= 2;
264 uint32_t hue824 = static_cast<uint32_t>(startcolor.hue) << 24;
265 uint32_t sat824 = static_cast<uint32_t>(startcolor.sat) << 24;
266 uint32_t val824 = static_cast<uint32_t>(startcolor.val) << 24;
267 for( uint16_t i = startpos; i <= endpos; ++i) {
268 targetArray[i] = CHSV( hue824 >> 24, sat824 >> 24, val824 >> 24);
269 hue824 += huedelta823;
270 sat824 += satdelta823;
271 val824 += valdelta823;
272 }
273 #else
274 // Use 8-bit math for older micros.
275 saccum87 huedelta87 = huedistance87 / divisor;
276 saccum87 satdelta87 = satdistance87 / divisor;
277 saccum87 valdelta87 = valdistance87 / divisor;
278
279 huedelta87 *= 2;
280 satdelta87 *= 2;
281 valdelta87 *= 2;
282
283 accum88 hue88 = startcolor.hue << 8;
284 accum88 sat88 = startcolor.sat << 8;
285 accum88 val88 = startcolor.val << 8;
286 for( uint16_t i = startpos; i <= endpos; ++i) {
287 targetArray[i] = CHSV( hue88 >> 8, sat88 >> 8, val88 >> 8);
288 hue88 += huedelta87;
289 sat88 += satdelta87;
290 val88 += valdelta87;
291 }
292 #endif // defined(__AVR__)
293}
@ LONGEST_HUES
Hue goes whichever way is longest.
Definition colorutils.h:164
@ FORWARD_HUES
Hue always goes clockwise around the color wheel.
Definition colorutils.h:161
@ SHORTEST_HUES
Hue goes whichever way is shortest.
Definition colorutils.h:163
@ BACKWARD_HUES
Hue always goes counter-clockwise around the color wheel.
Definition colorutils.h:162
#define saccum87
ANSI: signed short _Accum.
Definition colorutils.h:170
uint16_t accum88
ANSI: unsigned short _Accum. 8 bits int, 8 bits fraction.
Definition types.h:58
Representation of an HSV pixel (hue, saturation, value (aka brightness)).
Definition chsv.h:16

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

Referenced by CHSVPalette16::CHSVPalette16(), CHSVPalette16::CHSVPalette16(), CHSVPalette16::CHSVPalette16(), CHSVPalette256::CHSVPalette256(), CHSVPalette256::CHSVPalette256(), CHSVPalette256::CHSVPalette256(), CHSVPalette32::CHSVPalette32(), CHSVPalette32::CHSVPalette32(), CHSVPalette32::CHSVPalette32(), CRGBPalette16::CRGBPalette16(), CRGBPalette16::CRGBPalette16(), CRGBPalette16::CRGBPalette16(), CRGBPalette256::CRGBPalette256(), CRGBPalette256::CRGBPalette256(), CRGBPalette256::CRGBPalette256(), CRGBPalette32::CRGBPalette32(), CRGBPalette32::CRGBPalette32(), CRGBPalette32::CRGBPalette32(), fill_gradient(), fill_gradient(), and fill_gradient().

+ Here is the caller graph for this function: