Skip to content

Commit b59b651

Browse files
committed
[extensions] Automatically generated floating point filters.
1 parent 02b1632 commit b59b651

File tree

18 files changed

+2990
-0
lines changed

18 files changed

+2990
-0
lines changed

extensions/example/Jamfile

+1
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ project boost-geometry-examples-extensions
1313
;
1414

1515
build-project gis ;
16+
build-project generic_robust_predicates ;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Boost.Geometry (aka GGL, Generic Geometry Library)
2+
3+
# Use, modification and distribution is subject to the Boost Software License,
4+
# Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5+
# http://www.boost.org/LICENSE_1_0.txt)
6+
7+
8+
project boost-geometry-example-extensions-generic_robust_predicates
9+
:
10+
;
11+
12+
exe static_side_2d : static_side_2d.cpp ;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Boost.Geometry (aka GGL, Generic Geometry Library)
2+
3+
// Copyright (c) 2020 Tinko Bartels, Berlin, Germany.
4+
5+
// Contributed and/or modified by Tinko Bartels,
6+
// as part of Google Summer of Code 2020 program.
7+
8+
// Use, modification and distribution is subject to the Boost Software License,
9+
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
10+
// http://www.boost.org/LICENSE_1_0.txt)
11+
12+
13+
#define BOOST_GEOMETRY_NO_BOOST_TEST
14+
15+
#include <iostream>
16+
17+
#include <boost/geometry/core/cs.hpp>
18+
#include <boost/geometry/geometries/point.hpp>
19+
20+
#include <boost/geometry/extensions/triangulation/strategies/cartesian/side_robust.hpp>
21+
#include <boost/geometry/extensions/generic_robust_predicates/strategies/cartesian/detail/expressions.hpp>
22+
#include <boost/geometry/extensions/generic_robust_predicates/strategies/cartesian/detail/stage_a.hpp>
23+
24+
25+
namespace bg = boost::geometry;
26+
using point = bg::model::point<double, 2, bg::cs::cartesian>;
27+
28+
template <typename CalculationType>
29+
struct side_robust_with_static_filter
30+
{
31+
private:
32+
using ct = CalculationType;
33+
using expression = bg::detail::generic_robust_predicates::orient2d;
34+
using filter = bg::detail::generic_robust_predicates::stage_a_static
35+
<
36+
expression,
37+
ct
38+
>;
39+
filter m_filter;
40+
public:
41+
side_robust_with_static_filter(ct x_max, ct y_max, ct x_min, ct y_min)
42+
: m_filter(x_max, y_max, x_max, y_max, x_max, y_max,
43+
x_min, y_min, x_min, y_min, x_min, y_min) {};
44+
45+
template
46+
<
47+
typename P1,
48+
typename P2,
49+
typename P
50+
>
51+
inline int apply(P1 const& p1, P2 const& p2, P const& p) const
52+
{
53+
int sign = m_filter.apply(bg::get<0>(p1),
54+
bg::get<1>(p1),
55+
bg::get<0>(p2),
56+
bg::get<1>(p2),
57+
bg::get<0>(p),
58+
bg::get<1>(p));
59+
if(sign != bg::detail::generic_robust_predicates::sign_uncertain)
60+
{
61+
return sign;
62+
}
63+
else
64+
{
65+
//fallback if filter fails.
66+
return bg::strategy::side::side_robust<double>::apply(p1, p2, p);
67+
}
68+
}
69+
};
70+
71+
int main(int argc, char** argv)
72+
{
73+
point p1(0.0, 0.0);
74+
point p2(1.0, 1.0);
75+
point p (0.0, 1.0);
76+
side_robust_with_static_filter<double> static_strategy(2.0, 2.0, 1.0, 1.0);
77+
std::cout << "Side value: " << static_strategy.apply(p1, p2, p) << "\n";
78+
return 0;
79+
}

extensions/test/Jamfile

+1
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,4 @@ build-project gis ;
2828
build-project iterators ;
2929
build-project nsphere ;
3030
build-project triangulation ;
31+
build-project generic_robust_predicates ;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Boost.Geometry (aka GGL, Generic Geometry Library)
2+
#
3+
# Use, modification and distribution is subject to the Boost Software License,
4+
# Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5+
# http://www.boost.org/LICENSE_1_0.txt)
6+
7+
test-suite boost-geometry-extensions-generic_robust_predicates
8+
:
9+
[ run approximate.cpp ]
10+
[ run side3d.cpp : : : <debug-symbols>off ]
11+
;
12+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Boost.Geometry (aka GGL, Generic Geometry Library)
2+
// Unit Test
3+
4+
// Copyright (c) 2020 Tinko Bartels, Berlin, Germany.
5+
6+
// Contributed and/or modified by Tinko Bartels,
7+
// as part of Google Summer of Code 2020 program.
8+
9+
// Use, modification and distribution is subject to the Boost Software License,
10+
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
11+
// http://www.boost.org/LICENSE_1_0.txt)
12+
13+
#include <array>
14+
15+
#include <geometry_test_common.hpp>
16+
17+
#include <boost/geometry/extensions/generic_robust_predicates/strategies/cartesian/detail/approximate.hpp>
18+
#include <boost/geometry/extensions/generic_robust_predicates/strategies/cartesian/detail/expression_tree.hpp>
19+
20+
template <typename CalculationType>
21+
void test_all()
22+
{
23+
using bg::detail::generic_robust_predicates::_1;
24+
using bg::detail::generic_robust_predicates::_2;
25+
using bg::detail::generic_robust_predicates::_3;
26+
using bg::detail::generic_robust_predicates::_4;
27+
using bg::detail::generic_robust_predicates::sum;
28+
using bg::detail::generic_robust_predicates::difference;
29+
using bg::detail::generic_robust_predicates::product;
30+
using bg::detail::generic_robust_predicates::max;
31+
using bg::detail::generic_robust_predicates::abs;
32+
using bg::detail::generic_robust_predicates::post_order;
33+
using bg::detail::generic_robust_predicates::approximate_value;
34+
using bg::detail::generic_robust_predicates::get_approx;
35+
using bg::detail::generic_robust_predicates::approximate_interim;
36+
using ct = CalculationType;
37+
ct r1 = approximate_value<sum<_1, _2>, ct>(
38+
std::array<ct, 2>{1.0, 2.0});
39+
BOOST_CHECK_EQUAL(3.0, r1);
40+
ct r2 = approximate_value<max<abs<_1>, abs<_2>>, ct>(
41+
std::array<ct, 2>{-10.0, 2.0});
42+
BOOST_CHECK_EQUAL(10.0, r2);
43+
44+
using expression = product
45+
<
46+
difference<_1, _2>,
47+
difference<_3, _4>
48+
>;
49+
using evals = post_order<expression>;
50+
std::array<ct, boost::mp11::mp_size<evals>::value> r;
51+
std::array<ct, 4> input {5.0, 3.0, 2.0, 8.0};
52+
approximate_interim<evals, evals, ct>(r, input);
53+
ct r3 = get_approx<evals, typename expression::left, ct>(r, input);
54+
BOOST_CHECK_EQUAL(2.0, r3);
55+
ct r4 = get_approx<evals, typename expression::right, ct>(r, input);
56+
BOOST_CHECK_EQUAL(-6.0, r4);
57+
ct r5 = get_approx<evals, expression, ct>(r, input);
58+
BOOST_CHECK_EQUAL(-12.0, r5);
59+
}
60+
61+
62+
int test_main(int, char* [])
63+
{
64+
test_all<double>();
65+
return 0;
66+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Boost.Geometry (aka GGL, Generic Geometry Library)
2+
// Unit Test
3+
4+
// Copyright (c) 2020 Tinko Bartels, Berlin, Germany.
5+
6+
// Contributed and/or modified by Tinko Bartels,
7+
// as part of Google Summer of Code 2020 program.
8+
9+
// Use, modification and distribution is subject to the Boost Software License,
10+
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
11+
// http://www.boost.org/LICENSE_1_0.txt)
12+
13+
#include <array>
14+
15+
#include <geometry_test_common.hpp>
16+
17+
#include <boost/geometry/extensions/generic_robust_predicates/strategies/cartesian/detail/expressions.hpp>
18+
#include <boost/geometry/extensions/generic_robust_predicates/strategies/cartesian/detail/stage_a.hpp>
19+
20+
template <typename CalculationType>
21+
void test_all()
22+
{
23+
using bg::detail::generic_robust_predicates::orient3d;
24+
using bg::detail::generic_robust_predicates::stage_a_semi_static;
25+
using bg::detail::generic_robust_predicates::stage_a_almost_static;
26+
using bg::detail::generic_robust_predicates::stage_a_static;
27+
using ct = CalculationType;
28+
using semi_static = stage_a_semi_static<orient3d, ct>;
29+
BOOST_CHECK_EQUAL(1,
30+
semi_static::apply(1, 0, 0,
31+
0, 1, 0,
32+
1, 1, 0,
33+
0, 0, 1));
34+
BOOST_CHECK_EQUAL(-1,
35+
semi_static::apply(1, 0, 0,
36+
0, 1, 0,
37+
1, 1, 0,
38+
0, 0, -1));
39+
BOOST_CHECK_EQUAL(0,
40+
semi_static::apply(1, 0, 0,
41+
0, 1, 0,
42+
1, 1, 0,
43+
0, 0, 0));
44+
stage_a_static<orient3d, ct> stat(10, 10, 10,
45+
10, 10, 10,
46+
10, 10, 10,
47+
10, 10, 10,
48+
0, 0, 0,
49+
0, 0, 0,
50+
0, 0, 0,
51+
0, 0, 0);
52+
BOOST_CHECK_EQUAL(1, stat.apply(1, 0, 0,
53+
0, 1, 0,
54+
1, 1, 0,
55+
0, 0, 1));
56+
57+
stage_a_static<orient3d, ct> pessimistic(1e40, 1e40, 1e40,
58+
1e40, 1e40, 1e40,
59+
1e40, 1e40, 1e40,
60+
1e40, 1e40, 1e40,
61+
0, 0, 0,
62+
0, 0, 0,
63+
0, 0, 0,
64+
0, 0, 0);
65+
BOOST_CHECK_EQUAL(bg::detail::generic_robust_predicates::sign_uncertain,
66+
pessimistic.apply(1, 0, 0,
67+
0, 1, 0,
68+
1, 1, 0,
69+
0, 0, 1));
70+
}
71+
72+
int test_main(int, char* [])
73+
{
74+
test_all<double>();
75+
return 0;
76+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
// Boost.Geometry (aka GGL, Generic Geometry Library)
2+
3+
// Copyright (c) 2020 Tinko Bartels, Berlin, Germany.
4+
5+
// Contributed and/or modified by Tinko Bartels,
6+
// as part of Google Summer of Code 2020 program.
7+
8+
// Use, modification and distribution is subject to the Boost Software License,
9+
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
10+
// http://www.boost.org/LICENSE_1_0.txt)
11+
12+
#ifndef BOOST_GEOMETRY_EXTENSIONS_GENERIC_ROBUST_PREDICATES_STRATEGIES_CARTESIAN_DETAIL_ALMOST_STATIC_FILTER_HPP
13+
#define BOOST_GEOMETRY_EXTENSIONS_GENERIC_ROBUST_PREDICATES_STRATEGIES_CARTESIAN_DETAIL_ALMOST_STATIC_FILTER_HPP
14+
15+
#include <array>
16+
#include <algorithm>
17+
#include <limits>
18+
19+
#include <boost/geometry/extensions/generic_robust_predicates/strategies/cartesian/detail/expression_tree.hpp>
20+
21+
namespace boost { namespace geometry
22+
{
23+
24+
namespace detail { namespace generic_robust_predicates
25+
{
26+
27+
template <typename Filter, std::size_t N, std::size_t End>
28+
struct make_filter_impl
29+
{
30+
template <typename ExtremaArray, typename ...Reals>
31+
static Filter apply(const ExtremaArray& extrema, const Reals&... args)
32+
{
33+
return make_filter_impl<Filter, N + 1, End>
34+
::apply(extrema, args..., extrema[N]);
35+
}
36+
};
37+
38+
template <typename Filter, std::size_t End>
39+
struct make_filter_impl<Filter, End, End>
40+
{
41+
template <typename ExtremaArray, typename ...Reals>
42+
static Filter apply(const ExtremaArray& extrema, const Reals&... args)
43+
{
44+
Filter f(args...);
45+
return f;
46+
}
47+
};
48+
49+
template
50+
<
51+
typename Expression,
52+
typename CalculationType,
53+
typename StaticFilter
54+
>
55+
class almost_static_filter
56+
{
57+
private:
58+
using expression_max_argn = max_argn<Expression>;
59+
using ct = CalculationType;
60+
using extrema_array = std::array<ct, 2 * expression_max_argn::value>;
61+
extrema_array m_extrema;
62+
StaticFilter m_filter;
63+
public:
64+
const StaticFilter& filter() const { return m_filter; }
65+
inline almost_static_filter()
66+
{
67+
std::fill(m_extrema.begin(),
68+
m_extrema.begin() + m_extrema.size() / 2,
69+
-std::numeric_limits<ct>::infinity());
70+
std::fill(m_extrema.begin() + m_extrema.size() / 2,
71+
m_extrema.end(),
72+
std::numeric_limits<ct>::infinity());
73+
}
74+
template <typename ...Reals>
75+
int apply(const Reals&... args) const
76+
{
77+
return m_filter.apply(args...);
78+
}
79+
80+
template <typename ...Reals>
81+
inline void update_extrema(const Reals&... args)
82+
{
83+
std::array<ct, sizeof...(Reals)> input {{ static_cast<ct>(args)... }};
84+
for(int i = 0; i < m_extrema.size() / 2; ++i)
85+
{
86+
m_extrema[i] = std::max(m_extrema[i], input[i]);
87+
}
88+
for(int i = m_extrema.size() / 2; i < m_extrema.size(); ++i)
89+
{
90+
m_extrema[i] = std::min(m_extrema[i], input[i]);
91+
}
92+
}
93+
94+
template <typename ...Reals>
95+
inline bool update_extrema_check(const Reals&... args)
96+
{
97+
bool changed = false;
98+
std::array<ct, sizeof...(Reals)> input {{ static_cast<ct>(args)... }};
99+
for(int i = 0; i < m_extrema.size() / 2; ++i)
100+
{
101+
if(input[i] > m_extrema[i])
102+
{
103+
changed = true;
104+
m_extrema[i] = input[i];
105+
}
106+
}
107+
for(int i = m_extrema.size() / 2; i < m_extrema.size(); ++i)
108+
{
109+
if(input[i] < m_extrema[i])
110+
{
111+
changed = true;
112+
m_extrema[i] = input[i];
113+
}
114+
}
115+
return changed;
116+
}
117+
118+
inline void update_filter()
119+
{
120+
m_filter = make_filter_impl
121+
<
122+
StaticFilter,
123+
0,
124+
2 * expression_max_argn::value
125+
>::apply(m_extrema);
126+
}
127+
};
128+
129+
}} // namespace detail::generic_robust_predicates
130+
131+
}} // namespace boost::geometry
132+
133+
#endif // BOOST_GEOMETRY_EXTENSIONS_GENERIC_ROBUST_PREDICATES_STRATEGIES_CARTESIAN_DETAIL_ALMOST_STATIC_FILTER_HPP

0 commit comments

Comments
 (0)