Tatooine
ridgelines.h
Go to the documentation of this file.
1#ifndef TATOOINE_FIELDS_RIDGELINES_H
2#define TATOOINE_FIELDS_RIDGELINES_H
3//==============================================================================
4#include <tatooine/edgeset.h>
5#include <tatooine/isolines.h>
7//==============================================================================
8namespace tatooine {
9//==============================================================================
13template <typename Grid, arithmetic T, bool HasNonConstReference,
14 typename DomainX, typename DomainY>
15requires(Grid::num_dimensions() == 2)
17 Grid, T, HasNonConstReference> const& data,
19 execution_policy_tag auto const exec) {
20 using real_type = typename Grid::real_type;
21 using edgeset_type = Edgeset2<real_type>;
22 auto& g = working_grid.sample_to_vertex_property(diff<1>(data),
23 "[ridgelines]_g", exec);
24 auto& c = working_grid.sample_to_vertex_property(
25 [&](integral auto const... is) {
26 auto const& g_ = g(is...);
27 return vec{-g_(1), g_(0)};
28 },
29 "[ridgelines]_c", exec);
30 auto& hessian = working_grid.sample_to_vertex_property(
31 diff<2>(data), "[ridgelines]_H", exec);
32
33 auto& Hg = working_grid.sample_to_vertex_property(
34 [&](integral auto const... is) { return hessian(is...) * g(is...); },
35 "[ridgelines]_Hg", exec);
36 auto& Hc = working_grid.sample_to_vertex_property(
37 [&](integral auto const... is) { return hessian(is...) * c(is...); },
38 "[ridgelines]_Hc", exec);
39 working_grid.sample_to_vertex_property(
40 [&](integral auto const... is) {
41 auto i = std::size_t{};
42 auto max_abs = -std::numeric_limits<real_type>::max();
43 for (std::size_t j = 0; j < 2; ++j) {
44 if (auto const a = gcem::abs(g(is...)(j)); a > max_abs) {
45 max_abs = a;
46 i = j;
47 }
48 }
49 return Hc(is...)(i) / g(is...)(i);
50 },
51 "[ridgelines]_lambda_g", exec);
52 auto& lambda_c = working_grid.sample_to_vertex_property(
53 [&](integral auto const... is) {
54 auto i = std::size_t{};
55 auto max_abs = -std::numeric_limits<real_type>::max();
56 for (std::size_t j = 0; j < 2; ++j) {
57 if (auto const a = gcem::abs(c(is...)(j)); a > max_abs) {
58 max_abs = a;
59 i = j;
60 }
61 }
62 return Hc(is...)(i) / c(is...)(i);
63 },
64 "[ridgelines]_lambda_c", exec);
65 auto const compute_d = [&](integral auto const... is) {
66 auto const& g_ = g(is...);
67 auto const& Hg_ = Hg(is...);
68 return g_(0) * Hg_(1) - g_(1) * Hg_(0);
69 };
70 auto& d = working_grid.sample_to_vertex_property(
71 compute_d, "[ridgelines]_det(g|Hg)", exec);
72
73 auto const raw = isolines(d, 0);
74 auto ridgelines = edgeset_type{};
75 auto lc = lambda_c.linear_sampler();
76 for (auto const e : raw.simplices()) {
77 auto [v0, v1] = raw[e];
78 if (lc(raw[v0]) <= 0 && lc(raw[v1]) <= 0) {
79 auto vr0 = ridgelines.insert_vertex(raw[v0]);
80 auto vr1 = ridgelines.insert_vertex(raw[v1]);
81 ridgelines.insert_edge(vr0, vr1);
82 }
83 }
84 return ridgelines;
85}
86//------------------------------------------------------------------------------
88template <typename Grid, arithmetic T, bool HasNonConstReference,
89 typename DomainX, typename DomainY>
90requires(Grid::num_dimensions() == 2)
92 Grid, T, HasNonConstReference> const& data,
93 execution_policy_tag auto const exec) {
94 return ridgelines(data, data.grid.copy_without_properties(), exec);
95}
96//------------------------------------------------------------------------------
100template <typename Grid, arithmetic T, bool HasNonConstReference,
101 typename DomainX, typename DomainY>
102requires(Grid::num_dimensions() == 2)
104 Grid, T, HasNonConstReference> const& data,
106 return ridgelines(data, working_grid, execution_policy::sequential);
107}
108//------------------------------------------------------------------------------
110template <typename Grid, arithmetic T, bool HasNonConstReference>
111requires(Grid::num_dimensions() == 2)
113 Grid, T, HasNonConstReference> const& data) {
114 return ridgelines(data, data.grid.copy_without_properties(),
116}
117//==============================================================================
118} // namespace tatooine
119//==============================================================================
120#endif
Definition: rectilinear_grid.h:38
auto sample_to_vertex_property(F &&f, std::string const &name) -> auto &
Definition: rectilinear_grid.h:1080
Definition: tags.h:72
Definition: concepts.h:21
static constexpr sequential_t sequential
Definition: tags.h:63
Definition: algorithm.h:6
auto ridgelines(detail::rectilinear_grid::typed_vertex_property_interface< Grid, T, HasNonConstReference > const &data, rectilinear_grid< DomainX, DomainY > &working_grid, execution_policy_tag auto const exec)
Definition: ridgelines.h:16
auto isolines(invocable< std::size_t, std::size_t, Vec2< typename rectilinear_grid< XDomain, YDomain >::real_type > > auto &&get_scalars, rectilinear_grid< XDomain, YDomain > const &g, arithmetic auto const isolevel)
Indexing and lookup map from http://paulbourke.net/geometry/polygonise/.
Definition: isolines.h:24
Definition: edgeset.h:9
Definition: vec.h:12