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

◆ traverseGridSegment16()

template<typename GridVisitor>
void fl::traverseGridSegment16 ( const vec2f & start,
const vec2f & end,
GridVisitor & visitor )
inline

Traverse a grid segment using fixed-point 8.8 arithmetic.

Template Parameters
GridVisitor
Parameters
startstart point
endend point
visitorcalled for each cell visited.

UNTESTED!!!!

Definition at line 123 of file traverse_grid.h.

124 {
125 const i16 FP_SHIFT = 8;
126 const i16 FP_ONE = 1 << FP_SHIFT;
127 // const i16 FP_MASK = FP_ONE - 1;
128
129 // Convert to fixed-point (Q8.8), signed
130 i16 startX_fp = static_cast<i16>(start.x * FP_ONE);
131 i16 startY_fp = static_cast<i16>(start.y * FP_ONE);
132 i16 endX_fp = static_cast<i16>(end.x * FP_ONE);
133 i16 endY_fp = static_cast<i16>(end.y * FP_ONE);
134
135 i16 x0 = startX_fp >> FP_SHIFT;
136 i16 y0 = startY_fp >> FP_SHIFT;
137 i16 x1 = endX_fp >> FP_SHIFT;
138 i16 y1 = endY_fp >> FP_SHIFT;
139
140 i16 stepX = (x1 > x0) ? 1 : (x1 < x0) ? -1 : 0;
141 i16 stepY = (y1 > y0) ? 1 : (y1 < y0) ? -1 : 0;
142
143 i16 deltaX_fp = endX_fp - startX_fp;
144 i16 deltaY_fp = endY_fp - startY_fp;
145
146 u16 absDeltaX_fp =
147 (deltaX_fp != 0) ? static_cast<u16>(
148 ABS((i32(FP_ONE) << FP_SHIFT) / deltaX_fp))
149 : UINT16_MAX;
150 u16 absDeltaY_fp =
151 (deltaY_fp != 0) ? static_cast<u16>(
152 ABS((i32(FP_ONE) << FP_SHIFT) / deltaY_fp))
153 : UINT16_MAX;
154
155 i16 nextX_fp = (stepX > 0) ? ((x0 + 1) << FP_SHIFT) : (x0 << FP_SHIFT);
156 i16 nextY_fp = (stepY > 0) ? ((y0 + 1) << FP_SHIFT) : (y0 << FP_SHIFT);
157
158 u16 tMaxX_fp =
159 (deltaX_fp != 0)
160 ? static_cast<u16>(
161 ABS(i32(nextX_fp - startX_fp)) * absDeltaX_fp >> FP_SHIFT)
162 : UINT16_MAX;
163 u16 tMaxY_fp =
164 (deltaY_fp != 0)
165 ? static_cast<u16>(
166 ABS(i32(nextY_fp - startY_fp)) * absDeltaY_fp >> FP_SHIFT)
167 : UINT16_MAX;
168
169 const u16 maxT_fp = FP_ONE;
170
171 i16 currentX = x0;
172 i16 currentY = y0;
173
174 while (true) {
175 visitor.visit(currentX, currentY);
176
177 u16 t_fp = (tMaxX_fp < tMaxY_fp) ? tMaxX_fp : tMaxY_fp;
178 if (t_fp > maxT_fp)
179 break;
180
181 if (tMaxX_fp < tMaxY_fp) {
182 tMaxX_fp += absDeltaX_fp;
183 currentX += stepX;
184 } else {
185 tMaxY_fp += absDeltaY_fp;
186 currentY += stepY;
187 }
188 }
189
190 // Ensure the end cell (x1, y1) is visited at least once
191 if (currentX != x1 || currentY != y1) {
192 visitor.visit(x1, y1);
193 }
194}
#define ABS(x)
Definition math_macros.h:45
constexpr T * end(T(&array)[N]) noexcept
value_type y
Definition geometry.h:191
value_type x
Definition geometry.h:190

References ABS, end(), fl::vec2< T >::x, and fl::vec2< T >::y.

Referenced by traverseGridSegment().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: