1#ifndef TATOOINE_ISOLINES_H
2#define TATOOINE_ISOLINES_H
23template <
typename XDomain,
typename YDomain>
26 std::size_t, std::size_t,
38 auto process_cell = [&](
auto ix,
auto iy) {
39 auto iso_positions = std::vector<typename edgeset_type::vertex_handle>{};
44 get_scalars(ix, iy, p[0]), get_scalars(ix + 1, iy, p[1]),
45 get_scalars(ix + 1, iy + 1, p[2]), get_scalars(ix, iy + 1, p[3])};
46 if (s[0] > isolevel && s[1] > isolevel && s[2] > isolevel &&
50 if (s[0] < isolevel && s[1] < isolevel && s[2] < isolevel &&
55 auto check_edge = [&](std::size_t
const i, std::size_t
const j) {
56 if ((s[i] > isolevel && s[j] < isolevel) ||
57 (s[i] < isolevel && s[j] > isolevel)) {
58 auto const t = (isolevel - s[i]) / (-s[i] + s[j]);
59 iso_positions.push_back(
isolines.insert_vertex(p[i] * (1 - t) + p[j] * t));
66 for (std::size_t i = 0; i < 4; ++i) {
67 if (s[i] == isolevel) {
68 iso_positions.push_back(
isolines.insert_vertex(p[i]));
72 if (
size(iso_positions) == 2) {
75 std::lock_guard lock{mutex};
77 isolines.insert_edge(iso_positions[0], iso_positions[1]);
82 if (
size(iso_positions) == 4) {
83 auto const scalar_center = (s[0] + s[1] + s[2] + s[3]) / 4;
86 std::lock_guard lock{mutex};
88 if (scalar_center > isolevel && s[0] > isolevel) {
89 isolines.insert_edge(iso_positions[0], iso_positions[1]);
90 isolines.insert_edge(iso_positions[2], iso_positions[3]);
92 isolines.insert_edge(iso_positions[0], iso_positions[3]);
93 isolines.insert_edge(iso_positions[2], iso_positions[1]);
110template <
typename Gr
id, arithmetic T,
bool HasNonConstReference>
112 Grid, T, HasNonConstReference>
const& data,
115 [&](
auto ix,
auto iy,
auto const& ) ->
auto const& {
118 data.grid(), isolevel);
121template <arithmetic Real,
typename Indexing, arithmetic BBReal>
127 [&](
auto ix,
auto iy,
auto const& ) ->
auto const& {
135template <arithmetic Real, arithmetic BBReal,
typename Indexing,
136 typename MemLoc, std::size_t XRes, std::size_t YRes>
142 [&](
auto ix,
auto iy,
auto const& ) ->
auto const& {
150template <
typename Field,
typename FieldReal,
151 floating_point_range XDomain,
152 floating_point_range YDomain,
153 arithmetic TReal = FieldReal>
156 arithmetic auto const isolevel, TReal
const t = 0) {
157 auto eval = [&](
auto const ,
auto const ,
auto const& pos) {
Definition: dynamic_multidim_array.h:18
auto size() const -> auto const &
Definition: dynamic_multidim_size.h:107
auto num_dimensions() const
Definition: dynamic_multidim_size.h:105
Definition: rectilinear_grid.h:38
constexpr auto size(std::index_sequence< Seq... >) const
Definition: rectilinear_grid.h:347
auto vertex_at(std::index_sequence< DIs... >, std::array< Int, num_dimensions()> const &is) const -> vec< real_type, num_dimensions()>
Definition: rectilinear_grid.h:640
common_type< typename Dimensions::value_type... > real_type
Definition: rectilinear_grid.h:46
Definition: static_multidim_array.h:19
static auto constexpr size()
Definition: static_multidim_array.h:30
Definition: concepts.h:33
Definition: concepts.h:121
static constexpr sequential_t sequential
Definition: tags.h:63
Definition: algorithm.h:6
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
void eval(base_tensor< Tensor, GiNaC::ex, Dims... > &m)
Definition: tensor_symbolic.h:53
auto size(vec< ValueType, N > const &v)
Definition: vec.h:148
constexpr auto for_loop(Iteration &&iteration, execution_policy::sequential_t, Ranges(&&... ranges)[2]) -> void
Use this function for creating a sequential nested loop.
Definition: for_loop.h:336
Definition: axis_aligned_bounding_box.h:103
auto constexpr max() const -> auto const &
Definition: axis_aligned_bounding_box.h:156
auto constexpr min() const -> auto const &
Definition: axis_aligned_bounding_box.h:151
Definition: vertex_property.h:96
Definition: linspace.h:26