| 205 | /// @details UNTESTED!!!! |
| 206 | template <typename GridVisitor> |
| 207 | inline void traverseGridSegment32(const vec2f &start, const vec2f &end, |
| 208 | GridVisitor &visitor) { |
| 209 | const i32 FP_SHIFT = 8; |
| 210 | const i32 FP_ONE = 1 << FP_SHIFT; |
| 211 | // const i32 FP_MASK = FP_ONE - 1; |
| 212 | |
| 213 | // Convert to fixed-point (Q24.8) signed |
| 214 | i32 startX_fp = static_cast<i32>(start.x * FP_ONE); |
| 215 | i32 startY_fp = static_cast<i32>(start.y * FP_ONE); |
| 216 | i32 endX_fp = static_cast<i32>(end.x * FP_ONE); |
| 217 | i32 endY_fp = static_cast<i32>(end.y * FP_ONE); |
| 218 | |
| 219 | i32 x0 = startX_fp >> FP_SHIFT; |
| 220 | i32 y0 = startY_fp >> FP_SHIFT; |
| 221 | i32 x1 = endX_fp >> FP_SHIFT; |
| 222 | i32 y1 = endY_fp >> FP_SHIFT; |
| 223 | |
| 224 | i32 stepX = (x1 > x0) ? 1 : (x1 < x0) ? -1 : 0; |
| 225 | i32 stepY = (y1 > y0) ? 1 : (y1 < y0) ? -1 : 0; |
| 226 | |
| 227 | i32 deltaX_fp = endX_fp - startX_fp; |
| 228 | i32 deltaY_fp = endY_fp - startY_fp; |
| 229 | |
| 230 | // Use (max)() to prevent macro expansion by Arduino.h's max macro |
| 231 | u32 absDeltaX_fp = |
| 232 | (deltaX_fp != 0) ? static_cast<u32>( |
| 233 | fl::abs((fl::i64(FP_ONE) << FP_SHIFT) / deltaX_fp)) |
| 234 | : (fl::numeric_limits<u32>::max)(); |
| 235 | u32 absDeltaY_fp = |
| 236 | (deltaY_fp != 0) ? static_cast<u32>( |
| 237 | fl::abs((fl::i64(FP_ONE) << FP_SHIFT) / deltaY_fp)) |
| 238 | : (fl::numeric_limits<u32>::max)(); |
| 239 | |
| 240 | i32 nextX_fp = (stepX > 0) ? ((x0 + 1) << FP_SHIFT) : (x0 << FP_SHIFT); |
| 241 | i32 nextY_fp = (stepY > 0) ? ((y0 + 1) << FP_SHIFT) : (y0 << FP_SHIFT); |
| 242 | |
| 243 | // Use (max)() to prevent macro expansion by Arduino.h's max macro |
| 244 | u32 tMaxX_fp = |
| 245 | (deltaX_fp != 0) |
| 246 | ? static_cast<u32>( |
| 247 | fl::abs(fl::i64(nextX_fp - startX_fp)) * absDeltaX_fp >> FP_SHIFT) |
| 248 | : (fl::numeric_limits<u32>::max)(); |
| 249 | u32 tMaxY_fp = |
| 250 | (deltaY_fp != 0) |
| 251 | ? static_cast<u32>( |
| 252 | fl::abs(fl::i64(nextY_fp - startY_fp)) * absDeltaY_fp >> FP_SHIFT) |
| 253 | : (fl::numeric_limits<u32>::max)(); |
| 254 | |
| 255 | const u32 maxT_fp = FP_ONE; |
| 256 | |
| 257 | i32 currentX = x0; |
| 258 | i32 currentY = y0; |
| 259 | |
| 260 | while (true) { |
| 261 | visitor.visit(currentX, currentY); |
| 262 | |
| 263 | u32 t_fp = (tMaxX_fp < tMaxY_fp) ? tMaxX_fp : tMaxY_fp; |
| 264 | if (t_fp > maxT_fp) |
no test coverage detected