Tatooine
hyper_ellipse.h
Go to the documentation of this file.
1#ifndef TATOOINE_GEOMETRY_HYPER_ELLIPSE_H
2#define TATOOINE_GEOMETRY_HYPER_ELLIPSE_H
3//==============================================================================
4#include <tatooine/line.h>
6#include <tatooine/tensor.h>
9//==============================================================================
10namespace tatooine::geometry {
11//==============================================================================
12template <floating_point Real, std::size_t NumDimensions> struct hyper_ellipse {
13 static_assert(NumDimensions > 1);
18 using real_type = Real;
19 static auto constexpr num_dimensions() { return NumDimensions; }
20 //----------------------------------------------------------------------------
21private:
22 //----------------------------------------------------------------------------
25 //----------------------------------------------------------------------------
26public:
27 //----------------------------------------------------------------------------
29 constexpr hyper_ellipse()
30 : m_center{vec_type::zeros()}, m_S{mat_type::eye()} {}
31 //----------------------------------------------------------------------------
32 constexpr hyper_ellipse(hyper_ellipse const &) = default;
33 constexpr hyper_ellipse(hyper_ellipse &&) noexcept = default;
34 //----------------------------------------------------------------------------
35 constexpr auto operator=(hyper_ellipse const &) -> hyper_ellipse & = default;
36 constexpr auto operator=(hyper_ellipse &&) noexcept
37 -> hyper_ellipse & = default;
38 //----------------------------------------------------------------------------
39 ~hyper_ellipse() = default;
40 //----------------------------------------------------------------------------
42 constexpr hyper_ellipse(Real const radius) : m_S{mat_type::eye() * radius} {}
43 //----------------------------------------------------------------------------
45 constexpr hyper_ellipse(Real const radius, vec_type const &center)
46 : m_center{center}, m_S{mat_type::eye() * radius} {}
47 //----------------------------------------------------------------------------
49 constexpr hyper_ellipse(vec_type const &center, Real const radius)
50 : m_center{center}, m_S{mat_type::eye() * radius} {}
51 //----------------------------------------------------------------------------
55 : m_center{center}, m_S{S} {}
56 //----------------------------------------------------------------------------
58 constexpr hyper_ellipse(vec_type const &center,
59 arithmetic auto const... radii)
60 requires(sizeof...(radii) > 0)
61 : m_center{center}, m_S{diag(vec{static_cast<Real>(radii)...})} {
62 static_assert(sizeof...(radii) == NumDimensions,
63 "Number of radii does not match number of dimensions.");
64 }
65 //----------------------------------------------------------------------------
67 constexpr hyper_ellipse(arithmetic auto const... radii)
68 requires(sizeof...(radii) > 1)
70 m_S(diag(vec{static_cast<Real>(radii)...})) {
71 static_assert(sizeof...(radii) == NumDimensions,
72 "Number of radii does not match number of dimensions.");
73 }
74 //----------------------------------------------------------------------------
76 constexpr hyper_ellipse(fixed_size_vec<NumDimensions> auto const &...points)
77 requires(sizeof...(points) == NumDimensions)
78 {
79 fit(points...);
80 }
81 //----------------------------------------------------------------------------
83 constexpr hyper_ellipse(
85 fit(H);
86 }
87 //============================================================================
88 auto S() const -> auto const & { return m_S; }
89 auto S() -> auto & { return m_S; }
90 //----------------------------------------------------------------------------
91 auto center() const -> auto const & { return m_center; }
92 auto center() -> auto & { return m_center; }
93 //----------------------------------------------------------------------------
94 auto center(std::size_t const i) const { return m_center(i); }
95 auto center(std::size_t const i) -> auto & { return m_center(i); }
96 //----------------------------------------------------------------------------
97 auto local_coordinate(pos_type const &x) const {
98 return *solve(S(), (x - center()));
99 }
100 //----------------------------------------------------------------------------
103 }
104 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
106 return distance(x, center());
107 }
108 //----------------------------------------------------------------------------
111 }
112 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
113 auto local_distance_to_center(pos_type const &x) const {
115 }
116 //----------------------------------------------------------------------------
118 constexpr auto distance_to_boundary(pos_type const &x) const {
119 auto const x_local = local_coordinate(x);
120 auto const local_distance_to_point = euclidian_length(x_local);
121 auto const local_point_on_boundary = x_local / local_distance_to_point;
122 auto const local_offset_to_boundary = x_local - local_point_on_boundary;
123 return euclidian_length(m_S * local_offset_to_boundary);
124 }
125 //----------------------------------------------------------------------------
127 auto const local_point_on_boundary = normalize(local_coordinate(x));
128 return local_point_on_boundary;
129 }
130 //----------------------------------------------------------------------------
131 auto nearest_point_boundary(pos_type const &x) const {
132 return S() * local_nearest_point_boundary(x) + center();
133 }
134 //============================================================================
135private:
136 //----------------------------------------------------------------------------
138 template <std::size_t... Is>
139 constexpr auto fit(std::index_sequence<Is...> /*seq*/,
140 fixed_size_vec<NumDimensions> auto const &...points) {
141 auto H = mat_type{};
142 ([&] { H.col(Is) = points; }(), ...);
143 fit(H);
144 }
145 //----------------------------------------------------------------------------
146public:
147 //----------------------------------------------------------------------------
149 constexpr auto fit(fixed_size_vec<NumDimensions> auto const &...points) {
150 static_assert(sizeof...(points) == NumDimensions,
151 "Number of points does not match number of dimensions.");
152 fit(std::make_index_sequence<NumDimensions>{}, points...);
153 }
154 //----------------------------------------------------------------------------
157 constexpr auto fit(fixed_size_quadratic_mat<NumDimensions> auto const &H) {
158 auto const HHt = H * transposed(H);
159 auto const [Q, Sig] = eigenvectors_sym(HHt);
160 m_S = Q * sqrt(diag(Sig)) * transposed(Q);
161 }
162 //============================================================================
165 template <typename V, typename VReal>
168 return m_S * normalize(*solve(m_S, x - m_center)) + m_center;
169 }
170 //----------------------------------------------------------------------------
174 constexpr auto is_inside(pos_type const &x) const {
175 return squared_euclidean_length(*solve(m_S, x - m_center)) <= 1;
176 }
177 //----------------------------------------------------------------------------
178 auto discretize(std::size_t const num_vertices = 32) const
179 requires(NumDimensions == 2)
180 {
181 using namespace std::ranges;
182 auto radial = linspace<Real>{0.0, M_PI * 2, num_vertices + 1};
183 radial.pop_back();
184
185 auto discretization = line<Real, 2>{};
186 auto radian_to_cartesian = [](auto const t) {
187 return vec{std::cos(t), std::sin(t)};
188 };
189 auto out_it = std::back_inserter(discretization);
190 copy(radial | views::transform(radian_to_cartesian), out_it);
191 discretization.set_closed(true);
192 for (auto const v : discretization.vertices()) {
193 discretization[v] = S() * discretization[v] + center();
194 }
195 return discretization;
196 }
197 //----------------------------------------------------------------------------
198 auto discretize(std::size_t const num_subdivisions = 2) const
199 requires(NumDimensions == 3)
200 {
202 using vh = typename grid::vertex_handle;
203 using edge = std::pair<vh, vh>;
204 using cell = std::array<vh, 3>;
205 using cell_list = std::vector<cell>;
206 static constexpr auto X = Real(0.525731112119133606);
207 static constexpr auto Z = Real(0.850650808352039932);
208 auto g = grid{vec{-X, 0, Z}, vec{X, 0, Z}, vec{-X, 0, -Z}, vec{X, 0, -Z},
209 vec{0, Z, X}, vec{0, Z, -X}, vec{0, -Z, X}, vec{0, -Z, -X},
210 vec{Z, X, 0}, vec{-Z, X, 0}, vec{Z, -X, 0}, vec{-Z, -X, 0}};
211 auto triangles = cell_list{
212 {vh{0}, vh{4}, vh{1}}, {vh{0}, vh{9}, vh{4}}, {vh{9}, vh{5}, vh{4}},
213 {vh{4}, vh{5}, vh{8}}, {vh{4}, vh{8}, vh{1}}, {vh{8}, vh{10}, vh{1}},
214 {vh{8}, vh{3}, vh{10}}, {vh{5}, vh{3}, vh{8}}, {vh{5}, vh{2}, vh{3}},
215 {vh{2}, vh{7}, vh{3}}, {vh{7}, vh{10}, vh{3}}, {vh{7}, vh{6}, vh{10}},
216 {vh{7}, vh{11}, vh{6}}, {vh{11}, vh{0}, vh{6}}, {vh{0}, vh{1}, vh{6}},
217 {vh{6}, vh{1}, vh{10}}, {vh{9}, vh{0}, vh{11}}, {vh{9}, vh{11}, vh{2}},
218 {vh{9}, vh{2}, vh{5}}, {vh{7}, vh{2}, vh{11}}};
219
220 for (std::size_t i = 0; i < num_subdivisions; ++i) {
221 auto subdivided_cells = cell_list{};
222 auto subdivided = std::map<edge, std::size_t>{}; // vh index on edge
223 for (auto &[v0, v1, v2] : triangles) {
224 auto edges = std::array{edge{v0, v1}, edge{v0, v2}, edge{v1, v2}};
225 auto nvs = cell{vh{0}, vh{0}, vh{0}};
226 auto i = std::size_t{};
227 for (auto &edge : edges) {
228 auto &[v0, v1] = edge;
229 if (v0 < v1) {
230 std::swap(v0, v1);
231 }
232 if (subdivided.find(edge) == end(subdivided)) {
233 subdivided[edge] = vertices(g).size();
234 nvs[i++] = g.insert_vertex(normalize((g[v0] + g[v1]) * 0.5));
235 } else {
236 nvs[i++] = vh{subdivided[edge]};
237 }
238 }
239 subdivided_cells.emplace_back(cell{v0, nvs[1], nvs[0]});
240 subdivided_cells.emplace_back(cell{nvs[0], nvs[2], v1});
241 subdivided_cells.emplace_back(cell{nvs[1], v2, nvs[2]});
242 subdivided_cells.emplace_back(cell{nvs[0], nvs[1], nvs[2]});
243 }
244 triangles = subdivided_cells;
245 }
246 for (auto v : g.vertices()) {
247 g[v] = S() * g[v] + center();
248 }
249 for (auto const &c : triangles) {
250 g.insert_triangle(c[0], c[1], c[2]);
251 }
252 return g;
253 }
254 //----------------------------------------------------------------------------
255public:
256 //----------------------------------------------------------------------------
259 auto main_axes() const { return eigenvectors_sym(S()); }
260 //----------------------------------------------------------------------------
262 auto radii() const { return eigenvalues_sym(S()); }
263 //----------------------------------------------------------------------------
266 auto const [axes, lengths] = main_axes();
267 return axes * diag(lengths);
268 }
269};
270//------------------------------------------------------------------------------
271template <typename Real, std::size_t NumDimensions>
272 requires(NumDimensions == 2 || NumDimensions == 3)
274 std::size_t const n = 32) {
275 return s.discretize(n);
276}
277template <std::size_t NumDimensions>
279//==============================================================================
280} // namespace tatooine::geometry
281//==============================================================================
282namespace tatooine {
283namespace detail::geometry::hyper_ellipse {
284//==============================================================================
285template <floating_point Real, std::size_t NumDimensions>
287//==============================================================================
288template <floating_point Real, std::size_t NumDimensions>
290 -> std::true_type;
291auto ptr_convertible(void const volatile *) -> std::false_type;
292//------------------------------------------------------------------------------
293template <typename> auto is_derived(...) -> std::true_type;
294//------------------------------------------------------------------------------
295template <typename D>
296auto is_derived(int) -> decltype(ptr_convertible(static_cast<D *>(nullptr)));
297//------------------------------------------------------------------------------
298template <typename T>
300 : std::integral_constant<bool, std::is_class_v<T> &&decltype(is_derived<T>(
301 0))::value> {};
302//==============================================================================
303} // namespace detail::geometry::hyper_ellipse
304//==============================================================================
305template <typename T>
306static auto constexpr is_derived_from_hyper_ellipse =
308static_assert(is_derived_from_hyper_ellipse<geometry::HyperEllipse<2>>);
309//==============================================================================
310} // namespace tatooine
311//==============================================================================
312namespace tatooine::reflection {
313//==============================================================================
314// template <typename Real, std::size_t NumDimensions>
315// TATOOINE_MAKE_TEMPLATED_ADT_REFLECTABLE(
316// (geometry::hyper_ellipse<Real, NumDimensions>),
317// TATOOINE_REFLECTION_INSERT_METHOD(center, center()),
318// TATOOINE_REFLECTION_INSERT_METHOD(S, S()))
319//==============================================================================
320} // namespace tatooine::reflection
321//==============================================================================
324//==============================================================================
325namespace tatooine {
326//==============================================================================
327template <range Ellipsoids>
329 std::ranges::range_value_t<Ellipsoids>>) &&
330 (std::ranges::range_value_t<Ellipsoids>::num_dimensions() == 2)
331auto write_vtp(Ellipsoids const &ellipsoids, filesystem::path const &path) {
332 using namespace std::ranges;
333 using ellipsoid_t = std::ranges::range_value_t<Ellipsoids>;
334 using real_t = typename ellipsoid_t::real_type;
335 auto file = std::ofstream{path, std::ios::binary};
336 if (!file.is_open()) {
337 throw std::runtime_error{"Could not write " + path.string()};
338 }
339 auto appended_data_offset = std::size_t{};
340 using header_type = std::uint64_t;
341 using connectivity_int = std::int32_t;
342 using offset_int = connectivity_int;
343 file << "<VTKFile"
344 << " type=\"PolyData\""
345 << " version=\"1.0\" "
346 "byte_order=\"LittleEndian\""
347 << " header_type=\"" << vtk::xml::to_data_type<header_type>() << "\">";
348 file << "<PolyData>\n";
349 auto discretized_unit_circle =
351 discretized_unit_circle.set_closed(true);
352 auto transformed_circle = discretized_unit_circle;
353 auto const num_points = discretized_unit_circle.vertices().size();
354 auto const num_lines = discretized_unit_circle.num_line_segments();
355
356 auto offsets = std::vector<offset_int>(num_lines, 2);
357 //offsets.front() = 0;
358 for (std::size_t i = 1; i < size(offsets); ++i) {
359 offsets[i] += offsets[i - 1];
360 }
361
362 auto connectivity_data = std::vector<connectivity_int>{};
363 connectivity_data.reserve(num_lines * 2);
364 for (connectivity_int i = 0; i < static_cast<connectivity_int>(
365 discretized_unit_circle.num_vertices()) -
366 1;
367 ++i) {
368 connectivity_data.push_back(i);
369 connectivity_data.push_back(i + 1);
370 }
371 if (discretized_unit_circle.is_closed()) {
372 connectivity_data.push_back(static_cast<connectivity_int>(
373 discretized_unit_circle.num_vertices() - 1));
374 connectivity_data.push_back(0);
375 }
376
377 auto const num_bytes_points = header_type(3 * num_points * sizeof(real_t));
378 auto const num_bytes_connectivity =
379 header_type(num_lines * 2 * sizeof(connectivity_int));
380 auto const num_bytes_offsets =
381 header_type(offsets.size() * sizeof(offset_int));
382 for (std::size_t i = 0; i < size(ellipsoids); ++i) {
383 file << "<Piece"
384 << " NumberOfPoints=\"" << num_points << "\""
385 << " NumberOfLines=\"" << num_lines << "\""
386 << ">\n";
387
388 auto const points_base =
389 num_bytes_offsets + num_bytes_connectivity + sizeof(header_type) * 2;
390 // Points
391 file << "<Points>\n";
392 file << "<DataArray"
393 << " format=\"appended\""
394 << " offset=\"" << points_base + appended_data_offset << "\""
395 << " type=\"" << vtk::xml::to_data_type<real_t>()
396 << "\" NumberOfComponents=\"" << 3 << "\"/>\n";
397 appended_data_offset += num_bytes_points + sizeof(header_type);
398 file << "</Points>\n";
399
400 // Lines
401 file << "<Lines>\n";
402 // Lines - connectivity
403 file << "<DataArray format=\"appended\" offset=\"0\" type =\""
404 << vtk::xml::to_data_type<connectivity_int>()
405 << "\" Name=\"connectivity\"/>\n";
406
407 // Lines - offsets
408 file << "<DataArray format=\"appended\" offset=\""
409 << num_bytes_connectivity + sizeof(header_type) << "\" type =\""
410 << vtk::xml::to_data_type<offset_int>() << "\" Name =\"offsets\"/>\n";
411 file << "</Lines>\n";
412 file << "</Piece>\n";
413 }
414 file << "</PolyData>\n";
415 file << "<AppendedData encoding=\"raw\">_";
416
417 // Writing lines connectivity data to appended data section
418 file.write(reinterpret_cast<char const *>(&num_bytes_connectivity),
419 sizeof(header_type));
420 file.write(reinterpret_cast<char const *>(connectivity_data.data()),
421 num_bytes_connectivity);
422
423 // Writing lines offsets to appended data section
424 file.write(reinterpret_cast<char const *>(&num_bytes_offsets),
425 sizeof(header_type));
426 file.write(reinterpret_cast<char const *>(offsets.data()), num_bytes_offsets);
427
428 // Writing vertex data to appended data section
429 for (auto const &ellipsoid : ellipsoids) {
430 for (auto v : discretized_unit_circle.vertices()) {
431 transformed_circle[v] =
432 ellipsoid.center() + ellipsoid.S() * discretized_unit_circle[v];
433 }
434
435 // Writing points
436 file.write(reinterpret_cast<char const *>(&num_bytes_points),
437 sizeof(header_type));
438 auto zero = real_t{};
439 for (auto const v : transformed_circle.vertices()) {
440 file.write(
441 reinterpret_cast<char const *>(transformed_circle.at(v).data()),
442 sizeof(real_t) * 2);
443 file.write(reinterpret_cast<char const *>(&zero), sizeof(real_t));
444 }
445 }
446 file << "</AppendedData>";
447 file << "</VTKFile>";
448}
449//==============================================================================
450template <range Ellipsoids>
452 std::ranges::range_value_t<Ellipsoids>>) &&
453 (std::ranges::range_value_t<Ellipsoids>::num_dimensions() == 3)
454auto write_vtp(Ellipsoids const &ellipsoids, filesystem::path const &path) {
455 using namespace std::ranges;
456 using ellipsoid_t = std::ranges::range_value_t<Ellipsoids>;
457 using real_t = typename ellipsoid_t::real_type;
458 auto file = std::ofstream{path, std::ios::binary};
459 if (!file.is_open()) {
460 throw std::runtime_error{"Could not write " + path.string()};
461 }
462 auto offset = std::size_t{};
463 using header_type = std::uint64_t;
464 using connectivity_int = std::int32_t;
465 using offset_int = connectivity_int;
466 file << "<VTKFile"
467 << " type=\"PolyData\""
468 << " version=\"1.0\" "
469 "byte_order=\"LittleEndian\""
470 << " header_type=\"" << vtk::xml::to_data_type<header_type>() << "\">";
471 file << "<PolyData>\n";
472 auto const discretized_unit_sphere =
474 auto transformed_ellipse = discretized_unit_sphere;
475 auto const num_points = discretized_unit_sphere.vertices().size();
476 auto const num_polys = discretized_unit_sphere.triangles().size();
477
478 auto offsets = std::vector<offset_int>(num_polys, 3);
479 //offsets.front() = 0;
480 for (std::size_t i = 1; i < size(offsets); ++i) {
481 offsets[i] += offsets[i - 1];
482 };
483
484 auto index = [](auto const handle) -> connectivity_int {
485 return handle.index();
486 };
487 auto connectivity_data = std::vector<connectivity_int>(num_polys * 3);
488 copy(discretized_unit_sphere.simplices().data_container() |
489 views::transform(index),
490 begin(connectivity_data));
491
492 auto const num_bytes_connectivity = num_polys * 3 * sizeof(connectivity_int);
493 auto const num_bytes_offsets = sizeof(offset_int) * offsets.size();
494 for (std::size_t i = 0; i < size(ellipsoids); ++i) {
495 file << "<Piece"
496 << " NumberOfPoints=\"" << num_points << "\""
497 << " NumberOfPolys=\"" << num_polys << "\""
498 << " NumberOfVerts=\"0\""
499 << " NumberOfLines=\"0\""
500 << " NumberOfStrips=\"0\""
501 << ">\n";
502
503 // Points
504 file << "<Points>";
505 file << "<DataArray"
506 << " format=\"appended\""
507 << " offset=\"" << offset << "\""
508 << " type=\"" << vtk::xml::to_data_type<real_t>()
509 << "\" NumberOfComponents=\"" << 3 << "\"/>";
510 auto const num_bytes_points = header_type(sizeof(real_t) * 3 * num_points);
511 offset += num_bytes_points + sizeof(header_type);
512 file << "</Points>\n";
513
514 // Polys
515 file << "<Polys>\n";
516 // Polys - connectivity
517 file << "<DataArray format=\"appended\" offset=\"" << offset << "\" type=\""
518 << vtk::xml::to_data_type<connectivity_int>()
519 << "\" Name=\"connectivity\"/>\n";
520 offset += num_bytes_connectivity + sizeof(header_type);
521 // Polys - offsets
522 file << "<DataArray format=\"appended\" offset=\"" << offset << "\" type=\""
523 << vtk::xml::to_data_type<offset_int>() << "\" Name=\"offsets\"/>\n";
524 offset += num_bytes_offsets + sizeof(header_type);
525 file << "</Polys>\n";
526 file << "</Piece>\n";
527 }
528 file << "</PolyData>\n";
529 file << "<AppendedData encoding=\"raw\">_";
530 // Writing vertex data to appended data section
531 for (auto const &ellipsoid : ellipsoids) {
532 for (auto v : discretized_unit_sphere.vertices()) {
533 transformed_ellipse[v] =
534 ellipsoid.center() + ellipsoid.S() * discretized_unit_sphere[v];
535 }
536 auto const num_bytes_points = header_type(sizeof(real_t) * 3 * num_points);
537
538 // Writing points
539 file.write(reinterpret_cast<char const *>(&num_bytes_points),
540 sizeof(header_type));
541 for (auto const v : transformed_ellipse.vertices()) {
542 file.write(
543 reinterpret_cast<char const *>(transformed_ellipse.at(v).data()),
544 sizeof(real_t) * 3);
545 }
546
547 // Writing polys connectivity data to appended data section
548 file.write(reinterpret_cast<char const *>(&num_bytes_connectivity),
549 sizeof(header_type));
550 file.write(reinterpret_cast<char const *>(connectivity_data.data()),
551 num_bytes_connectivity);
552
553 // Writing polys offsets to appended data section
554 file.write(reinterpret_cast<char const *>(&num_bytes_offsets),
555 sizeof(header_type));
556 file.write(reinterpret_cast<char const *>(offsets.data()),
557 num_bytes_offsets);
558 }
559 file << "</AppendedData>";
560 file << "</VTKFile>";
561}
562//==============================================================================
563} // namespace tatooine
564//==============================================================================
565#endif
Definition: grid_edge.h:16
Definition: concepts.h:33
Definition: tensor_concepts.h:88
Definition: tensor_concepts.h:33
auto is_derived(...) -> std::true_type
auto ptr_convertible(he_t< Real, NumDimensions > const volatile *) -> std::true_type
Definition: ellipse.h:11
auto discretize(hyper_ellipse< Real, NumDimensions > const &s, std::size_t const n=32)
Definition: hyper_ellipse.h:273
Definition: linspace.h:172
Definition: algorithm.h:6
constexpr auto distance(Iter const &it0, Iter const &it1)
Definition: iterator_facade.h:372
constexpr auto squared_euclidean_length(base_tensor< Tensor, T, N > const &t_in)
Definition: length.h:7
auto begin(Range &&range)
Definition: iterator_facade.h:318
auto end(Range &&range)
Definition: iterator_facade.h:322
auto discretize(polymorphic::field< VReal, NumDimensions, Tensor > const &f, rectilinear_grid< SpatialDimensions... > const &discretized_domain, arithmetic auto const t, execution_policy_tag auto const pol) -> auto
Definition: discretize_field.h:92
auto vertices(pointset< Real, NumDimensions > const &ps)
Definition: vertex_container.h:278
auto eigenvectors_sym(Mat &&A)
Definition: eigenvalues.h:44
auto solve(polynomial< Real, 1 > const &p) -> std::vector< Real >
solve a + b*x
Definition: polynomial.h:187
auto constexpr index(handle< Child, Int > const h)
Definition: handle.h:119
auto write_vtp(Lines const &lines, filesystem::path const &path) -> void
Definition: write.h:38
constexpr auto euclidean_length(base_tensor< Tensor, T, N > const &t_in) -> T
Definition: length.h:12
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
auto transposed(dynamic_tensor auto &&t)
Definition: transposed_tensor.h:170
constexpr auto squared_euclidean_distance(base_tensor< Tensor0, T0, N > const &lhs, base_tensor< Tensor1, T1, N > const &rhs)
Definition: distance.h:11
constexpr auto eigenvalues_sym(Mat &&A)
Definition: eigenvalues.h:55
constexpr auto sqrt(arithmetic auto const x)
Definition: math.h:29
static auto constexpr is_derived_from_hyper_ellipse
Definition: hyper_ellipse.h:306
auto Q(V &&v)
Definition: Q_field.h:57
Definition: base_tensor.h:23
Definition: hyper_ellipse.h:12
auto euclidean_distance_to_center(pos_type const &x) const
Definition: hyper_ellipse.h:105
auto center() const -> auto const &
Definition: hyper_ellipse.h:91
auto squared_local_euclidean_distance_to_center(pos_type const &x) const
Definition: hyper_ellipse.h:109
vec_type m_center
Definition: hyper_ellipse.h:23
auto discretize(std::size_t const num_subdivisions=2) const
Definition: hyper_ellipse.h:198
constexpr hyper_ellipse(fixed_size_vec< NumDimensions > auto const &center, fixed_size_quadratic_mat< NumDimensions > auto const &S)
Sets up a sphere with specified radius and origin point.
Definition: hyper_ellipse.h:53
constexpr hyper_ellipse(arithmetic auto const ... radii)
Sets up a sphere with specified radii.
Definition: hyper_ellipse.h:67
auto center(std::size_t const i) -> auto &
Definition: hyper_ellipse.h:95
constexpr hyper_ellipse(fixed_size_quadratic_mat< NumDimensions > auto const &H)
Fits an ellipse through specified points.
Definition: hyper_ellipse.h:83
mat_type m_S
Definition: hyper_ellipse.h:24
hyper_ellipse< Real, NumDimensions > this_type
Definition: hyper_ellipse.h:14
constexpr auto is_inside(pos_type const &x) const
Definition: hyper_ellipse.h:174
constexpr hyper_ellipse()
defaults to unit hypersphere
Definition: hyper_ellipse.h:29
constexpr hyper_ellipse(vec_type const &center, Real const radius)
Sets up a sphere with specified radius and origin point.
Definition: hyper_ellipse.h:49
constexpr auto fit(fixed_size_quadratic_mat< NumDimensions > auto const &H)
Definition: hyper_ellipse.h:157
auto S() -> auto &
Definition: hyper_ellipse.h:89
constexpr hyper_ellipse(hyper_ellipse &&) noexcept=default
vec< Real, NumDimensions > vec_type
Definition: hyper_ellipse.h:15
constexpr auto fit(fixed_size_vec< NumDimensions > auto const &...points)
Fits an ellipse through specified points.
Definition: hyper_ellipse.h:149
constexpr hyper_ellipse(Real const radius, vec_type const &center)
Sets up a sphere with specified radius and origin point.
Definition: hyper_ellipse.h:45
auto squared_euclidean_distance_to_center(pos_type const &x) const
Definition: hyper_ellipse.h:101
Real real_type
Definition: hyper_ellipse.h:18
constexpr hyper_ellipse(vec_type const &center, arithmetic auto const ... radii)
Sets up a sphere with specified radii.
Definition: hyper_ellipse.h:58
auto local_coordinate(pos_type const &x) const
Definition: hyper_ellipse.h:97
auto radii() const
Returns a the radii of the hyper ellipse as a vector.
Definition: hyper_ellipse.h:262
auto nearest_point_boundary(pos_type const &x) const
Definition: hyper_ellipse.h:131
auto discretize(std::size_t const num_vertices=32) const
Definition: hyper_ellipse.h:178
auto local_distance_to_center(pos_type const &x) const
Definition: hyper_ellipse.h:113
static auto constexpr num_dimensions()
Definition: hyper_ellipse.h:19
auto center(std::size_t const i) const
Definition: hyper_ellipse.h:94
constexpr hyper_ellipse(fixed_size_vec< NumDimensions > auto const &...points)
Fits an ellipse through specified points.
Definition: hyper_ellipse.h:76
constexpr auto distance_to_boundary(pos_type const &x) const
Computes euclidean distance to nearest boundary point.
Definition: hyper_ellipse.h:118
constexpr hyper_ellipse(hyper_ellipse const &)=default
auto center() -> auto &
Definition: hyper_ellipse.h:92
constexpr auto nearest_point_on_boundary(base_tensor< V, VReal, NumDimensions > const &x) const
Definition: hyper_ellipse.h:166
auto main_axes() const
Definition: hyper_ellipse.h:259
auto local_nearest_point_boundary(pos_type const &x) const
Definition: hyper_ellipse.h:126
auto S() const -> auto const &
Definition: hyper_ellipse.h:88
auto base_coordinate_system() const
Returns a the radii of the hyper ellipse as a vector.
Definition: hyper_ellipse.h:265
constexpr auto fit(std::index_sequence< Is... >, fixed_size_vec< NumDimensions > auto const &...points)
Fits an ellipse through specified points.
Definition: hyper_ellipse.h:139
Definition: handle.h:14
auto index() const
Definition: handle.h:64
Definition: line.h:35
Definition: linspace.h:26
constexpr auto pop_back()
Definition: linspace.h:107
static auto constexpr eye()
Definition: mat.h:46
Definition: unstructured_triangular_grid.h:10
static auto constexpr zeros()
Definition: vec.h:26