1#ifndef TATOOINE_RENDERING_RENDER_LINE_H
2#define TATOOINE_RENDERING_RENDER_LINE_H
10template <
typename Real>
15 auto const& ax_x =
grid.template dimension<0>();
17 nn_ax_x.front() -= ax_x.spacing() / 2;
18 nn_ax_x.back() -= ax_x.spacing() / 2;
20 auto const& ax_y =
grid.template dimension<1>();
22 nn_ax_y.front() -= ax_y.spacing() / 2;
23 nn_ax_y.back() -= ax_y.spacing() / 2;
26 if ((p0.
x() < nn_ax_x.front() && p1.
x() < nn_ax_x.front()) ||
27 (p0.
x() > nn_ax_x.back() && p1.
x() > nn_ax_x.back()) ||
28 (p0.
y() < nn_ax_y.front() && p1.
y() < nn_ax_y.front()) ||
29 (p0.
y() > nn_ax_y.back() && p1.
y() > nn_ax_y.back())) {
33 auto get_t = [](
auto const a,
auto const b,
auto const c) {
34 return (c - a) / (b - a);
37 if (p0.
x() < nn_ax_x.front()) {
38 auto const t = get_t(p0.
x(), p1.
x(), nn_ax_x.front());
39 p0 =
vec{nn_ax_x.front(), p0.
y() * (1 - t) + p1.
y() * t};
40 }
else if (p0.
x() > nn_ax_x.back()) {
41 auto const t = get_t(p0.
x(), p1.
x(), nn_ax_x.back());
42 p0 =
vec{nn_ax_x.back(), p0.
y() * (1 - t) + p1.
y() * t};
45 if (p1.
x() <= nn_ax_x.front()) {
46 auto const t = get_t(p0.
x(), p1.
x(), nn_ax_x.front());
47 p1 =
vec{nn_ax_x.front(), p0.
y() * (1 - t) + p1.
y() * t};
48 }
else if (p1.
x() > nn_ax_x.back()) {
49 auto const t = get_t(p0.
x(), p1.
x(), nn_ax_x.back());
50 p1 =
vec{nn_ax_x.back(), p0.
y() * (1 - t) + p1.
y() * t};
53 if (p0.
y() < nn_ax_y.front()) {
54 auto const t = get_t(p0.
y(), p1.
y(), nn_ax_y.front());
55 p0 =
vec{p0.
x() * (1 - t) + p1.
x() * t, nn_ax_y.front()};
56 }
else if (p0.
y() > nn_ax_y.back()) {
57 auto const t = get_t(p0.
y(), p1.
y(), nn_ax_y.back());
58 p0 =
vec{p0.
x() * (1 - t) + p1.
x() * t, nn_ax_y.back()};
61 if (p1.
y() < nn_ax_y.front()) {
62 auto const t = get_t(p0.
y(), p1.
y(), nn_ax_y.front());
63 p1 =
vec{p0.
x() * (1 - t) + p1.
x() * t, nn_ax_y.front()};
64 }
else if (p1.
y() > nn_ax_y.back()) {
65 auto const t = get_t(p0.
y(), p1.
y(), nn_ax_y.back());
66 p1 =
vec{p0.
x() * (1 - t) + p1.
x() * t, nn_ax_y.back()};
71 for (std::size_t i = 0; i <
size(nn_ax_x) - 1; ++i) {
72 if (nn_ax_x[i] <= p0.
x() && p0.
x() <= nn_ax_x[i + 1]) {
78 for (std::size_t i = 0; i <
size(nn_ax_x) - 1; ++i) {
79 if (nn_ax_x[i] <= p1.
x() && p1.
x() <= nn_ax_x[i + 1]) {
85 for (std::size_t i = 0; i <
size(nn_ax_y) - 1; ++i) {
86 if (nn_ax_y[i] <= p0.
y() && p0.
y() <= nn_ax_y[i + 1]) {
92 for (std::size_t i = 0; i <
size(nn_ax_y) - 1; ++i) {
93 if (nn_ax_y[i] <= p1.
y() && p1.
y() <= nn_ax_y[i + 1]) {
99 vec{std::max(ip0.x(), ip1.x()) - std::min(ip0.x(), ip1.x()),
100 std::max(ip0.y(), ip1.y()) - std::min(ip0.y(), ip1.y())};
102 auto dx = std::abs((
long long)(ip1.x()) - (
long long)(ip0.x()));
103 auto sx = ip0.x() < ip1.x() ? 1 : -1;
104 auto dy = -std::abs((
long long)(ip1.y()) - (
long long)(ip0.y()));
105 auto sy = ip0.y() < ip1.y() ? 1 : -1;
107 auto e2 = (
long long)(0);
108 auto c = [&](
auto const t,
auto const ix,
auto const iy) {
109 if (line_width == 1) {
112 auto const half_line_width = line_width / 2;
113 auto const m = 1 - line_width % 2;
114 if (dist.x() < dist.y()) {
115 for (
int i = -half_line_width + m; i <= half_line_width; ++i) {
116 if (ix >= std::abs(i) &&
117 std::size_t(ix + i) <
grid.template size<0>() - 1) {
118 callback(t, ix + i, iy);
122 for (
int i = -half_line_width + m; i <= half_line_width; ++i) {
123 if (iy >= std::abs(i) &&
124 std::size_t(iy + i) <
grid.template size<1>() - 1) {
125 callback(t, ix, iy + i);
132 auto const t_offset = Real(1) / (std::max(dist.x(), dist.y()) - 1);
133 auto i = std::size_t(0);
134 while (ip0.x() != ip1.x() || ip0.y() != ip1.y()) {
135 c(i++ * t_offset, ip0.x(), ip0.y());
146 c(i++ * t_offset, ip1.x(), ip1.y());
149template <
typename Real, invocable<Real, std::
size_t, std::
size_t> Callback>
152 render(p0, p1, 1,
grid, std::forward<Callback>(callback));
155template <
typename Real, invocable<Real, std::
size_t, std::
size_t> Callback>
158 Callback&& callback) {
159 render(cam.project(p0).xy(), cam.project(p1).xy(), line_width,
grid,
160 std::forward<Callback>(callback));
Definition: grid_edge.h:16
Definition: concepts.h:121
auto render(AABB3< Real > const &aabb, int const line_width, UniformRectilinearGrid2< Real > const &grid, camera auto const &cam, invocable< Real, typename AABB3< Real >::pos_type, typename AABB3< Real >::pos_type, std::size_t, std::size_t > auto &&callback)
Definition: render_axis_aligned_bounding_box.h:11
uniform_rectilinear_grid< Real, 2 > UniformRectilinearGrid2
Definition: rectilinear_grid.h:1912
detail::rectilinear_grid::creator_t< linspace< Real >, N > uniform_rectilinear_grid
Definition: rectilinear_grid.h:1904
auto size(vec< ValueType, N > const &v)
Definition: vec.h:148
auto constexpr x() const -> auto const &requires(N >=1)
Definition: vec.h:102
auto constexpr y() const -> auto const &requires(N >=2)
Definition: vec.h:106