1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
4 // Copyright (c) 2009-2011 Barend Gehrels, Amsterdam, the Netherlands.
6 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
7 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
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)
13 #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP
14 #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP
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>
23 #include <boost/geometry/geometries/point.hpp>
26 namespace boost { namespace geometry
29 namespace strategy { namespace centroid
35 template <typename Type, std::size_t DimensionCount>
36 struct weighted_length_sums
38 typedef typename geometry::model::point
45 work_point average_sum;
47 inline weighted_length_sums()
50 geometry::assign_zero(average_sum);
58 typename PointOfSegment = Point
63 typedef typename select_most_precise
65 typename default_distance_result<Point>::type,
66 typename default_distance_result<PointOfSegment>::type
67 >::type distance_type;
70 typedef detail::weighted_length_sums
73 geometry::dimension<Point>::type::value
76 static inline void apply(PointOfSegment const& p1,
77 PointOfSegment const& p2, state_type& state)
79 distance_type const d = geometry::distance(p1, p2);
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);
90 static inline bool result(state_type const& state, Point& centroid)
92 distance_type const zero = distance_type();
93 if (! geometry::math::equals(state.length, zero))
95 assign_zero(centroid);
96 add_point(centroid, state.average_sum);
97 divide_value(centroid, state.length);
106 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
112 // Register this strategy for linear geometries, in all dimensions
114 template <std::size_t N, typename Point, typename Geometry>
115 struct default_strategy
124 typedef weighted_length
127 typename point_type<Geometry>::type
132 } // namespace services
135 #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
138 }} // namespace strategy::centroid
141 }} // namespace boost::geometry
144 #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP