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

◆ fill_gradient() [4/4]

template<typename T>
void fl::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 77 of file fill.h.

79 {
80 // if the points are in the wrong order, straighten them
81 if (endpos < startpos) {
82 uint16_t t = endpos;
83 CHSV tc = endcolor;
84 endcolor = startcolor;
85 endpos = startpos;
86 startpos = t;
87 startcolor = tc;
88 }
89
90 // If we're fading toward black (val=0) or white (sat=0),
91 // then set the endhue to the starthue.
92 // This lets us ramp smoothly to black or white, regardless
93 // of what 'hue' was set in the endcolor (since it doesn't matter)
94 if (endcolor.value == 0 || endcolor.saturation == 0) {
95 endcolor.hue = startcolor.hue;
96 }
97
98 // Similarly, if we're fading in from black (val=0) or white (sat=0)
99 // then set the starthue to the endhue.
100 // This lets us ramp smoothly up from black or white, regardless
101 // of what 'hue' was set in the startcolor (since it doesn't matter)
102 if (startcolor.value == 0 || startcolor.saturation == 0) {
103 startcolor.hue = endcolor.hue;
104 }
105
106 saccum87 huedistance87;
107 saccum87 satdistance87;
108 saccum87 valdistance87;
109
110 satdistance87 = (endcolor.sat - startcolor.sat) << 7;
111 valdistance87 = (endcolor.val - startcolor.val) << 7;
112
113 uint8_t huedelta8 = endcolor.hue - startcolor.hue;
114
115 if (directionCode == SHORTEST_HUES) {
116 directionCode = FORWARD_HUES;
117 if (huedelta8 > 127) {
118 directionCode = BACKWARD_HUES;
119 }
120 }
121
122 if (directionCode == LONGEST_HUES) {
123 directionCode = FORWARD_HUES;
124 if (huedelta8 < 128) {
125 directionCode = BACKWARD_HUES;
126 }
127 }
128
129 if (directionCode == FORWARD_HUES) {
130 huedistance87 = huedelta8 << 7;
131 } else /* directionCode == BACKWARD_HUES */
132 {
133 huedistance87 = (uint8_t)(256 - huedelta8) << 7;
134 huedistance87 = -huedistance87;
135 }
136
137 uint16_t pixeldistance = endpos - startpos;
138 int16_t divisor = pixeldistance ? pixeldistance : 1;
139
140#if FASTLED_USE_32_BIT_GRADIENT_FILL
141 // Use higher precision 32 bit math for new micros.
142 int32_t huedelta823 = (huedistance87 * 65536) / divisor;
143 int32_t satdelta823 = (satdistance87 * 65536) / divisor;
144 int32_t valdelta823 = (valdistance87 * 65536) / divisor;
145
146 huedelta823 *= 2;
147 satdelta823 *= 2;
148 valdelta823 *= 2;
149 uint32_t hue824 = static_cast<uint32_t>(startcolor.hue) << 24;
150 uint32_t sat824 = static_cast<uint32_t>(startcolor.sat) << 24;
151 uint32_t val824 = static_cast<uint32_t>(startcolor.val) << 24;
152 for (uint16_t i = startpos; i <= endpos; ++i) {
153 targetArray[i] = CHSV(hue824 >> 24, sat824 >> 24, val824 >> 24);
154 hue824 += huedelta823;
155 sat824 += satdelta823;
156 val824 += valdelta823;
157 }
158#else
159 // Use 8-bit math for older micros.
160 saccum87 huedelta87 = huedistance87 / divisor;
161 saccum87 satdelta87 = satdistance87 / divisor;
162 saccum87 valdelta87 = valdistance87 / divisor;
163
164 huedelta87 *= 2;
165 satdelta87 *= 2;
166 valdelta87 *= 2;
167
168 accum88 hue88 = startcolor.hue << 8;
169 accum88 sat88 = startcolor.sat << 8;
170 accum88 val88 = startcolor.val << 8;
171 for (uint16_t i = startpos; i <= endpos; ++i) {
172 targetArray[i] = CHSV(hue88 >> 8, sat88 >> 8, val88 >> 8);
173 hue88 += huedelta87;
174 sat88 += satdelta87;
175 val88 += valdelta87;
176 }
177#endif // defined(__AVR__)
178}
#define saccum87
ANSI: signed short _Accum.
Definition fill.h:9
uint16_t accum88
ANSI: unsigned short _Accum. 8 bits int, 8 bits fraction.
Definition types.h:58
@ 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.
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 fill_gradient(), fill_gradient(), and fill_gradient().

+ Here is the caller graph for this function: