$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r71027 - in trunk: boost/geometry/strategies/cartesian libs/geometry/test/algorithms
From: bruno.lalande_at_[hidden]
Date: 2011-04-06 02:56:19
Author: bruno.lalande
Date: 2011-04-06 02:56:16 EDT (Wed, 06 Apr 2011)
New Revision: 71027
URL: http://svn.boost.org/trac/boost/changeset/71027
Log:
Generalized linestring centroid to nD.
Text files modified: 
   trunk/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp |    59 +++++++++++++++++++++++++++------------ 
   trunk/libs/geometry/test/algorithms/centroid.cpp                       |     1                                         
   2 files changed, 42 insertions(+), 18 deletions(-)
Modified: trunk/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp
==============================================================================
--- trunk/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp	(original)
+++ trunk/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp	2011-04-06 02:56:16 EDT (Wed, 06 Apr 2011)
@@ -13,10 +13,9 @@
 #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP
 #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP
 
-#include <cstddef>
-
-#include <boost/array.hpp>
 #include <boost/geometry/algorithms/distance.hpp>
+#include <boost/geometry/arithmetic/arithmetic.hpp>
+#include <boost/geometry/geometries/point.hpp>
 #include <boost/geometry/util/select_most_precise.hpp>
 #include <boost/geometry/strategies/centroid.hpp>
 #include <boost/geometry/strategies/default_distance_result.hpp>
@@ -37,16 +36,19 @@
 template <typename Type, std::size_t DimensionCount>
 struct weighted_length_sums
 {
+    typedef typename geometry::model::point
+        <
+            Type, DimensionCount,
+            cs::cartesian
+        > work_point;
+
     Type length;
-    boost::array<Type, DimensionCount> average_sum;
+    work_point average_sum;
 
     inline weighted_length_sums()
         : length(Type())
     {
-        for (std::size_t i = 0; i < DimensionCount; i++)
-        {
-            average_sum[i] = Type();
-        }
+        geometry::assign_zero(average_sum);
     }
 };
 }
@@ -66,7 +68,11 @@
         >::type distance_type;
 
 public :
-    typedef detail::weighted_length_sums<distance_type, 2> state_type;
+    typedef detail::weighted_length_sums
+        <
+            distance_type,
+            geometry::dimension<Point>::type::value
+        > state_type;
 
     static inline void apply(PointOfSegment const& p1,
             PointOfSegment const& p2, state_type& state)
@@ -74,13 +80,12 @@
         distance_type const d = geometry::distance(p1, p2);
         state.length += d;
 
-        distance_type two(2);
-
-        // Might be made generic for N dimensions using specializations
-        distance_type const mx = (get<0>(p1) + get<0>(p2)) / two;
-        distance_type const my = (get<1>(p1) + get<1>(p2)) / two;
-        state.average_sum[0] += d * mx;
-        state.average_sum[1] += d * my;
+        typename state_type::work_point weighted_median;
+        geometry::assign_zero(weighted_median);
+        geometry::add_point(weighted_median, p1);
+        geometry::add_point(weighted_median, p2);
+        geometry::multiply_value(weighted_median, d/2);
+        geometry::add_point(state.average_sum, weighted_median);
     }
 
     static inline bool result(state_type const& state, Point& centroid)
@@ -88,8 +93,9 @@
         distance_type const zero = distance_type();
         if (! geometry::math::equals(state.length, zero))
         {
-            set<0>(centroid, state.average_sum[0] / state.length);
-            set<1>(centroid, state.average_sum[1] / state.length);
+            assign_zero(centroid);
+            add_point(centroid, state.average_sum);
+            divide_value(centroid, state.length);
             return true;
         }
 
@@ -121,6 +127,23 @@
         > type;
 };
 
+template <typename Point, typename Geometry>
+struct default_strategy
+<
+    cartesian_tag,
+    linear_tag,
+    3,
+    Point,
+    Geometry
+>
+{
+    typedef weighted_length
+        <
+            Point,
+            typename point_type<Geometry>::type
+        > type;
+};
+
 
 
 } // namespace services
Modified: trunk/libs/geometry/test/algorithms/centroid.cpp
==============================================================================
--- trunk/libs/geometry/test/algorithms/centroid.cpp	(original)
+++ trunk/libs/geometry/test/algorithms/centroid.cpp	2011-04-06 02:56:16 EDT (Wed, 06 Apr 2011)
@@ -78,6 +78,7 @@
 template <typename P>
 void test_3d()
 {
+    test_centroid<bg::model::linestring<P> >("LINESTRING(1 2 3,4 5 -6,7 -8 9,-10 11 12,13 -14 -15, 16 17 18)", 5.6748865168734692, 0.31974938587214002, 1.9915270387763671);
     test_centroid<bg::model::box<P> >("POLYGON((1 2 3,5 6 7))", 3, 4, 5);
     test_centroid<P>("POINT(1 2 3)", 1, 2, 3);
 }