diff options
author | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-06-20 14:33:09 +1000 |
---|---|---|
committer | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-06-20 14:33:09 +1000 |
commit | 6352e8e3196f78388b6c771073f9e03eaa612673 (patch) | |
tree | e23772f79a7fbc41bc9108951e9e136857484bf4 /source/base/StarBlocksAlongLine.hpp | |
parent | 6741a057e5639280d85d0f88ba26f000baa58f61 (diff) |
everything everywhere
all at once
Diffstat (limited to 'source/base/StarBlocksAlongLine.hpp')
-rw-r--r-- | source/base/StarBlocksAlongLine.hpp | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/source/base/StarBlocksAlongLine.hpp b/source/base/StarBlocksAlongLine.hpp new file mode 100644 index 0000000..bdd3c9a --- /dev/null +++ b/source/base/StarBlocksAlongLine.hpp @@ -0,0 +1,108 @@ +#ifndef STAR_BLOCKS_ALONG_LINE_HPP +#define STAR_BLOCKS_ALONG_LINE_HPP + +#include "StarVector.hpp" + +namespace Star { + +// Iterate over integral cells based on Bresenham's line drawing algorithm. +// Returns false immediately when the callback returns false for any cell, +// returns true after iterating through every cell otherwise. +template <typename Scalar> +bool forBlocksAlongLine(Vector<Scalar, 2> origin, Vector<Scalar, 2> const& dxdy, function<bool(int, int)> callback) { + Vector<Scalar, 2> remote = origin + dxdy; + + double dx = dxdy[0]; + if (dx < 0) + dx *= -1; + + double dy = dxdy[1]; + if (dy < 0) + dy *= -1; + + double oxfloor = floor(origin[0]); + double oyfloor = floor(origin[1]); + double rxfloor = floor(remote[0]); + double ryfloor = floor(remote[1]); + + if (dx == 0) { + if (oyfloor < ryfloor) { + for (int i = oyfloor; i <= ryfloor; ++i) { + if (!callback(oxfloor, i)) + return false; + } + } else { + for (int i = oyfloor; i >= ryfloor; --i) { + if (!callback(oxfloor, i)) + return false; + } + } + return true; + + } else if (dy == 0) { + if (oxfloor < rxfloor) { + for (int i = oxfloor; i <= rxfloor; ++i) { + if (!callback(i, oyfloor)) + return false; + } + } else { + for (int i = oxfloor; i >= rxfloor; --i) { + if (!callback(i, oyfloor)) + return false; + } + } + return true; + + } else { + int x = oxfloor; + int y = oyfloor; + + int n = 1; + int x_inc, y_inc; + double error; + + if (dxdy[0] > 0) { + x_inc = 1; + n += int(rxfloor) - x; + error = (oxfloor + 1 - origin[0]) * dy; + } else { + x_inc = -1; + n += x - int(rxfloor); + error = (origin[0] - oxfloor) * dy; + } + + if (dxdy[1] > 0) { + y_inc = 1; + n += int(ryfloor) - y; + error -= (oyfloor + 1 - origin[1]) * dx; + } else { + y_inc = -1; + n += y - int(ryfloor); + error -= (origin[1] - oyfloor) * dx; + } + + for (; n > 0; --n) { + if (!callback(x, y)) + return false; + + if (error > 0) { + y += y_inc; + error -= dx; + } else if (error < 0) { + x += x_inc; + error += dy; + } else { + --n; + y += y_inc; + x += x_inc; + error += dy; + error -= dx; + } + } + return true; + } +} + +} + +#endif |