Chris@16: // Boost.Geometry (aka GGL, Generic Geometry Library) Chris@16: Chris@16: // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. Chris@16: // Copyright (c) 2009-2012 Barend Gehrels, Amsterdam, the Netherlands. Chris@16: Chris@16: // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library Chris@16: // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. Chris@16: Chris@16: // Use, modification and distribution is subject to the Boost Software License, Chris@16: // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP Chris@16: #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP Chris@16: Chris@101: #include Chris@101: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: // Helper geometry Chris@16: #include Chris@16: Chris@16: Chris@16: namespace boost { namespace geometry Chris@16: { Chris@16: Chris@16: namespace strategy { namespace centroid Chris@16: { Chris@16: Chris@16: namespace detail Chris@16: { Chris@16: Chris@16: template Chris@16: struct weighted_length_sums Chris@16: { Chris@16: typedef typename geometry::model::point Chris@16: < Chris@16: Type, DimensionCount, Chris@16: cs::cartesian Chris@16: > work_point; Chris@16: Chris@16: Type length; Chris@16: work_point average_sum; Chris@16: Chris@16: inline weighted_length_sums() Chris@16: : length(Type()) Chris@16: { Chris@16: geometry::assign_zero(average_sum); Chris@16: } Chris@16: }; Chris@16: } Chris@16: Chris@16: template Chris@16: < Chris@16: typename Point, Chris@16: typename PointOfSegment = Point Chris@16: > Chris@16: class weighted_length Chris@16: { Chris@16: private : Chris@16: typedef typename select_most_precise Chris@16: < Chris@16: typename default_distance_result::type, Chris@16: typename default_distance_result::type Chris@16: >::type distance_type; Chris@16: Chris@16: public : Chris@16: typedef detail::weighted_length_sums Chris@16: < Chris@16: distance_type, Chris@16: geometry::dimension::type::value Chris@16: > state_type; Chris@16: Chris@16: static inline void apply(PointOfSegment const& p1, Chris@16: PointOfSegment const& p2, state_type& state) Chris@16: { Chris@16: distance_type const d = geometry::distance(p1, p2); Chris@16: state.length += d; Chris@16: Chris@16: typename state_type::work_point weighted_median; Chris@16: geometry::assign_zero(weighted_median); Chris@16: geometry::add_point(weighted_median, p1); Chris@16: geometry::add_point(weighted_median, p2); Chris@16: geometry::multiply_value(weighted_median, d/2); Chris@16: geometry::add_point(state.average_sum, weighted_median); Chris@16: } Chris@16: Chris@16: static inline bool result(state_type const& state, Point& centroid) Chris@16: { Chris@16: distance_type const zero = distance_type(); Chris@16: if (! geometry::math::equals(state.length, zero)) Chris@16: { Chris@16: assign_zero(centroid); Chris@16: add_point(centroid, state.average_sum); Chris@16: divide_value(centroid, state.length); Chris@16: return true; Chris@16: } Chris@16: Chris@16: return false; Chris@16: } Chris@16: Chris@16: }; Chris@16: Chris@16: #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS Chris@16: Chris@16: namespace services Chris@16: { Chris@16: Chris@16: Chris@16: // Register this strategy for linear geometries, in all dimensions Chris@16: Chris@16: template Chris@16: struct default_strategy Chris@16: < Chris@16: cartesian_tag, Chris@16: linear_tag, Chris@16: N, Chris@16: Point, Chris@16: Geometry Chris@16: > Chris@16: { Chris@16: typedef weighted_length Chris@16: < Chris@16: Point, Chris@16: typename point_type::type Chris@16: > type; Chris@16: }; Chris@16: Chris@16: Chris@16: } // namespace services Chris@16: Chris@16: Chris@16: #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS Chris@16: Chris@16: Chris@16: }} // namespace strategy::centroid Chris@16: Chris@16: Chris@16: }} // namespace boost::geometry Chris@16: Chris@16: Chris@16: #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP