]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/geometry/include/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / geometry / include / boost / geometry / strategies / cartesian / centroid_weighted_length.hpp
CommitLineData
7c673cae
FG
1// Boost.Geometry (aka GGL, Generic Geometry Library)
2
3// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
4// Copyright (c) 2009-2015 Barend Gehrels, Amsterdam, the Netherlands.
5
6// This file was modified by Oracle on 2015.
7// Modifications copyright (c) 2015, Oracle and/or its affiliates.
8
9// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
10
11// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
12// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
13
14// Use, modification and distribution is subject to the Boost Software License,
15// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
16// http://www.boost.org/LICENSE_1_0.txt)
17
18#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP
19#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP
20
21#include <boost/math/special_functions/fpclassify.hpp>
22#include <boost/numeric/conversion/cast.hpp>
23
24#include <boost/geometry/algorithms/detail/distance/interface.hpp>
25#include <boost/geometry/algorithms/detail/distance/point_to_geometry.hpp>
26#include <boost/geometry/arithmetic/arithmetic.hpp>
27#include <boost/geometry/util/for_each_coordinate.hpp>
28#include <boost/geometry/util/select_most_precise.hpp>
29#include <boost/geometry/strategies/centroid.hpp>
30#include <boost/geometry/strategies/default_distance_result.hpp>
31
32// Helper geometry
33#include <boost/geometry/geometries/point.hpp>
34
35
36namespace boost { namespace geometry
37{
38
39namespace strategy { namespace centroid
40{
41
42namespace detail
43{
44
45template <typename Type, std::size_t DimensionCount>
46struct weighted_length_sums
47{
48 typedef typename geometry::model::point
49 <
50 Type, DimensionCount,
51 cs::cartesian
52 > work_point;
53
54 Type length;
55 work_point average_sum;
56
57 inline weighted_length_sums()
58 : length(Type())
59 {
60 geometry::assign_zero(average_sum);
61 }
62};
63}
64
65template
66<
67 typename Point,
68 typename PointOfSegment = Point
69>
70class weighted_length
71{
72private :
73 typedef typename select_most_precise
74 <
75 typename default_distance_result<Point>::type,
76 typename default_distance_result<PointOfSegment>::type
77 >::type distance_type;
78
79public :
80 typedef detail::weighted_length_sums
81 <
82 distance_type,
83 geometry::dimension<Point>::type::value
84 > state_type;
85
86 static inline void apply(PointOfSegment const& p1,
87 PointOfSegment const& p2, state_type& state)
88 {
89 distance_type const d = geometry::distance(p1, p2);
90 state.length += d;
91
92 typename state_type::work_point weighted_median;
93 geometry::assign_zero(weighted_median);
94 geometry::add_point(weighted_median, p1);
95 geometry::add_point(weighted_median, p2);
96 geometry::multiply_value(weighted_median, d/2);
97 geometry::add_point(state.average_sum, weighted_median);
98 }
99
100 static inline bool result(state_type const& state, Point& centroid)
101 {
102 distance_type const zero = distance_type();
103 if (! geometry::math::equals(state.length, zero)
104 && boost::math::isfinite(state.length)) // Prevent NaN centroid coordinates
105 {
106 // NOTE: above distance_type is checked, not the centroid coordinate_type
107 // which means that the centroid can still be filled with INF
108 // if e.g. distance_type is double and centroid contains floats
109 geometry::for_each_coordinate(centroid, set_sum_div_length(state));
110 return true;
111 }
112
113 return false;
114 }
115
116 struct set_sum_div_length
117 {
118 state_type const& m_state;
119 set_sum_div_length(state_type const& state)
120 : m_state(state)
121 {}
122 template <typename Pt, std::size_t Dimension>
123 void apply(Pt & centroid) const
124 {
125 typedef typename geometry::coordinate_type<Pt>::type coordinate_type;
126 geometry::set<Dimension>(
127 centroid,
128 boost::numeric_cast<coordinate_type>(
129 geometry::get<Dimension>(m_state.average_sum) / m_state.length
130 )
131 );
132 }
133 };
134};
135
136#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
137
138namespace services
139{
140
141
142// Register this strategy for linear geometries, in all dimensions
143
144template <std::size_t N, typename Point, typename Geometry>
145struct default_strategy
146<
147 cartesian_tag,
148 linear_tag,
149 N,
150 Point,
151 Geometry
152>
153{
154 typedef weighted_length
155 <
156 Point,
157 typename point_type<Geometry>::type
158 > type;
159};
160
161
162} // namespace services
163
164
165#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
166
167
168}} // namespace strategy::centroid
169
170
171}} // namespace boost::geometry
172
173
174#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP