1#ifndef TATOOINE_DETAIL_AUTONOMOUS_PARTICLE_POST_TRIANGULATION_H
2#define TATOOINE_DETAIL_AUTONOMOUS_PARTICLE_POST_TRIANGULATION_H
8#include <unordered_map>
12template <
typename Real, std::
size_t NumDimensions>
20template <
typename Real, std::
size_t NumDimensions>
26 std::uint64_t
id = std::numeric_limits<std::uint64_t>::max();
28 std::vector<hierarchy>
leafs = {};
38 hierarchy(std::uint64_t
const id_, std::vector<hierarchy_pair>
const& hps,
39 std::unordered_map<std::uint64_t, vertex_type>
const& centers,
42 build(hps, centers, edges);
51 std::unordered_map<std::uint64_t, vertex_type>
const& centers,
53 for (
auto const& hp : hps) {
55 if (hp.id == hp.parent) {
56 leafs.emplace_back(hp.parent, hps, centers, edges);
62 return id == std::numeric_limits<std::uint64_t>::max();
65 auto find_by_id(std::uint64_t
const&
id)
const ->
auto const& {
66 for (
auto const& l :
leafs) {
76 auto build(std::vector<hierarchy_pair>
const& hps,
77 std::unordered_map<std::uint64_t, vertex_type>
const& centers,
79 for (
auto const& hp : hps) {
80 if (
id == hp.parent && hp.parent != hp.id) {
81 leafs.emplace_back(hp.id, hps, centers, edges);
91 auto dists = std::vector<std::pair<std::uint64_t, Real>>{};
92 dists.reserve(
leafs.size());
93 dists.emplace_back(0, 0.0);
94 for (std::size_t i = 1; i <
leafs.size(); ++i) {
95 auto offset = edges[
leafs[i].center] - edges[
leafs[0].center];
97 dot(offset, split_dir)));
99 std::ranges::sort(dists, [](
auto const& lhs,
auto const& rhs) {
100 auto const& [i, idist] = lhs;
101 auto const& [j, jdist] = rhs;
102 return idist < jdist;
104 auto reordered_indices = std::vector<std::uint64_t>(
leafs.size());
105 using namespace std::ranges;
106 copy(dists | views::transform([](
auto const& x) {
return x.first; }),
107 begin(reordered_indices));
123template <
typename Real, std::
size_t NumDimensions>
127 -> std::vector<vertex<Real, NumDimensions>> {
128 using namespace std::ranges;
129 if (h.leafs.empty()) {
132 auto const split_dir = edges[h.leafs[1].center] - edges[h.leafs[0].center];
133 auto front = std::vector<vertex<Real, NumDimensions>>{};
134 auto constexpr angle_threshold = Real(20);
135 auto constexpr radians = gcem::cos(angle_threshold * M_PI / Real(180));
136 auto const offset_dir = other_center - edges[h.center];
137 auto ca =
cos_angle(offset_dir, split_dir);
143 for (
auto const& l : h.leafs) {
145 std::back_inserter(
front));
148 auto out_it = std::back_inserter(
front);
152 edges[h.leafs.front().center]) <
154 edges[h.leafs.back().center])) {
155 copy(
get_front(h.leafs.front(), edges, other_center), out_it);
157 copy(
get_front(h.leafs.back(), edges, other_center), out_it);
163template <
typename Real, std::
size_t NumDimensions>
167 if (
dot(edges[front0.back()] - edges[front0.front()],
168 edges[front1.back()] - edges[front1.front()]) < 0) {
169 std::ranges::reverse(front1);
172 auto it0 =
begin(front0);
173 auto it1 =
begin(front1);
174 auto end0 =
end(front0);
175 auto end1 =
end(front1);
177 edges.insert_edge(*it0, *it1);
178 while (
next(it0) != end0 ||
next(it1) != end1) {
179 if (
next(it0) == end0) {
181 edges.insert_edge(*it0, *it1);
182 }
else if (
next(it1) == end1) {
184 edges.insert_edge(*it0, *it1);
186 auto itn0 =
next(it0);
187 auto itn1 =
next(it1);
190 edges.insert_edge(*it0, *itn1);
193 edges.insert_edge(*it1, *itn0);
201template <
typename Real, std::
size_t NumDimensions>
205 auto front0 =
get_front(h0, edges, edges[h1.center]);
206 auto front1 =
get_front(h1, edges, edges[h0.center]);
210template <
typename Real, std::
size_t NumDimensions>
213 for (
auto const& l : h.
leafs) {
218template <
typename Real, std::
size_t NumDimensions>
221 if (!h.leafs.empty()) {
222 for (
auto const& l : h.leafs) {
225 for (std::size_t i = 0; i < h.leafs.size() - 1; ++i) {
232template <
typename Real, std::
size_t NumDimensions>
244 for (
auto const& hp : hps) {
245 num = std::max(num, hp.id);
Definition: post_triangulation.h:10
auto total_num_particles(std::vector< hierarchy_pair > const &hps)
Definition: post_triangulation.h:242
typename tatooine::edgeset< Real, NumDimensions >::vertex_handle vertex
Definition: post_triangulation.h:13
auto get_front(hierarchy< Real, NumDimensions > const &h, edgeset< Real, NumDimensions > const &edges, vec< Real, NumDimensions > const &other_center) -> std::vector< vertex< Real, NumDimensions > >
Definition: post_triangulation.h:124
auto triangulate_root(edgeset< Real, NumDimensions > &edges, hierarchy< Real, NumDimensions > const &h)
Definition: post_triangulation.h:211
auto triangulate(edgeset< Real, NumDimensions > &edges, hierarchy< Real, NumDimensions > const &h0, hierarchy< Real, NumDimensions > const &h1) -> void
Triangulates two particles.
Definition: post_triangulation.h:202
auto connect_fronts(std::vector< vertex< Real, NumDimensions > > &front0, std::vector< vertex< Real, NumDimensions > > &front1, edgeset< Real, NumDimensions > &edges) -> void
Definition: post_triangulation.h:164
auto triangulate_non_root(edgeset< Real, NumDimensions > &edges, hierarchy< Real, NumDimensions > const &h) -> void
Definition: post_triangulation.h:219
constexpr auto squared_euclidean_length(base_tensor< Tensor, T, N > const &t_in)
Definition: length.h:7
constexpr auto cos_angle(base_tensor< Tensor0, T0, N > const &v0, base_tensor< Tensor1, T1, N > const &v1)
Returns the cosine of the angle of two normalized vectors.
Definition: tensor_operations.h:32
auto begin(Range &&range)
Definition: iterator_facade.h:318
auto reorder(std::ranges::range auto &data, std::ranges::range auto &order) -> void
reorders a range data with another range order
Definition: reorder.h:10
auto end(Range &&range)
Definition: iterator_facade.h:322
constexpr auto normalize(base_tensor< Tensor, T, N > const &t_in) -> vec< T, N >
Definition: tensor_operations.h:100
constexpr auto dot(base_tensor< Tensor0, T0, N > const &lhs, base_tensor< Tensor1, T1, N > const &rhs)
Definition: tensor_operations.h:120
auto next(Iter iter)
Definition: iterator_facade.h:325
constexpr auto squared_euclidean_distance(base_tensor< Tensor0, T0, N > const &lhs, base_tensor< Tensor1, T1, N > const &rhs)
Definition: distance.h:11
auto front(linspace< Real > const &l)
Definition: linspace.h:126
Definition: post_triangulation.h:15
std::uint64_t id
Definition: post_triangulation.h:16
std::uint64_t parent
Definition: post_triangulation.h:17
Definition: post_triangulation.h:21
vertex< Real, NumDimensions > vertex_type
Definition: post_triangulation.h:22
std::vector< hierarchy > leafs
Definition: post_triangulation.h:28
hierarchy(std::uint64_t const id_)
Definition: post_triangulation.h:32
auto build(std::vector< hierarchy_pair > const &hps, std::unordered_map< std::uint64_t, vertex_type > const ¢ers, edgeset_type const &edges) -> void
Definition: post_triangulation.h:76
std::uint64_t id
Definition: post_triangulation.h:26
auto find_by_id(std::uint64_t const &id) const -> auto const &
Definition: post_triangulation.h:65
auto calc_split_dir(edgeset_type const &edges) -> vec_type
Definition: post_triangulation.h:111
hierarchy(std::uint64_t const id_, vertex_type const center_)
Definition: post_triangulation.h:34
hierarchy(std::vector< hierarchy_pair > const &hps, std::unordered_map< std::uint64_t, vertex_type > const ¢ers, edgeset_type const &edges)
as root node
Definition: post_triangulation.h:50
vertex_type center
Definition: post_triangulation.h:27
auto sort_leafs(edgeset_type const &edges) -> void
Definition: post_triangulation.h:89
auto is_root() const
Definition: post_triangulation.h:61
hierarchy(std::uint64_t const id_, std::vector< hierarchy_pair > const &hps, std::unordered_map< std::uint64_t, vertex_type > const ¢ers, edgeset_type const &edges)
as child node
Definition: post_triangulation.h:38
Definition: vertex_handle.h:10
static auto constexpr zeros()
Definition: vec.h:26