1#ifndef TATOOINE_GEOMETRY_SPHERE_H
2#define TATOOINE_GEOMETRY_SPHERE_H
6#include <tatooine/real.h>
10#include <boost/range/adaptor/transformed.hpp>
11#include <boost/range/algorithm/copy.hpp>
15template <
floating_po
int Real,
size_t N>
41 if constexpr (N == 3) {
50 auto const discr = b * b - c;
59 auto t = -b - std::sqrt(discr);
66 auto const hit_pos = r(t);
72 throw std::runtime_error{
"sphere ray intersection not implemented for " +
73 std::to_string(N) +
" dimensions."};
84 template <
typename RandomEngine = std::mt19937_64>
86 std::random_device{}()})
const {
88 auto const u = rand();
89 auto const v = rand();
90 auto const theta = u * 2 * M_PI;
91 auto const phi = std::acos(2 * v - 1);
92 auto const r = std::cbrt(rand()) *
m_radius;
93 auto const sin_theta = std::sin(theta);
94 auto const cos_theta = std::cos(theta);
95 auto const sin_phi = std::sin(phi);
96 auto const cos_phi = std::cos(phi);
97 auto const x = r * sin_phi * cos_theta;
98 auto const y = r * sin_phi * sin_theta;
99 auto const z = r * cos_phi;
103 template <
typename RandReal,
typename RandEngine>
106 auto ps = std::vector<vec<Real, N>>{};
107 for (
size_t i = 0; i < n; ++i) {
108 auto const u = rand();
109 auto const v = rand();
110 auto const theta = u * 2 * M_PI;
111 auto const phi = std::acos(2 * v - 1);
112 auto const r = std::cbrt(rand()) *
m_radius / 2;
113 auto const sin_theta = std::sin(theta);
114 auto const cos_theta = std::cos(theta);
115 auto const sin_phi = std::sin(phi);
116 auto const cos_phi = std::cos(phi);
117 auto const x = r * sin_phi * cos_theta;
118 auto const y = r * sin_phi * sin_theta;
119 auto const z = r * cos_phi;
120 ps.emplace_back(x, y, z);
125 template <
typename RandEngine = std::mt19937_64>
132template <
floating_po
int Real0,
floating_po
int Real1,
size_t N>
135template <
floating_po
int Real0,
floating_po
int Real1,
size_t N>
139template <
floating_po
int Real>
141 using namespace std::ranges;
146 auto radian_to_cartesian = [&s](
auto const t) {
149 auto out_it = std::back_inserter(
ellipse);
150 copy(radial | views::transform(radian_to_cartesian), out_it);
155template <
floating_po
int Real>
158 using vertex_handle =
typename mesh_type::vertex_handle;
161 Real
const X = 0.525731112119133606;
162 Real
const Z = 0.850650808352039932;
164 std::vector{
vec{-X, 0, Z},
vec{X, 0, Z},
vec{-X, 0, -Z},
vec{X, 0, -Z},
165 vec{0, Z, X},
vec{0, Z, -X},
vec{0, -Z, X},
vec{0, -Z, -X},
166 vec{Z, X, 0},
vec{-Z, X, 0},
vec{Z, -X, 0},
vec{-Z, -X, 0}};
167 auto faces = std::vector<std::array<vertex_handle, 3>>{
168 {vertex_handle{0}, vertex_handle{4}, vertex_handle{1}},
169 {vertex_handle{0}, vertex_handle{9}, vertex_handle{4}},
170 {vertex_handle{9}, vertex_handle{5}, vertex_handle{4}},
171 {vertex_handle{4}, vertex_handle{5}, vertex_handle{8}},
172 {vertex_handle{4}, vertex_handle{8}, vertex_handle{1}},
173 {vertex_handle{8}, vertex_handle{10}, vertex_handle{1}},
174 {vertex_handle{8}, vertex_handle{3}, vertex_handle{10}},
175 {vertex_handle{5}, vertex_handle{3}, vertex_handle{8}},
176 {vertex_handle{5}, vertex_handle{2}, vertex_handle{3}},
177 {vertex_handle{2}, vertex_handle{7}, vertex_handle{3}},
178 {vertex_handle{7}, vertex_handle{10}, vertex_handle{3}},
179 {vertex_handle{7}, vertex_handle{6}, vertex_handle{10}},
180 {vertex_handle{7}, vertex_handle{11}, vertex_handle{6}},
181 {vertex_handle{11}, vertex_handle{0}, vertex_handle{6}},
182 {vertex_handle{0}, vertex_handle{1}, vertex_handle{6}},
183 {vertex_handle{6}, vertex_handle{1}, vertex_handle{10}},
184 {vertex_handle{9}, vertex_handle{0}, vertex_handle{11}},
185 {vertex_handle{9}, vertex_handle{11}, vertex_handle{2}},
186 {vertex_handle{9}, vertex_handle{2}, vertex_handle{5}},
187 {vertex_handle{7}, vertex_handle{2}, vertex_handle{11}}};
188 for (
size_t i = 0; i < num_subdivisions; ++i) {
189 std::vector<std::array<vertex_handle, 3>> subdivided_faces;
190 using edge_t = std::pair<vertex_handle, vertex_handle>;
192 std::map<edge_t, size_t>{};
193 for (
auto& [v0, v1, v2] : faces) {
194 auto edges = std::array{edge_t{v0, v1}, edge_t{v0, v2}, edge_t{v1, v2}};
196 std::array{vertex_handle{0}, vertex_handle{0}, vertex_handle{0}};
198 for (
auto& edge : edges) {
199 if (edge.first < edge.second) {
200 std::swap(edge.first, edge.second);
202 if (subdivided.find(edge) ==
end(subdivided)) {
209 nvs[i++] = subdivided[edge];
212 subdivided_faces.emplace_back(std::array{v0, nvs[1], nvs[0]});
213 subdivided_faces.emplace_back(std::array{nvs[0], nvs[2], v1});
214 subdivided_faces.emplace_back(std::array{nvs[1], v2, nvs[2]});
215 subdivided_faces.emplace_back(std::array{nvs[0], nvs[1], nvs[2]});
217 faces = subdivided_faces;
222 auto m = mesh_type{};
223 for (
auto& vertex_handle :
vertices) {
224 m.insert_vertex(std::move(vertex_handle) + s.
center());
226 for (
auto& f : faces) {
227 m.insert_simplex(f[0], f[1], f[2]);
232template <std::
size_t N>
240template <
typename Real>
242template <
typename Real>
244template <
typename Real>
246template <
typename Real>
hyper_ellipse< Real, 2 > ellipse
Definition: ellipse.h:14
auto discretize(hyper_ellipse< Real, NumDimensions > const &s, std::size_t const n=32)
Definition: hyper_ellipse.h:273
auto end(Range &&range)
Definition: iterator_facade.h:322
auto vertices(pointset< Real, NumDimensions > const &ps)
Definition: vertex_container.h:278
constexpr auto normalize(base_tensor< Tensor, T, N > const &t_in) -> vec< T, N >
Definition: tensor_operations.h:100
auto size(vec< ValueType, N > const &v)
Definition: vec.h:148
constexpr auto dot(base_tensor< Tensor0, T0, N > const &lhs, base_tensor< Tensor1, T1, N > const &rhs)
Definition: tensor_operations.h:120
Definition: hyper_ellipse.h:12
auto random_points(size_t const n, random::uniform< RandReal, RandEngine > &rand) const
Definition: sphere.h:104
vec_t m_center
Definition: sphere.h:24
sphere(vec_t const ¢er, Real const radius)
Definition: sphere.h:31
constexpr auto radius() -> auto &
Definition: sphere.h:82
sphere(sphere &&)=default
auto random_point(RandomEngine &&eng=RandomEngine{ std::random_device{}()}) const
Definition: sphere.h:85
auto random_points(size_t const n) const
Definition: sphere.h:126
auto check_intersection(ray< Real, N > const &r, Real const min_t=0) const -> optional_intersection_type override
Definition: sphere.h:39
constexpr auto center() const -> auto const &
Definition: sphere.h:78
sphere(sphere const &)=default
sphere(Real const radius, vec_t const ¢er)
Definition: sphere.h:29
sphere & operator=(sphere const &)=default
constexpr auto radius() const
Definition: sphere.h:81
Real m_radius
Definition: sphere.h:25
sphere & operator=(sphere &&)=default
constexpr auto center() -> auto &
Definition: sphere.h:79
sphere(Real const radius=1)
Definition: sphere.h:28
Definition: intersection.h:13
Definition: linspace.h:26
constexpr auto pop_back()
Definition: linspace.h:107
Definition: ray_intersectable.h:10
std::optional< intersection_type > optional_intersection_type
Definition: ray_intersectable.h:14
intersection< real_type, NumDimensions > intersection_type
Definition: ray_intersectable.h:13
auto direction() -> auto &
Definition: ray.h:54
auto origin() -> auto &
Definition: ray.h:41
Definition: unstructured_triangular_grid.h:10
static auto constexpr zeros()
Definition: vec.h:26