]> git.sesse.net Git - casparcg/blob - dependencies/boost/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp
Manually merged pull request #222
[casparcg] / dependencies / boost / boost / geometry / strategies / cartesian / centroid_weighted_length.hpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2
3 // Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
4 // Copyright (c) 2009-2011 Barend Gehrels, Amsterdam, the Netherlands.
5
6 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
7 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
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 #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP
14 #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP
15
16 #include <boost/geometry/algorithms/distance.hpp>
17 #include <boost/geometry/arithmetic/arithmetic.hpp>
18 #include <boost/geometry/util/select_most_precise.hpp>
19 #include <boost/geometry/strategies/centroid.hpp>
20 #include <boost/geometry/strategies/default_distance_result.hpp>
21
22 // Helper geometry
23 #include <boost/geometry/geometries/point.hpp>
24
25
26 namespace boost { namespace geometry
27 {
28
29 namespace strategy { namespace centroid
30 {
31
32 namespace detail
33 {
34
35 template <typename Type, std::size_t DimensionCount>
36 struct weighted_length_sums
37 {
38     typedef typename geometry::model::point
39         <
40             Type, DimensionCount,
41             cs::cartesian
42         > work_point;
43
44     Type length;
45     work_point average_sum;
46
47     inline weighted_length_sums()
48         : length(Type())
49     {
50         geometry::assign_zero(average_sum);
51     }
52 };
53 }
54
55 template
56 <
57     typename Point,
58     typename PointOfSegment = Point
59 >
60 class weighted_length
61 {
62 private :
63     typedef typename select_most_precise
64         <
65             typename default_distance_result<Point>::type,
66             typename default_distance_result<PointOfSegment>::type
67         >::type distance_type;
68
69 public :
70     typedef detail::weighted_length_sums
71         <
72             distance_type,
73             geometry::dimension<Point>::type::value
74         > state_type;
75
76     static inline void apply(PointOfSegment const& p1,
77             PointOfSegment const& p2, state_type& state)
78     {
79         distance_type const d = geometry::distance(p1, p2);
80         state.length += d;
81
82         typename state_type::work_point weighted_median;
83         geometry::assign_zero(weighted_median);
84         geometry::add_point(weighted_median, p1);
85         geometry::add_point(weighted_median, p2);
86         geometry::multiply_value(weighted_median, d/2);
87         geometry::add_point(state.average_sum, weighted_median);
88     }
89
90     static inline bool result(state_type const& state, Point& centroid)
91     {
92         distance_type const zero = distance_type();
93         if (! geometry::math::equals(state.length, zero))
94         {
95             assign_zero(centroid);
96             add_point(centroid, state.average_sum);
97             divide_value(centroid, state.length);
98             return true;
99         }
100
101         return false;
102     }
103
104 };
105
106 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
107
108 namespace services
109 {
110
111
112 // Register this strategy for linear geometries, in all dimensions
113
114 template <std::size_t N, typename Point, typename Geometry>
115 struct default_strategy
116 <
117     cartesian_tag,
118     linear_tag,
119     N,
120     Point,
121     Geometry
122 >
123 {
124     typedef weighted_length
125         <
126             Point,
127             typename point_type<Geometry>::type
128         > type;
129 };
130
131
132 } // namespace services
133
134
135 #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
136
137
138 }} // namespace strategy::centroid
139
140
141 }} // namespace boost::geometry
142
143
144 #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP