@@ -361,6 +361,49 @@ inline std::ostream &logDuration(std::ostream &out, const D &duration)
361361 }
362362 return out;
363363}
364+
365+ inline int sign (double x)
366+ {
367+ return (x > 0.0 ) - (x < 0.0 );
368+ }
369+
370+ // for similar appraoch see: https://github.com/StrandedKitty/tiles-intersect/blob/master/src/index.js
371+ template <class T >
372+ void walkGrid (const Eigen::Vector3d &start, const Eigen::Vector3d &end, T &object)
373+ {
374+ Eigen::Vector3d direction = end - start;
375+ double max_length = direction.norm ();
376+ Eigen::Vector3i p = Eigen::Vector3d (std::floor (start[0 ]), std::floor (start[1 ]), std::floor (start[2 ])).cast <int >();
377+ const Eigen::Vector3i target = Eigen::Vector3d (std::floor (end[0 ]), std::floor (end[1 ]), std::floor (end[2 ])).cast <int >();
378+
379+ const Eigen::Vector3i step (sign (direction[0 ]), sign (direction[1 ]), sign (direction[2 ]));
380+ direction /= max_length;
381+ Eigen::Vector3d lengths, length_delta;
382+ for (int j = 0 ; j<3 ; j++)
383+ {
384+ const double to = std::abs (start[j] - p[j] - (double )std::max (0 , step[j]));
385+ const double dir = std::max (std::numeric_limits<double >::epsilon (), std::abs (direction[j]));
386+ lengths[j] = to / dir;
387+ length_delta[j] = 1.0 / dir;
388+ }
389+ int ax = lengths[0 ] < lengths[1 ] && lengths[0 ] < lengths[2 ] ? 0 : (lengths[1 ] < lengths[2 ] ? 1 : 2 );
390+ if (object (p, target, 0.0 , lengths[ax], max_length))
391+ {
392+ return ; // only adding to one cell
393+ }
394+
395+ while (p != target)
396+ {
397+ p[ax] += step[ax];
398+ const double in_length = lengths[ax];
399+ lengths[ax] += length_delta[ax];
400+ ax = lengths[0 ] < lengths[1 ] && lengths[0 ] < lengths[2 ] ? 0 : (lengths[1 ] < lengths[2 ] ? 1 : 2 );
401+ if (object (p, target, in_length, lengths[ax], max_length))
402+ {
403+ break ; // only adding to one cell
404+ }
405+ }
406+ }
364407} // namespace ray
365408
366409#endif // RAYLIB_RAYUTILS_H
0 commit comments