|
Boost-Commit : |
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);
}
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk