Added boost header
This commit is contained in:
131
test/external/boost/geometry/strategies/cartesian/area_surveyor.hpp
vendored
Normal file
131
test/external/boost/geometry/strategies/cartesian/area_surveyor.hpp
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_AREA_SURVEYOR_HPP
|
||||
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_AREA_SURVEYOR_HPP
|
||||
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/point_xy.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
namespace strategy { namespace area
|
||||
{
|
||||
|
||||
/*!
|
||||
\brief Area calculation for cartesian points
|
||||
\ingroup strategies
|
||||
\details Calculates area using the Surveyor's formula, a well-known
|
||||
triangulation algorithm
|
||||
\tparam PointOfSegment \tparam_segment_point
|
||||
\tparam CalculationType \tparam_calculation
|
||||
|
||||
\qbk{
|
||||
[heading See also]
|
||||
[link geometry.reference.algorithms.area.area_2_with_strategy area (with strategy)]
|
||||
}
|
||||
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename PointOfSegment,
|
||||
typename CalculationType = void
|
||||
>
|
||||
class surveyor
|
||||
{
|
||||
public :
|
||||
// If user specified a calculation type, use that type,
|
||||
// whatever it is and whatever the point-type is.
|
||||
// Else, use the pointtype, but at least double
|
||||
typedef typename
|
||||
boost::mpl::if_c
|
||||
<
|
||||
boost::is_void<CalculationType>::type::value,
|
||||
typename select_most_precise
|
||||
<
|
||||
typename coordinate_type<PointOfSegment>::type,
|
||||
double
|
||||
>::type,
|
||||
CalculationType
|
||||
>::type return_type;
|
||||
|
||||
|
||||
private :
|
||||
|
||||
class summation
|
||||
{
|
||||
friend class surveyor;
|
||||
|
||||
return_type sum;
|
||||
public :
|
||||
|
||||
inline summation() : sum(return_type())
|
||||
{
|
||||
// Strategy supports only 2D areas
|
||||
assert_dimension<PointOfSegment, 2>();
|
||||
}
|
||||
inline return_type area() const
|
||||
{
|
||||
return_type result = sum;
|
||||
result /= 2;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
public :
|
||||
typedef summation state_type;
|
||||
typedef PointOfSegment segment_point_type;
|
||||
|
||||
static inline void apply(PointOfSegment const& p1,
|
||||
PointOfSegment const& p2,
|
||||
summation& state)
|
||||
{
|
||||
// SUM += x2 * y1 - x1 * y2;
|
||||
state.sum += get<0>(p2) * get<1>(p1) - get<0>(p1) * get<1>(p2);
|
||||
}
|
||||
|
||||
static inline return_type result(summation const& state)
|
||||
{
|
||||
return state.area();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
|
||||
|
||||
namespace services
|
||||
{
|
||||
template <typename Point>
|
||||
struct default_strategy<cartesian_tag, Point>
|
||||
{
|
||||
typedef strategy::area::surveyor<Point> type;
|
||||
};
|
||||
|
||||
} // namespace services
|
||||
|
||||
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
|
||||
|
||||
|
||||
}} // namespace strategy::area
|
||||
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_AREA_SURVEYOR_HPP
|
||||
176
test/external/boost/geometry/strategies/cartesian/box_in_box.hpp
vendored
Normal file
176
test/external/boost/geometry/strategies/cartesian/box_in_box.hpp
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BOX_IN_BOX_HPP
|
||||
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BOX_IN_BOX_HPP
|
||||
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/strategies/covered_by.hpp>
|
||||
#include <boost/geometry/strategies/within.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry { namespace strategy
|
||||
{
|
||||
|
||||
|
||||
namespace within
|
||||
{
|
||||
|
||||
struct box_within_range
|
||||
{
|
||||
template <typename BoxContainedValue, typename BoxContainingValue>
|
||||
static inline bool apply(BoxContainedValue const& bed_min
|
||||
, BoxContainedValue const& bed_max
|
||||
, BoxContainingValue const& bing_min
|
||||
, BoxContainingValue const& bing_max)
|
||||
{
|
||||
return bed_min > bing_min && bed_max < bing_max;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct box_covered_by_range
|
||||
{
|
||||
template <typename BoxContainedValue, typename BoxContainingValue>
|
||||
static inline bool apply(BoxContainedValue const& bed_min
|
||||
, BoxContainedValue const& bed_max
|
||||
, BoxContainingValue const& bing_min
|
||||
, BoxContainingValue const& bing_max)
|
||||
{
|
||||
return bed_min >= bing_min && bed_max <= bing_max;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename SubStrategy,
|
||||
typename Box1,
|
||||
typename Box2,
|
||||
std::size_t Dimension,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct relate_box_box_loop
|
||||
{
|
||||
static inline bool apply(Box1 const& b_contained, Box2 const& b_containing)
|
||||
{
|
||||
assert_dimension_equal<Box1, Box2>();
|
||||
|
||||
if (! SubStrategy::apply(
|
||||
get<min_corner, Dimension>(b_contained),
|
||||
get<max_corner, Dimension>(b_contained),
|
||||
get<min_corner, Dimension>(b_containing),
|
||||
get<max_corner, Dimension>(b_containing)
|
||||
)
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return relate_box_box_loop
|
||||
<
|
||||
SubStrategy,
|
||||
Box1, Box2,
|
||||
Dimension + 1, DimensionCount
|
||||
>::apply(b_contained, b_containing);
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename SubStrategy,
|
||||
typename Box1,
|
||||
typename Box2,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct relate_box_box_loop<SubStrategy, Box1, Box2, DimensionCount, DimensionCount>
|
||||
{
|
||||
static inline bool apply(Box1 const& , Box2 const& )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Box1,
|
||||
typename Box2,
|
||||
typename SubStrategy = box_within_range
|
||||
>
|
||||
struct box_in_box
|
||||
{
|
||||
static inline bool apply(Box1 const& box1, Box2 const& box2)
|
||||
{
|
||||
return relate_box_box_loop
|
||||
<
|
||||
SubStrategy,
|
||||
Box1, Box2, 0, dimension<Box1>::type::value
|
||||
>::apply(box1, box2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace within
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
|
||||
|
||||
|
||||
namespace within { namespace services
|
||||
{
|
||||
|
||||
template <typename BoxContained, typename BoxContaining>
|
||||
struct default_strategy
|
||||
<
|
||||
box_tag, box_tag,
|
||||
box_tag, areal_tag,
|
||||
cartesian_tag, cartesian_tag,
|
||||
BoxContained, BoxContaining
|
||||
>
|
||||
{
|
||||
typedef within::box_in_box<BoxContained, BoxContaining> type;
|
||||
};
|
||||
|
||||
|
||||
}} // namespace within::services
|
||||
|
||||
namespace covered_by { namespace services
|
||||
{
|
||||
|
||||
template <typename BoxContained, typename BoxContaining>
|
||||
struct default_strategy
|
||||
<
|
||||
box_tag, box_tag,
|
||||
box_tag, areal_tag,
|
||||
cartesian_tag, cartesian_tag,
|
||||
BoxContained, BoxContaining
|
||||
>
|
||||
{
|
||||
typedef within::box_in_box
|
||||
<
|
||||
BoxContained, BoxContaining,
|
||||
within::box_covered_by_range
|
||||
> type;
|
||||
};
|
||||
|
||||
}} // namespace covered_by::services
|
||||
|
||||
|
||||
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
|
||||
|
||||
|
||||
}}} // namespace boost::geometry::strategy
|
||||
|
||||
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BOX_IN_BOX_HPP
|
||||
495
test/external/boost/geometry/strategies/cartesian/cart_intersect.hpp
vendored
Normal file
495
test/external/boost/geometry/strategies/cartesian/cart_intersect.hpp
vendored
Normal file
@@ -0,0 +1,495 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_INTERSECTION_HPP
|
||||
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_INTERSECTION_HPP
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/geometry/core/exception.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/point_concept.hpp>
|
||||
#include <boost/geometry/geometries/concepts/segment_concept.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/assign_values.hpp>
|
||||
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
#include <boost/geometry/util/select_calculation_type.hpp>
|
||||
|
||||
// Temporary / will be Strategy as template parameter
|
||||
#include <boost/geometry/strategies/side.hpp>
|
||||
#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/side_info.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
namespace strategy { namespace intersection
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename Segment, size_t Dimension>
|
||||
struct segment_arrange
|
||||
{
|
||||
template <typename T>
|
||||
static inline void apply(Segment const& s, T& s_1, T& s_2, bool& swapped)
|
||||
{
|
||||
s_1 = get<0, Dimension>(s);
|
||||
s_2 = get<1, Dimension>(s);
|
||||
if (s_1 > s_2)
|
||||
{
|
||||
std::swap(s_1, s_2);
|
||||
swapped = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t Index, typename Segment>
|
||||
inline typename geometry::point_type<Segment>::type get_from_index(
|
||||
Segment const& segment)
|
||||
{
|
||||
typedef typename geometry::point_type<Segment>::type point_type;
|
||||
point_type point;
|
||||
geometry::detail::assign::assign_point_from_index
|
||||
<
|
||||
Segment, point_type, Index, 0, dimension<Segment>::type::value
|
||||
>::apply(segment, point);
|
||||
return point;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/***
|
||||
template <typename T>
|
||||
inline std::string rdebug(T const& value)
|
||||
{
|
||||
if (math::equals(value, 0)) return "'0'";
|
||||
if (math::equals(value, 1)) return "'1'";
|
||||
if (value < 0) return "<0";
|
||||
if (value > 1) return ">1";
|
||||
return "<0..1>";
|
||||
}
|
||||
***/
|
||||
|
||||
/*!
|
||||
\see http://mathworld.wolfram.com/Line-LineIntersection.html
|
||||
*/
|
||||
template <typename Policy, typename CalculationType = void>
|
||||
struct relate_cartesian_segments
|
||||
{
|
||||
typedef typename Policy::return_type return_type;
|
||||
typedef typename Policy::segment_type1 segment_type1;
|
||||
typedef typename Policy::segment_type2 segment_type2;
|
||||
|
||||
//typedef typename point_type<segment_type1>::type point_type;
|
||||
//BOOST_CONCEPT_ASSERT( (concept::Point<point_type>) );
|
||||
|
||||
BOOST_CONCEPT_ASSERT( (concept::ConstSegment<segment_type1>) );
|
||||
BOOST_CONCEPT_ASSERT( (concept::ConstSegment<segment_type2>) );
|
||||
|
||||
typedef typename select_calculation_type
|
||||
<segment_type1, segment_type2, CalculationType>::type coordinate_type;
|
||||
|
||||
/// Relate segments a and b
|
||||
static inline return_type apply(segment_type1 const& a, segment_type2 const& b)
|
||||
{
|
||||
coordinate_type const dx_a = get<1, 0>(a) - get<0, 0>(a); // distance in x-dir
|
||||
coordinate_type const dx_b = get<1, 0>(b) - get<0, 0>(b);
|
||||
coordinate_type const dy_a = get<1, 1>(a) - get<0, 1>(a); // distance in y-dir
|
||||
coordinate_type const dy_b = get<1, 1>(b) - get<0, 1>(b);
|
||||
return apply(a, b, dx_a, dy_a, dx_b, dy_b);
|
||||
}
|
||||
|
||||
|
||||
// Relate segments a and b using precalculated differences.
|
||||
// This can save two or four subtractions in many cases
|
||||
static inline return_type apply(segment_type1 const& a, segment_type2 const& b,
|
||||
coordinate_type const& dx_a, coordinate_type const& dy_a,
|
||||
coordinate_type const& dx_b, coordinate_type const& dy_b)
|
||||
{
|
||||
// 1) Handle "disjoint", probably common case.
|
||||
// per dimension, 2 cases: a_1----------a_2 b_1-------b_2 or B left of A
|
||||
coordinate_type ax_1, ax_2, bx_1, bx_2;
|
||||
bool ax_swapped = false, bx_swapped = false;
|
||||
detail::segment_arrange<segment_type1, 0>::apply(a, ax_1, ax_2, ax_swapped);
|
||||
detail::segment_arrange<segment_type2, 0>::apply(b, bx_1, bx_2, bx_swapped);
|
||||
if (ax_2 < bx_1 || ax_1 > bx_2)
|
||||
{
|
||||
return Policy::disjoint();
|
||||
}
|
||||
|
||||
// 1b) In Y-dimension
|
||||
coordinate_type ay_1, ay_2, by_1, by_2;
|
||||
bool ay_swapped = false, by_swapped = false;
|
||||
detail::segment_arrange<segment_type1, 1>::apply(a, ay_1, ay_2, ay_swapped);
|
||||
detail::segment_arrange<segment_type2, 1>::apply(b, by_1, by_2, by_swapped);
|
||||
if (ay_2 < ay_1 || ay_1 > by_2)
|
||||
{
|
||||
return Policy::disjoint();
|
||||
}
|
||||
|
||||
typedef side::side_by_triangle<coordinate_type> side;
|
||||
side_info sides;
|
||||
|
||||
// 2) Calculate sides
|
||||
// Note: Do NOT yet calculate the determinant here, but use the SIDE strategy.
|
||||
// Determinant calculation is not robust; side (orient) can be made robust
|
||||
// (and is much robuster even without measures)
|
||||
sides.set<1>
|
||||
(
|
||||
side::apply(detail::get_from_index<0>(a)
|
||||
, detail::get_from_index<1>(a)
|
||||
, detail::get_from_index<0>(b)),
|
||||
side::apply(detail::get_from_index<0>(a)
|
||||
, detail::get_from_index<1>(a)
|
||||
, detail::get_from_index<1>(b))
|
||||
);
|
||||
|
||||
if (sides.same<1>())
|
||||
{
|
||||
// Both points are at same side of other segment, we can leave
|
||||
return Policy::disjoint();
|
||||
}
|
||||
|
||||
// 2b) For other segment
|
||||
sides.set<0>
|
||||
(
|
||||
side::apply(detail::get_from_index<0>(b)
|
||||
, detail::get_from_index<1>(b)
|
||||
, detail::get_from_index<0>(a)),
|
||||
side::apply(detail::get_from_index<0>(b)
|
||||
, detail::get_from_index<1>(b)
|
||||
, detail::get_from_index<1>(a))
|
||||
);
|
||||
|
||||
if (sides.same<0>())
|
||||
{
|
||||
return Policy::disjoint();
|
||||
}
|
||||
|
||||
// Degenerate cases: segments of single point, lying on other segment, non disjoint
|
||||
coordinate_type const zero = 0;
|
||||
if (math::equals(dx_a, zero) && math::equals(dy_a, zero))
|
||||
{
|
||||
return Policy::degenerate(a, true);
|
||||
}
|
||||
if (math::equals(dx_b, zero) && math::equals(dy_b, zero))
|
||||
{
|
||||
return Policy::degenerate(b, false);
|
||||
}
|
||||
|
||||
bool collinear = sides.collinear();
|
||||
|
||||
// Get the same type, but at least a double (also used for divisions)
|
||||
typedef typename select_most_precise
|
||||
<
|
||||
coordinate_type, double
|
||||
>::type promoted_type;
|
||||
|
||||
|
||||
promoted_type const d = (dy_b * dx_a) - (dx_b * dy_a);
|
||||
// Determinant d should be nonzero.
|
||||
// If it is zero, we have an robustness issue here,
|
||||
// (and besides that we cannot divide by it)
|
||||
if(math::equals(d, zero) && ! collinear)
|
||||
//if(! collinear && sides.as_collinear())
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION
|
||||
std::cout << "Determinant zero? Type : "
|
||||
<< typeid(coordinate_type).name()
|
||||
<< std::endl;
|
||||
|
||||
std::cout << " dx_a : " << dx_a << std::endl;
|
||||
std::cout << " dy_a : " << dy_a << std::endl;
|
||||
std::cout << " dx_b : " << dx_b << std::endl;
|
||||
std::cout << " dy_b : " << dy_b << std::endl;
|
||||
|
||||
std::cout << " side a <-> b.first : " << sides.get<0,0>() << std::endl;
|
||||
std::cout << " side a <-> b.second: " << sides.get<0,1>() << std::endl;
|
||||
std::cout << " side b <-> a.first : " << sides.get<1,0>() << std::endl;
|
||||
std::cout << " side b <-> a.second: " << sides.get<1,1>() << std::endl;
|
||||
#endif
|
||||
|
||||
if (sides.as_collinear())
|
||||
{
|
||||
sides.set<0>(0,0);
|
||||
sides.set<1>(0,0);
|
||||
collinear = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Policy::error("Determinant zero!");
|
||||
}
|
||||
}
|
||||
|
||||
if(collinear)
|
||||
{
|
||||
// Segments are collinear. We'll find out how.
|
||||
if (math::equals(dx_b, zero))
|
||||
{
|
||||
// Vertical -> Check y-direction
|
||||
return relate_collinear(a, b,
|
||||
ay_1, ay_2, by_1, by_2,
|
||||
ay_swapped, by_swapped);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check x-direction
|
||||
return relate_collinear(a, b,
|
||||
ax_1, ax_2, bx_1, bx_2,
|
||||
ax_swapped, bx_swapped);
|
||||
}
|
||||
}
|
||||
|
||||
return Policy::segments_intersect(sides,
|
||||
dx_a, dy_a, dx_b, dy_b,
|
||||
a, b);
|
||||
}
|
||||
|
||||
private :
|
||||
|
||||
/// Relate segments known collinear
|
||||
static inline return_type relate_collinear(segment_type1 const& a
|
||||
, segment_type2 const& b
|
||||
, coordinate_type a_1, coordinate_type a_2
|
||||
, coordinate_type b_1, coordinate_type b_2
|
||||
, bool a_swapped, bool b_swapped)
|
||||
{
|
||||
// All ca. 150 lines are about collinear rays
|
||||
// The intersections, if any, are always boundary points of the segments. No need to calculate anything.
|
||||
// However we want to find out HOW they intersect, there are many cases.
|
||||
// Most sources only provide the intersection (above) or that there is a collinearity (but not the points)
|
||||
// or some spare sources give the intersection points (calculated) but not how they align.
|
||||
// This source tries to give everything and still be efficient.
|
||||
// It is therefore (and because of the extensive clarification comments) rather long...
|
||||
|
||||
// \see http://mpa.itc.it/radim/g50history/CMP/4.2.1-CERL-beta-libes/file475.txt
|
||||
// \see http://docs.codehaus.org/display/GEOTDOC/Point+Set+Theory+and+the+DE-9IM+Matrix
|
||||
// \see http://mathworld.wolfram.com/Line-LineIntersection.html
|
||||
|
||||
// Because of collinearity the case is now one-dimensional and can be checked using intervals
|
||||
// This function is called either horizontally or vertically
|
||||
// We get then two intervals:
|
||||
// a_1-------------a_2 where a_1 < a_2
|
||||
// b_1-------------b_2 where b_1 < b_2
|
||||
// In all figures below a_1/a_2 denotes arranged intervals, a1-a2 or a2-a1 are still unarranged
|
||||
|
||||
// Handle "equal", in polygon neighbourhood comparisons a common case
|
||||
|
||||
// Check if segments are equal...
|
||||
bool const a1_eq_b1 = math::equals(get<0, 0>(a), get<0, 0>(b))
|
||||
&& math::equals(get<0, 1>(a), get<0, 1>(b));
|
||||
bool const a2_eq_b2 = math::equals(get<1, 0>(a), get<1, 0>(b))
|
||||
&& math::equals(get<1, 1>(a), get<1, 1>(b));
|
||||
if (a1_eq_b1 && a2_eq_b2)
|
||||
{
|
||||
return Policy::segment_equal(a, false);
|
||||
}
|
||||
|
||||
// ... or opposite equal
|
||||
bool const a1_eq_b2 = math::equals(get<0, 0>(a), get<1, 0>(b))
|
||||
&& math::equals(get<0, 1>(a), get<1, 1>(b));
|
||||
bool const a2_eq_b1 = math::equals(get<1, 0>(a), get<0, 0>(b))
|
||||
&& math::equals(get<1, 1>(a), get<0, 1>(b));
|
||||
if (a1_eq_b2 && a2_eq_b1)
|
||||
{
|
||||
return Policy::segment_equal(a, true);
|
||||
}
|
||||
|
||||
|
||||
// The rest below will return one or two intersections.
|
||||
// The delegated class can decide which is the intersection point, or two, build the Intersection Matrix (IM)
|
||||
// For IM it is important to know which relates to which. So this information is given,
|
||||
// without performance penalties to intersection calculation
|
||||
|
||||
bool const has_common_points = a1_eq_b1 || a1_eq_b2 || a2_eq_b1 || a2_eq_b2;
|
||||
|
||||
|
||||
// "Touch" -> one intersection point -> one but not two common points
|
||||
// --------> A (or B)
|
||||
// <---------- B (or A)
|
||||
// a_2==b_1 (b_2==a_1 or a_2==b1)
|
||||
|
||||
// The check a_2/b_1 is necessary because it excludes cases like
|
||||
// ------->
|
||||
// --->
|
||||
// ... which are handled lateron
|
||||
|
||||
// Corresponds to 4 cases, of which the equal points are determined above
|
||||
// #1: a1---->a2 b1--->b2 (a arrives at b's border)
|
||||
// #2: a2<----a1 b2<---b1 (b arrives at a's border)
|
||||
// #3: a1---->a2 b2<---b1 (both arrive at each others border)
|
||||
// #4: a2<----a1 b1--->b2 (no arrival at all)
|
||||
// Where the arranged forms have two forms:
|
||||
// a_1-----a_2/b_1-------b_2 or reverse (B left of A)
|
||||
if (has_common_points && (math::equals(a_2, b_1) || math::equals(b_2, a_1)))
|
||||
{
|
||||
if (a2_eq_b1) return Policy::collinear_touch(get<1, 0>(a), get<1, 1>(a), 0, -1);
|
||||
if (a1_eq_b2) return Policy::collinear_touch(get<0, 0>(a), get<0, 1>(a), -1, 0);
|
||||
if (a2_eq_b2) return Policy::collinear_touch(get<1, 0>(a), get<1, 1>(a), 0, 0);
|
||||
if (a1_eq_b1) return Policy::collinear_touch(get<0, 0>(a), get<0, 1>(a), -1, -1);
|
||||
}
|
||||
|
||||
|
||||
// "Touch/within" -> there are common points and also an intersection of interiors:
|
||||
// Corresponds to many cases:
|
||||
// #1a: a1------->a2 #1b: a1-->a2
|
||||
// b1--->b2 b1------->b2
|
||||
// #2a: a2<-------a1 #2b: a2<--a1
|
||||
// b1--->b2 b1------->b2
|
||||
// #3a: a1------->a2 #3b: a1-->a2
|
||||
// b2<---b1 b2<-------b1
|
||||
// #4a: a2<-------a1 #4b: a2<--a1
|
||||
// b2<---b1 b2<-------b1
|
||||
|
||||
// Note: next cases are similar and handled by the code
|
||||
// #4c: a1--->a2
|
||||
// b1-------->b2
|
||||
// #4d: a1-------->a2
|
||||
// b1-->b2
|
||||
|
||||
// For case 1-4: a_1 < (b_1 or b_2) < a_2, two intersections are equal to segment B
|
||||
// For case 5-8: b_1 < (a_1 or a_2) < b_2, two intersections are equal to segment A
|
||||
if (has_common_points)
|
||||
{
|
||||
// Either A is in B, or B is in A, or (in case of robustness/equals)
|
||||
// both are true, see below
|
||||
bool a_in_b = (b_1 < a_1 && a_1 < b_2) || (b_1 < a_2 && a_2 < b_2);
|
||||
bool b_in_a = (a_1 < b_1 && b_1 < a_2) || (a_1 < b_2 && b_2 < a_2);
|
||||
|
||||
if (a_in_b && b_in_a)
|
||||
{
|
||||
// testcase "ggl_list_20110306_javier"
|
||||
// In robustness it can occur that a point of A is inside B AND a point of B is inside A,
|
||||
// still while has_common_points is true (so one point equals the other).
|
||||
// If that is the case we select on length.
|
||||
coordinate_type const length_a = geometry::math::abs(a_1 - a_2);
|
||||
coordinate_type const length_b = geometry::math::abs(b_1 - b_2);
|
||||
if (length_a > length_b)
|
||||
{
|
||||
a_in_b = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
b_in_a = false;
|
||||
}
|
||||
}
|
||||
|
||||
int const arrival_a = a_in_b ? 1 : -1;
|
||||
if (a2_eq_b2) return Policy::collinear_interior_boundary_intersect(a_in_b ? a : b, a_in_b, 0, 0, false);
|
||||
if (a1_eq_b2) return Policy::collinear_interior_boundary_intersect(a_in_b ? a : b, a_in_b, arrival_a, 0, true);
|
||||
if (a2_eq_b1) return Policy::collinear_interior_boundary_intersect(a_in_b ? a : b, a_in_b, 0, -arrival_a, true);
|
||||
if (a1_eq_b1) return Policy::collinear_interior_boundary_intersect(a_in_b ? a : b, a_in_b, arrival_a, -arrival_a, false);
|
||||
}
|
||||
|
||||
bool const opposite = a_swapped ^ b_swapped;
|
||||
|
||||
|
||||
// "Inside", a completely within b or b completely within a
|
||||
// 2 cases:
|
||||
// case 1:
|
||||
// a_1---a_2 -> take A's points as intersection points
|
||||
// b_1------------b_2
|
||||
// case 2:
|
||||
// a_1------------a_2
|
||||
// b_1---b_2 -> take B's points
|
||||
if (a_1 > b_1 && a_2 < b_2)
|
||||
{
|
||||
// A within B
|
||||
return Policy::collinear_a_in_b(a, opposite);
|
||||
}
|
||||
if (b_1 > a_1 && b_2 < a_2)
|
||||
{
|
||||
// B within A
|
||||
return Policy::collinear_b_in_a(b, opposite);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Now that all cases with equal,touch,inside,disjoint,
|
||||
degenerate are handled the only thing left is an overlap
|
||||
|
||||
Either a1 is between b1,b2
|
||||
or a2 is between b1,b2 (a2 arrives)
|
||||
|
||||
Next table gives an overview.
|
||||
The IP's are ordered following the line A1->A2
|
||||
|
||||
| |
|
||||
| a_2 in between | a_1 in between
|
||||
| |
|
||||
-----+---------------------------------+--------------------------
|
||||
| a1--------->a2 | a1--------->a2
|
||||
| b1----->b2 | b1----->b2
|
||||
| (b1,a2), a arrives | (a1,b2), b arrives
|
||||
| |
|
||||
-----+---------------------------------+--------------------------
|
||||
a sw.| a2<---------a1* | a2<---------a1*
|
||||
| b1----->b2 | b1----->b2
|
||||
| (a1,b1), no arrival | (b2,a2), a and b arrive
|
||||
| |
|
||||
-----+---------------------------------+--------------------------
|
||||
| a1--------->a2 | a1--------->a2
|
||||
b sw.| b2<-----b1 | b2<-----b1
|
||||
| (b2,a2), a and b arrive | (a1,b1), no arrival
|
||||
| |
|
||||
-----+---------------------------------+--------------------------
|
||||
a sw.| a2<---------a1* | a2<---------a1*
|
||||
b sw.| b2<-----b1 | b2<-----b1
|
||||
| (a1,b2), b arrives | (b1,a2), a arrives
|
||||
| |
|
||||
-----+---------------------------------+--------------------------
|
||||
* Note that a_1 < a_2, and a1 <> a_1; if a is swapped,
|
||||
the picture might seem wrong but it (supposed to be) is right.
|
||||
*/
|
||||
|
||||
bool const both_swapped = a_swapped && b_swapped;
|
||||
if (b_1 < a_2 && a_2 < b_2)
|
||||
{
|
||||
// Left column, from bottom to top
|
||||
return
|
||||
both_swapped ? Policy::collinear_overlaps(get<0, 0>(a), get<0, 1>(a), get<1, 0>(b), get<1, 1>(b), -1, 1, opposite)
|
||||
: b_swapped ? Policy::collinear_overlaps(get<1, 0>(b), get<1, 1>(b), get<1, 0>(a), get<1, 1>(a), 1, 1, opposite)
|
||||
: a_swapped ? Policy::collinear_overlaps(get<0, 0>(a), get<0, 1>(a), get<0, 0>(b), get<0, 1>(b), -1, -1, opposite)
|
||||
: Policy::collinear_overlaps(get<0, 0>(b), get<0, 1>(b), get<1, 0>(a), get<1, 1>(a), 1, -1, opposite)
|
||||
;
|
||||
}
|
||||
if (b_1 < a_1 && a_1 < b_2)
|
||||
{
|
||||
// Right column, from bottom to top
|
||||
return
|
||||
both_swapped ? Policy::collinear_overlaps(get<0, 0>(b), get<0, 1>(b), get<1, 0>(a), get<1, 1>(a), 1, -1, opposite)
|
||||
: b_swapped ? Policy::collinear_overlaps(get<0, 0>(a), get<0, 1>(a), get<0, 0>(b), get<0, 1>(b), -1, -1, opposite)
|
||||
: a_swapped ? Policy::collinear_overlaps(get<1, 0>(b), get<1, 1>(b), get<1, 0>(a), get<1, 1>(a), 1, 1, opposite)
|
||||
: Policy::collinear_overlaps(get<0, 0>(a), get<0, 1>(a), get<1, 0>(b), get<1, 1>(b), -1, 1, opposite)
|
||||
;
|
||||
}
|
||||
// Nothing should goes through. If any we have made an error
|
||||
// Robustness: it can occur here...
|
||||
return Policy::error("Robustness issue, non-logical behaviour");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace strategy::intersection
|
||||
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_INTERSECTION_HPP
|
||||
241
test/external/boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp
vendored
Normal file
241
test/external/boost/geometry/strategies/cartesian/centroid_bashein_detmer.hpp
vendored
Normal file
@@ -0,0 +1,241 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_BASHEIN_DETMER_HPP
|
||||
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_BASHEIN_DETMER_HPP
|
||||
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
#include <boost/geometry/core/coordinate_type.hpp>
|
||||
#include <boost/geometry/core/point_type.hpp>
|
||||
#include <boost/geometry/strategies/centroid.hpp>
|
||||
#include <boost/geometry/util/select_coordinate_type.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
// Note: when calling the namespace "centroid", it sometimes,
|
||||
// somehow, in gcc, gives compilation problems (confusion with function centroid).
|
||||
|
||||
namespace strategy { namespace centroid
|
||||
{
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
\brief Centroid calculation using algorith Bashein / Detmer
|
||||
\ingroup strategies
|
||||
\details Calculates centroid using triangulation method published by
|
||||
Bashein / Detmer
|
||||
\tparam Point point type of centroid to calculate
|
||||
\tparam PointOfSegment point type of segments, defaults to Point
|
||||
\par Concepts for Point and PointOfSegment:
|
||||
- specialized point_traits class
|
||||
\author Adapted from "Centroid of a Polygon" by
|
||||
Gerard Bashein and Paul R. Detmer<em>,
|
||||
in "Graphics Gems IV", Academic Press, 1994</em>
|
||||
\par Research notes
|
||||
The algorithm gives the same results as Oracle and PostGIS but
|
||||
differs from MySQL
|
||||
(tried 5.0.21 / 5.0.45 / 5.0.51a / 5.1.23).
|
||||
|
||||
Without holes:
|
||||
- this: POINT(4.06923363095238 1.65055803571429)
|
||||
- geolib: POINT(4.07254 1.66819)
|
||||
- MySQL: POINT(3.6636363636364 1.6272727272727)'
|
||||
- PostGIS: POINT(4.06923363095238 1.65055803571429)
|
||||
- Oracle: 4.06923363095238 1.65055803571429
|
||||
- SQL Server: POINT(4.06923362245959 1.65055804168294)
|
||||
|
||||
Statements:
|
||||
- \b MySQL/PostGIS: select AsText(Centroid(GeomFromText(
|
||||
'POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2,3.7 1.6,3.4 2,4.1 3,5.3 2.6
|
||||
,5.4 1.2,4.9 0.8,2.9 0.7,2 1.3))')))
|
||||
- \b Oracle: select sdo_geom.sdo_centroid(sdo_geometry(2003, null, null,
|
||||
sdo_elem_info_array(1, 1003, 1), sdo_ordinate_array(
|
||||
2,1.3,2.4,1.7,2.8,1.8,3.4,1.2,3.7,1.6,3.4,2,4.1,3,5.3,2.6
|
||||
,5.4,1.2,4.9,0.8,2.9,0.7,2,1.3))
|
||||
, mdsys.sdo_dim_array(mdsys.sdo_dim_element('x',0,10,.00000005)
|
||||
,mdsys.sdo_dim_element('y',0,10,.00000005)))
|
||||
from dual
|
||||
- \b SQL Server 2008: select geometry::STGeomFromText(
|
||||
'POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2,3.7 1.6,3.4 2,4.1 3,5.3 2.6
|
||||
,5.4 1.2,4.9 0.8,2.9 0.7,2 1.3))',0)
|
||||
.STCentroid()
|
||||
.STAsText()
|
||||
|
||||
With holes:
|
||||
- this: POINT(4.04663 1.6349)
|
||||
- geolib: POINT(4.04675 1.65735)
|
||||
- MySQL: POINT(3.6090580503834 1.607573932092)
|
||||
- PostGIS: POINT(4.0466265060241 1.63489959839357)
|
||||
- Oracle: 4.0466265060241 1.63489959839357
|
||||
- SQL Server: POINT(4.0466264962959677 1.6348996057331333)
|
||||
|
||||
Statements:
|
||||
- \b MySQL/PostGIS: select AsText(Centroid(GeomFromText(
|
||||
'POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2
|
||||
,3.7 1.6,3.4 2,4.1 3,5.3 2.6,5.4 1.2,4.9 0.8,2.9 0.7,2 1.3)
|
||||
,(4 2,4.2 1.4,4.8 1.9,4.4 2.2,4 2))')));
|
||||
- \b Oracle: select sdo_geom.sdo_centroid(sdo_geometry(2003, null, null
|
||||
, sdo_elem_info_array(1, 1003, 1, 25, 2003, 1)
|
||||
, sdo_ordinate_array(2,1.3,2.4,1.7,2.8,1.8,3.4,1.2,3.7,1.6,3.4,
|
||||
2,4.1,3,5.3,2.6,5.4,1.2,4.9,0.8,2.9,0.7,2,1.3,4,2, 4.2,1.4,
|
||||
4.8,1.9, 4.4,2.2, 4,2))
|
||||
, mdsys.sdo_dim_array(mdsys.sdo_dim_element('x',0,10,.00000005)
|
||||
,mdsys.sdo_dim_element('y',0,10,.00000005)))
|
||||
from dual
|
||||
|
||||
\qbk{
|
||||
[heading See also]
|
||||
[link geometry.reference.algorithms.centroid.centroid_3_with_strategy centroid (with strategy)]
|
||||
}
|
||||
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename Point,
|
||||
typename PointOfSegment = Point,
|
||||
typename CalculationType = void
|
||||
>
|
||||
class bashein_detmer
|
||||
{
|
||||
private :
|
||||
// If user specified a calculation type, use that type,
|
||||
// whatever it is and whatever the point-type(s) are.
|
||||
// Else, use the most appropriate coordinate type
|
||||
// of the two points, but at least double
|
||||
typedef typename
|
||||
boost::mpl::if_c
|
||||
<
|
||||
boost::is_void<CalculationType>::type::value,
|
||||
typename select_most_precise
|
||||
<
|
||||
typename select_coordinate_type
|
||||
<
|
||||
Point,
|
||||
PointOfSegment
|
||||
>::type,
|
||||
double
|
||||
>::type,
|
||||
CalculationType
|
||||
>::type calculation_type;
|
||||
|
||||
/*! subclass to keep state */
|
||||
class sums
|
||||
{
|
||||
friend class bashein_detmer;
|
||||
int count;
|
||||
calculation_type sum_a2;
|
||||
calculation_type sum_x;
|
||||
calculation_type sum_y;
|
||||
|
||||
public :
|
||||
inline sums()
|
||||
: count(0)
|
||||
, sum_a2(calculation_type())
|
||||
, sum_x(calculation_type())
|
||||
, sum_y(calculation_type())
|
||||
{
|
||||
typedef calculation_type ct;
|
||||
}
|
||||
};
|
||||
|
||||
public :
|
||||
typedef sums state_type;
|
||||
|
||||
static inline void apply(PointOfSegment const& p1,
|
||||
PointOfSegment const& p2, sums& state)
|
||||
{
|
||||
/* Algorithm:
|
||||
For each segment:
|
||||
begin
|
||||
ai = x1 * y2 - x2 * y1;
|
||||
sum_a2 += ai;
|
||||
sum_x += ai * (x1 + x2);
|
||||
sum_y += ai * (y1 + y2);
|
||||
end
|
||||
return POINT(sum_x / (3 * sum_a2), sum_y / (3 * sum_a2) )
|
||||
*/
|
||||
|
||||
// Get coordinates and promote them to calculation_type
|
||||
calculation_type const x1 = boost::numeric_cast<calculation_type>(get<0>(p1));
|
||||
calculation_type const y1 = boost::numeric_cast<calculation_type>(get<1>(p1));
|
||||
calculation_type const x2 = boost::numeric_cast<calculation_type>(get<0>(p2));
|
||||
calculation_type const y2 = boost::numeric_cast<calculation_type>(get<1>(p2));
|
||||
calculation_type const ai = x1 * y2 - x2 * y1;
|
||||
state.count++;
|
||||
state.sum_a2 += ai;
|
||||
state.sum_x += ai * (x1 + x2);
|
||||
state.sum_y += ai * (y1 + y2);
|
||||
}
|
||||
|
||||
static inline bool result(sums const& state, Point& centroid)
|
||||
{
|
||||
calculation_type const zero = calculation_type();
|
||||
if (state.count > 0 && state.sum_a2 != zero)
|
||||
{
|
||||
calculation_type const v3 = 3;
|
||||
calculation_type const a3 = v3 * state.sum_a2;
|
||||
|
||||
typedef typename geometry::coordinate_type
|
||||
<
|
||||
Point
|
||||
>::type coordinate_type;
|
||||
|
||||
set<0>(centroid,
|
||||
boost::numeric_cast<coordinate_type>(state.sum_x / a3));
|
||||
set<1>(centroid,
|
||||
boost::numeric_cast<coordinate_type>(state.sum_y / a3));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
|
||||
|
||||
namespace services
|
||||
{
|
||||
|
||||
// Register this strategy for rings and (multi)polygons, in two dimensions
|
||||
template <typename Point, typename Geometry>
|
||||
struct default_strategy<cartesian_tag, areal_tag, 2, Point, Geometry>
|
||||
{
|
||||
typedef bashein_detmer
|
||||
<
|
||||
Point,
|
||||
typename point_type<Geometry>::type
|
||||
> type;
|
||||
};
|
||||
|
||||
|
||||
} // namespace services
|
||||
|
||||
|
||||
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
|
||||
|
||||
|
||||
}} // namespace strategy::centroid
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_BASHEIN_DETMER_HPP
|
||||
144
test/external/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp
vendored
Normal file
144
test/external/boost/geometry/strategies/cartesian/centroid_weighted_length.hpp
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
// Copyright (c) 2009-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP
|
||||
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP
|
||||
|
||||
#include <boost/geometry/algorithms/distance.hpp>
|
||||
#include <boost/geometry/arithmetic/arithmetic.hpp>
|
||||
#include <boost/geometry/util/select_most_precise.hpp>
|
||||
#include <boost/geometry/strategies/centroid.hpp>
|
||||
#include <boost/geometry/strategies/default_distance_result.hpp>
|
||||
|
||||
// Helper geometry
|
||||
#include <boost/geometry/geometries/point.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
namespace strategy { namespace centroid
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename Type, std::size_t DimensionCount>
|
||||
struct weighted_length_sums
|
||||
{
|
||||
typedef typename geometry::model::point
|
||||
<
|
||||
Type, DimensionCount,
|
||||
cs::cartesian
|
||||
> work_point;
|
||||
|
||||
Type length;
|
||||
work_point average_sum;
|
||||
|
||||
inline weighted_length_sums()
|
||||
: length(Type())
|
||||
{
|
||||
geometry::assign_zero(average_sum);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template
|
||||
<
|
||||
typename Point,
|
||||
typename PointOfSegment = Point
|
||||
>
|
||||
class weighted_length
|
||||
{
|
||||
private :
|
||||
typedef typename select_most_precise
|
||||
<
|
||||
typename default_distance_result<Point>::type,
|
||||
typename default_distance_result<PointOfSegment>::type
|
||||
>::type distance_type;
|
||||
|
||||
public :
|
||||
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)
|
||||
{
|
||||
distance_type const d = geometry::distance(p1, p2);
|
||||
state.length += d;
|
||||
|
||||
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)
|
||||
{
|
||||
distance_type const zero = distance_type();
|
||||
if (! geometry::math::equals(state.length, zero))
|
||||
{
|
||||
assign_zero(centroid);
|
||||
add_point(centroid, state.average_sum);
|
||||
divide_value(centroid, state.length);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
|
||||
|
||||
namespace services
|
||||
{
|
||||
|
||||
|
||||
// Register this strategy for linear geometries, in all dimensions
|
||||
|
||||
template <std::size_t N, typename Point, typename Geometry>
|
||||
struct default_strategy
|
||||
<
|
||||
cartesian_tag,
|
||||
linear_tag,
|
||||
N,
|
||||
Point,
|
||||
Geometry
|
||||
>
|
||||
{
|
||||
typedef weighted_length
|
||||
<
|
||||
Point,
|
||||
typename point_type<Geometry>::type
|
||||
> type;
|
||||
};
|
||||
|
||||
|
||||
} // namespace services
|
||||
|
||||
|
||||
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
|
||||
|
||||
|
||||
}} // namespace strategy::centroid
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_CENTROID_WEIGHTED_LENGTH_HPP
|
||||
315
test/external/boost/geometry/strategies/cartesian/distance_projected_point.hpp
vendored
Normal file
315
test/external/boost/geometry/strategies/cartesian/distance_projected_point.hpp
vendored
Normal file
@@ -0,0 +1,315 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PROJECTED_POINT_HPP
|
||||
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PROJECTED_POINT_HPP
|
||||
|
||||
|
||||
#include <boost/concept_check.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/point_type.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/convert.hpp>
|
||||
#include <boost/geometry/arithmetic/arithmetic.hpp>
|
||||
#include <boost/geometry/arithmetic/dot_product.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/tags.hpp>
|
||||
#include <boost/geometry/strategies/distance.hpp>
|
||||
#include <boost/geometry/strategies/default_distance_result.hpp>
|
||||
#include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
|
||||
|
||||
#include <boost/geometry/util/select_coordinate_type.hpp>
|
||||
|
||||
// Helper geometry (projected point on line)
|
||||
#include <boost/geometry/geometries/point.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
namespace strategy { namespace distance
|
||||
{
|
||||
|
||||
|
||||
/*!
|
||||
\brief Strategy for distance point to segment
|
||||
\ingroup strategies
|
||||
\details Calculates distance using projected-point method, and (optionally) Pythagoras
|
||||
\author Adapted from: http://geometryalgorithms.com/Archive/algorithm_0102/algorithm_0102.htm
|
||||
\tparam Point \tparam_point
|
||||
\tparam PointOfSegment \tparam_segment_point
|
||||
\tparam CalculationType \tparam_calculation
|
||||
\tparam Strategy underlying point-point distance strategy
|
||||
\par Concepts for Strategy:
|
||||
- cartesian_distance operator(Point,Point)
|
||||
\note If the Strategy is a "comparable::pythagoras", this strategy
|
||||
automatically is a comparable projected_point strategy (so without sqrt)
|
||||
|
||||
\qbk{
|
||||
[heading See also]
|
||||
[link geometry.reference.algorithms.distance.distance_3_with_strategy distance (with strategy)]
|
||||
}
|
||||
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename Point,
|
||||
typename PointOfSegment = Point,
|
||||
typename CalculationType = void,
|
||||
typename Strategy = pythagoras<Point, PointOfSegment, CalculationType>
|
||||
>
|
||||
class projected_point
|
||||
{
|
||||
public :
|
||||
typedef typename strategy::distance::services::return_type<Strategy>::type calculation_type;
|
||||
|
||||
private :
|
||||
|
||||
// The three typedefs below are necessary to calculate distances
|
||||
// from segments defined in integer coordinates.
|
||||
|
||||
// Integer coordinates can still result in FP distances.
|
||||
// There is a division, which must be represented in FP.
|
||||
// So promote.
|
||||
typedef typename promote_floating_point<calculation_type>::type fp_type;
|
||||
|
||||
// A projected point of points in Integer coordinates must be able to be
|
||||
// represented in FP.
|
||||
typedef model::point
|
||||
<
|
||||
fp_type,
|
||||
dimension<PointOfSegment>::value,
|
||||
typename coordinate_system<PointOfSegment>::type
|
||||
> fp_point_type;
|
||||
|
||||
// For convenience
|
||||
typedef fp_point_type fp_vector_type;
|
||||
|
||||
// We have to use a strategy using FP coordinates (fp-type) which is
|
||||
// not always the same as Strategy (defined as point_strategy_type)
|
||||
// So we create a "similar" one
|
||||
typedef typename strategy::distance::services::similar_type
|
||||
<
|
||||
Strategy,
|
||||
Point,
|
||||
fp_point_type
|
||||
>::type fp_strategy_type;
|
||||
|
||||
public :
|
||||
|
||||
inline calculation_type apply(Point const& p,
|
||||
PointOfSegment const& p1, PointOfSegment const& p2) const
|
||||
{
|
||||
assert_dimension_equal<Point, PointOfSegment>();
|
||||
|
||||
/*
|
||||
Algorithm [p1: (x1,y1), p2: (x2,y2), p: (px,py)]
|
||||
VECTOR v(x2 - x1, y2 - y1)
|
||||
VECTOR w(px - x1, py - y1)
|
||||
c1 = w . v
|
||||
c2 = v . v
|
||||
b = c1 / c2
|
||||
RETURN POINT(x1 + b * vx, y1 + b * vy)
|
||||
*/
|
||||
|
||||
// v is multiplied below with a (possibly) FP-value, so should be in FP
|
||||
// For consistency we define w also in FP
|
||||
fp_vector_type v, w;
|
||||
|
||||
geometry::convert(p2, v);
|
||||
geometry::convert(p, w);
|
||||
subtract_point(v, p1);
|
||||
subtract_point(w, p1);
|
||||
|
||||
Strategy strategy;
|
||||
boost::ignore_unused_variable_warning(strategy);
|
||||
|
||||
calculation_type const zero = calculation_type();
|
||||
fp_type const c1 = dot_product(w, v);
|
||||
if (c1 <= zero)
|
||||
{
|
||||
return strategy.apply(p, p1);
|
||||
}
|
||||
fp_type const c2 = dot_product(v, v);
|
||||
if (c2 <= c1)
|
||||
{
|
||||
return strategy.apply(p, p2);
|
||||
}
|
||||
|
||||
// See above, c1 > 0 AND c2 > c1 so: c2 != 0
|
||||
fp_type const b = c1 / c2;
|
||||
|
||||
fp_strategy_type fp_strategy
|
||||
= strategy::distance::services::get_similar
|
||||
<
|
||||
Strategy, Point, fp_point_type
|
||||
>::apply(strategy);
|
||||
|
||||
fp_point_type projected;
|
||||
geometry::convert(p1, projected);
|
||||
multiply_value(v, b);
|
||||
add_point(projected, v);
|
||||
|
||||
//std::cout << "distance " << dsv(p) << " .. " << dsv(projected) << std::endl;
|
||||
|
||||
return fp_strategy.apply(p, projected);
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
|
||||
namespace services
|
||||
{
|
||||
|
||||
template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
|
||||
struct tag<projected_point<Point, PointOfSegment, CalculationType, Strategy> >
|
||||
{
|
||||
typedef strategy_tag_distance_point_segment type;
|
||||
};
|
||||
|
||||
|
||||
template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
|
||||
struct return_type<projected_point<Point, PointOfSegment, CalculationType, Strategy> >
|
||||
{
|
||||
typedef typename projected_point<Point, PointOfSegment, CalculationType, Strategy>::calculation_type type;
|
||||
};
|
||||
|
||||
template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
|
||||
struct strategy_point_point<projected_point<Point, PointOfSegment, CalculationType, Strategy> >
|
||||
{
|
||||
typedef Strategy type;
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Point,
|
||||
typename PointOfSegment,
|
||||
typename CalculationType,
|
||||
typename Strategy,
|
||||
typename P1,
|
||||
typename P2
|
||||
>
|
||||
struct similar_type<projected_point<Point, PointOfSegment, CalculationType, Strategy>, P1, P2>
|
||||
{
|
||||
typedef projected_point<P1, P2, CalculationType, Strategy> type;
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Point,
|
||||
typename PointOfSegment,
|
||||
typename CalculationType,
|
||||
typename Strategy,
|
||||
typename P1,
|
||||
typename P2
|
||||
>
|
||||
struct get_similar<projected_point<Point, PointOfSegment, CalculationType, Strategy>, P1, P2>
|
||||
{
|
||||
static inline typename similar_type
|
||||
<
|
||||
projected_point<Point, PointOfSegment, CalculationType, Strategy>, P1, P2
|
||||
>::type apply(projected_point<Point, PointOfSegment, CalculationType, Strategy> const& )
|
||||
{
|
||||
return projected_point<P1, P2, CalculationType, Strategy>();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
|
||||
struct comparable_type<projected_point<Point, PointOfSegment, CalculationType, Strategy> >
|
||||
{
|
||||
// Define a projected_point strategy with its underlying point-point-strategy
|
||||
// being comparable
|
||||
typedef projected_point
|
||||
<
|
||||
Point,
|
||||
PointOfSegment,
|
||||
CalculationType,
|
||||
typename comparable_type<Strategy>::type
|
||||
> type;
|
||||
};
|
||||
|
||||
|
||||
template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
|
||||
struct get_comparable<projected_point<Point, PointOfSegment, CalculationType, Strategy> >
|
||||
{
|
||||
typedef typename comparable_type
|
||||
<
|
||||
projected_point<Point, PointOfSegment, CalculationType, Strategy>
|
||||
>::type comparable_type;
|
||||
public :
|
||||
static inline comparable_type apply(projected_point<Point, PointOfSegment, CalculationType, Strategy> const& )
|
||||
{
|
||||
return comparable_type();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Point, typename PointOfSegment, typename CalculationType, typename Strategy>
|
||||
struct result_from_distance<projected_point<Point, PointOfSegment, CalculationType, Strategy> >
|
||||
{
|
||||
private :
|
||||
typedef typename return_type<projected_point<Point, PointOfSegment, CalculationType, Strategy> >::type return_type;
|
||||
public :
|
||||
template <typename T>
|
||||
static inline return_type apply(projected_point<Point, PointOfSegment, CalculationType, Strategy> const& , T const& value)
|
||||
{
|
||||
Strategy s;
|
||||
return result_from_distance<Strategy>::apply(s, value);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Get default-strategy for point-segment distance calculation
|
||||
// while still have the possibility to specify point-point distance strategy (PPS)
|
||||
// It is used in algorithms/distance.hpp where users specify PPS for distance
|
||||
// of point-to-segment or point-to-linestring.
|
||||
// Convenient for geographic coordinate systems especially.
|
||||
template <typename Point, typename PointOfSegment, typename Strategy>
|
||||
struct default_strategy<segment_tag, Point, PointOfSegment, cartesian_tag, cartesian_tag, Strategy>
|
||||
{
|
||||
typedef strategy::distance::projected_point
|
||||
<
|
||||
Point,
|
||||
PointOfSegment,
|
||||
void,
|
||||
typename boost::mpl::if_
|
||||
<
|
||||
boost::is_void<Strategy>,
|
||||
typename default_strategy
|
||||
<
|
||||
point_tag, Point, PointOfSegment,
|
||||
cartesian_tag, cartesian_tag
|
||||
>::type,
|
||||
Strategy
|
||||
>::type
|
||||
> type;
|
||||
};
|
||||
|
||||
|
||||
} // namespace services
|
||||
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
|
||||
|
||||
|
||||
}} // namespace strategy::distance
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PROJECTED_POINT_HPP
|
||||
345
test/external/boost/geometry/strategies/cartesian/distance_pythagoras.hpp
vendored
Normal file
345
test/external/boost/geometry/strategies/cartesian/distance_pythagoras.hpp
vendored
Normal file
@@ -0,0 +1,345 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2008-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP
|
||||
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP
|
||||
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/distance.hpp>
|
||||
|
||||
#include <boost/geometry/util/select_calculation_type.hpp>
|
||||
#include <boost/geometry/util/promote_floating_point.hpp>
|
||||
|
||||
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
namespace strategy { namespace distance
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename Point1, typename Point2, size_t I, typename T>
|
||||
struct compute_pythagoras
|
||||
{
|
||||
static inline T apply(Point1 const& p1, Point2 const& p2)
|
||||
{
|
||||
T const c1 = boost::numeric_cast<T>(get<I-1>(p2));
|
||||
T const c2 = boost::numeric_cast<T>(get<I-1>(p1));
|
||||
T const d = c1 - c2;
|
||||
return d * d + compute_pythagoras<Point1, Point2, I-1, T>::apply(p1, p2);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Point1, typename Point2, typename T>
|
||||
struct compute_pythagoras<Point1, Point2, 0, T>
|
||||
{
|
||||
static inline T apply(Point1 const&, Point2 const&)
|
||||
{
|
||||
return boost::numeric_cast<T>(0);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
namespace comparable
|
||||
{
|
||||
|
||||
/*!
|
||||
\brief Strategy to calculate comparable distance between two points
|
||||
\ingroup strategies
|
||||
\tparam Point1 \tparam_first_point
|
||||
\tparam Point2 \tparam_second_point
|
||||
\tparam CalculationType \tparam_calculation
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename Point1,
|
||||
typename Point2 = Point1,
|
||||
typename CalculationType = void
|
||||
>
|
||||
class pythagoras
|
||||
{
|
||||
public :
|
||||
typedef typename select_calculation_type
|
||||
<
|
||||
Point1,
|
||||
Point2,
|
||||
CalculationType
|
||||
>::type calculation_type;
|
||||
|
||||
static inline calculation_type apply(Point1 const& p1, Point2 const& p2)
|
||||
{
|
||||
BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point1>) );
|
||||
BOOST_CONCEPT_ASSERT( (concept::ConstPoint<Point2>) );
|
||||
|
||||
// Calculate distance using Pythagoras
|
||||
// (Leave comment above for Doxygen)
|
||||
|
||||
assert_dimension_equal<Point1, Point2>();
|
||||
|
||||
return detail::compute_pythagoras
|
||||
<
|
||||
Point1, Point2,
|
||||
dimension<Point1>::value,
|
||||
calculation_type
|
||||
>::apply(p1, p2);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace comparable
|
||||
|
||||
|
||||
/*!
|
||||
\brief Strategy to calculate the distance between two points
|
||||
\ingroup strategies
|
||||
\tparam Point1 \tparam_first_point
|
||||
\tparam Point2 \tparam_second_point
|
||||
\tparam CalculationType \tparam_calculation
|
||||
|
||||
\qbk{
|
||||
[heading Notes]
|
||||
[note Can be used for points with two\, three or more dimensions]
|
||||
[heading See also]
|
||||
[link geometry.reference.algorithms.distance.distance_3_with_strategy distance (with strategy)]
|
||||
}
|
||||
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename Point1,
|
||||
typename Point2 = Point1,
|
||||
typename CalculationType = void
|
||||
>
|
||||
class pythagoras
|
||||
{
|
||||
typedef comparable::pythagoras<Point1, Point2, CalculationType> comparable_type;
|
||||
public :
|
||||
typedef typename promote_floating_point
|
||||
<
|
||||
typename services::return_type<comparable_type>::type
|
||||
>::type calculation_type;
|
||||
|
||||
/*!
|
||||
\brief applies the distance calculation using pythagoras
|
||||
\return the calculated distance (including taking the square root)
|
||||
\param p1 first point
|
||||
\param p2 second point
|
||||
*/
|
||||
static inline calculation_type apply(Point1 const& p1, Point2 const& p2)
|
||||
{
|
||||
calculation_type const t = comparable_type::apply(p1, p2);
|
||||
return sqrt(t);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
|
||||
namespace services
|
||||
{
|
||||
|
||||
template <typename Point1, typename Point2, typename CalculationType>
|
||||
struct tag<pythagoras<Point1, Point2, CalculationType> >
|
||||
{
|
||||
typedef strategy_tag_distance_point_point type;
|
||||
};
|
||||
|
||||
|
||||
template <typename Point1, typename Point2, typename CalculationType>
|
||||
struct return_type<pythagoras<Point1, Point2, CalculationType> >
|
||||
{
|
||||
typedef typename pythagoras<Point1, Point2, CalculationType>::calculation_type type;
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Point1,
|
||||
typename Point2,
|
||||
typename CalculationType,
|
||||
typename P1,
|
||||
typename P2
|
||||
>
|
||||
struct similar_type<pythagoras<Point1, Point2, CalculationType>, P1, P2>
|
||||
{
|
||||
typedef pythagoras<P1, P2, CalculationType> type;
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Point1,
|
||||
typename Point2,
|
||||
typename CalculationType,
|
||||
typename P1,
|
||||
typename P2
|
||||
>
|
||||
struct get_similar<pythagoras<Point1, Point2, CalculationType>, P1, P2>
|
||||
{
|
||||
static inline typename similar_type
|
||||
<
|
||||
pythagoras<Point1, Point2, CalculationType>, P1, P2
|
||||
>::type apply(pythagoras<Point1, Point2, CalculationType> const& )
|
||||
{
|
||||
return pythagoras<P1, P2, CalculationType>();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Point1, typename Point2, typename CalculationType>
|
||||
struct comparable_type<pythagoras<Point1, Point2, CalculationType> >
|
||||
{
|
||||
typedef comparable::pythagoras<Point1, Point2, CalculationType> type;
|
||||
};
|
||||
|
||||
|
||||
template <typename Point1, typename Point2, typename CalculationType>
|
||||
struct get_comparable<pythagoras<Point1, Point2, CalculationType> >
|
||||
{
|
||||
typedef comparable::pythagoras<Point1, Point2, CalculationType> comparable_type;
|
||||
public :
|
||||
static inline comparable_type apply(pythagoras<Point1, Point2, CalculationType> const& input)
|
||||
{
|
||||
return comparable_type();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Point1, typename Point2, typename CalculationType>
|
||||
struct result_from_distance<pythagoras<Point1, Point2, CalculationType> >
|
||||
{
|
||||
private :
|
||||
typedef typename return_type<pythagoras<Point1, Point2, CalculationType> >::type return_type;
|
||||
public :
|
||||
template <typename T>
|
||||
static inline return_type apply(pythagoras<Point1, Point2, CalculationType> const& , T const& value)
|
||||
{
|
||||
return return_type(value);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Specializations for comparable::pythagoras
|
||||
template <typename Point1, typename Point2, typename CalculationType>
|
||||
struct tag<comparable::pythagoras<Point1, Point2, CalculationType> >
|
||||
{
|
||||
typedef strategy_tag_distance_point_point type;
|
||||
};
|
||||
|
||||
|
||||
template <typename Point1, typename Point2, typename CalculationType>
|
||||
struct return_type<comparable::pythagoras<Point1, Point2, CalculationType> >
|
||||
{
|
||||
typedef typename comparable::pythagoras<Point1, Point2, CalculationType>::calculation_type type;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Point1,
|
||||
typename Point2,
|
||||
typename CalculationType,
|
||||
typename P1,
|
||||
typename P2
|
||||
>
|
||||
struct similar_type<comparable::pythagoras<Point1, Point2, CalculationType>, P1, P2>
|
||||
{
|
||||
typedef comparable::pythagoras<P1, P2, CalculationType> type;
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Point1,
|
||||
typename Point2,
|
||||
typename CalculationType,
|
||||
typename P1,
|
||||
typename P2
|
||||
>
|
||||
struct get_similar<comparable::pythagoras<Point1, Point2, CalculationType>, P1, P2>
|
||||
{
|
||||
static inline typename similar_type
|
||||
<
|
||||
comparable::pythagoras<Point1, Point2, CalculationType>, P1, P2
|
||||
>::type apply(comparable::pythagoras<Point1, Point2, CalculationType> const& )
|
||||
{
|
||||
return comparable::pythagoras<P1, P2, CalculationType>();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Point1, typename Point2, typename CalculationType>
|
||||
struct comparable_type<comparable::pythagoras<Point1, Point2, CalculationType> >
|
||||
{
|
||||
typedef comparable::pythagoras<Point1, Point2, CalculationType> type;
|
||||
};
|
||||
|
||||
|
||||
template <typename Point1, typename Point2, typename CalculationType>
|
||||
struct get_comparable<comparable::pythagoras<Point1, Point2, CalculationType> >
|
||||
{
|
||||
typedef comparable::pythagoras<Point1, Point2, CalculationType> comparable_type;
|
||||
public :
|
||||
static inline comparable_type apply(comparable::pythagoras<Point1, Point2, CalculationType> const& input)
|
||||
{
|
||||
return comparable_type();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Point1, typename Point2, typename CalculationType>
|
||||
struct result_from_distance<comparable::pythagoras<Point1, Point2, CalculationType> >
|
||||
{
|
||||
private :
|
||||
typedef typename return_type<comparable::pythagoras<Point1, Point2, CalculationType> >::type return_type;
|
||||
public :
|
||||
template <typename T>
|
||||
static inline return_type apply(comparable::pythagoras<Point1, Point2, CalculationType> const& , T const& value)
|
||||
{
|
||||
return_type const v = value;
|
||||
return v * v;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Point1, typename Point2>
|
||||
struct default_strategy<point_tag, Point1, Point2, cartesian_tag, cartesian_tag, void>
|
||||
{
|
||||
typedef pythagoras<Point1, Point2> type;
|
||||
};
|
||||
|
||||
|
||||
} // namespace services
|
||||
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
|
||||
|
||||
|
||||
}} // namespace strategy::distance
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISTANCE_PYTHAGORAS_HPP
|
||||
172
test/external/boost/geometry/strategies/cartesian/point_in_box.hpp
vendored
Normal file
172
test/external/boost/geometry/strategies/cartesian/point_in_box.hpp
vendored
Normal file
@@ -0,0 +1,172 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_BOX_HPP
|
||||
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_BOX_HPP
|
||||
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/strategies/covered_by.hpp>
|
||||
#include <boost/geometry/strategies/within.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry { namespace strategy
|
||||
{
|
||||
|
||||
namespace within
|
||||
{
|
||||
|
||||
|
||||
struct within_range
|
||||
{
|
||||
template <typename Value1, typename Value2>
|
||||
static inline bool apply(Value1 const& value, Value2 const& min_value, Value2 const& max_value)
|
||||
{
|
||||
return value > min_value && value < max_value;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct covered_by_range
|
||||
{
|
||||
template <typename Value1, typename Value2>
|
||||
static inline bool apply(Value1 const& value, Value2 const& min_value, Value2 const& max_value)
|
||||
{
|
||||
return value >= min_value && value <= max_value;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename SubStrategy,
|
||||
typename Point,
|
||||
typename Box,
|
||||
std::size_t Dimension,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct relate_point_box_loop
|
||||
{
|
||||
static inline bool apply(Point const& point, Box const& box)
|
||||
{
|
||||
if (! SubStrategy::apply(get<Dimension>(point),
|
||||
get<min_corner, Dimension>(box),
|
||||
get<max_corner, Dimension>(box))
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return relate_point_box_loop
|
||||
<
|
||||
SubStrategy,
|
||||
Point, Box,
|
||||
Dimension + 1, DimensionCount
|
||||
>::apply(point, box);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename SubStrategy,
|
||||
typename Point,
|
||||
typename Box,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct relate_point_box_loop<SubStrategy, Point, Box, DimensionCount, DimensionCount>
|
||||
{
|
||||
static inline bool apply(Point const& , Box const& )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Point,
|
||||
typename Box,
|
||||
typename SubStrategy = within_range
|
||||
>
|
||||
struct point_in_box
|
||||
{
|
||||
static inline bool apply(Point const& point, Box const& box)
|
||||
{
|
||||
return relate_point_box_loop
|
||||
<
|
||||
SubStrategy,
|
||||
Point, Box,
|
||||
0, dimension<Point>::type::value
|
||||
>::apply(point, box);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace within
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
|
||||
|
||||
|
||||
namespace within { namespace services
|
||||
{
|
||||
|
||||
template <typename Point, typename Box>
|
||||
struct default_strategy
|
||||
<
|
||||
point_tag, box_tag,
|
||||
point_tag, areal_tag,
|
||||
cartesian_tag, cartesian_tag,
|
||||
Point, Box
|
||||
>
|
||||
{
|
||||
typedef within::point_in_box<Point, Box> type;
|
||||
};
|
||||
|
||||
|
||||
}} // namespace within::services
|
||||
|
||||
|
||||
namespace covered_by { namespace services
|
||||
{
|
||||
|
||||
|
||||
template <typename Point, typename Box>
|
||||
struct default_strategy
|
||||
<
|
||||
point_tag, box_tag,
|
||||
point_tag, areal_tag,
|
||||
cartesian_tag, cartesian_tag,
|
||||
Point, Box
|
||||
>
|
||||
{
|
||||
typedef within::point_in_box
|
||||
<
|
||||
Point, Box,
|
||||
within::covered_by_range
|
||||
> type;
|
||||
};
|
||||
|
||||
|
||||
}} // namespace covered_by::services
|
||||
|
||||
|
||||
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
|
||||
|
||||
|
||||
}}} // namespace boost::geometry::strategy
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_BOX_HPP
|
||||
124
test/external/boost/geometry/strategies/cartesian/point_in_poly_crossings_multiply.hpp
vendored
Normal file
124
test/external/boost/geometry/strategies/cartesian/point_in_poly_crossings_multiply.hpp
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_POLY_CROSSINGS_MULTIPLY_HPP
|
||||
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_POLY_CROSSINGS_MULTIPLY_HPP
|
||||
|
||||
|
||||
#include <boost/geometry/core/coordinate_type.hpp>
|
||||
#include <boost/geometry/util/select_calculation_type.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
namespace strategy { namespace within
|
||||
{
|
||||
|
||||
/*!
|
||||
\brief Within detection using cross counting,
|
||||
\ingroup strategies
|
||||
\tparam Point \tparam_point
|
||||
\tparam PointOfSegment \tparam_segment_point
|
||||
\tparam CalculationType \tparam_calculation
|
||||
\see http://tog.acm.org/resources/GraphicsGems/gemsiv/ptpoly_haines/ptinpoly.c
|
||||
\note Does NOT work correctly for point ON border
|
||||
\qbk{
|
||||
[heading See also]
|
||||
[link geometry.reference.algorithms.within.within_3_with_strategy within (with strategy)]
|
||||
}
|
||||
*/
|
||||
|
||||
template
|
||||
<
|
||||
typename Point,
|
||||
typename PointOfSegment = Point,
|
||||
typename CalculationType = void
|
||||
>
|
||||
class crossings_multiply
|
||||
{
|
||||
typedef typename select_calculation_type
|
||||
<
|
||||
Point,
|
||||
PointOfSegment,
|
||||
CalculationType
|
||||
>::type calculation_type;
|
||||
|
||||
class flags
|
||||
{
|
||||
bool inside_flag;
|
||||
bool first;
|
||||
bool yflag0;
|
||||
|
||||
public :
|
||||
|
||||
friend class crossings_multiply;
|
||||
|
||||
inline flags()
|
||||
: inside_flag(false)
|
||||
, first(true)
|
||||
, yflag0(false)
|
||||
{}
|
||||
};
|
||||
|
||||
public :
|
||||
|
||||
typedef Point point_type;
|
||||
typedef PointOfSegment segment_point_type;
|
||||
typedef flags state_type;
|
||||
|
||||
static inline bool apply(Point const& point,
|
||||
PointOfSegment const& seg1, PointOfSegment const& seg2,
|
||||
flags& state)
|
||||
{
|
||||
calculation_type const tx = get<0>(point);
|
||||
calculation_type const ty = get<1>(point);
|
||||
calculation_type const x0 = get<0>(seg1);
|
||||
calculation_type const y0 = get<1>(seg1);
|
||||
calculation_type const x1 = get<0>(seg2);
|
||||
calculation_type const y1 = get<1>(seg2);
|
||||
|
||||
if (state.first)
|
||||
{
|
||||
state.first = false;
|
||||
state.yflag0 = y0 >= ty;
|
||||
}
|
||||
|
||||
|
||||
bool yflag1 = y1 >= ty;
|
||||
if (state.yflag0 != yflag1)
|
||||
{
|
||||
if ( ((y1-ty) * (x0-x1) >= (x1-tx) * (y0-y1)) == yflag1 )
|
||||
{
|
||||
state.inside_flag = ! state.inside_flag;
|
||||
}
|
||||
}
|
||||
state.yflag0 = yflag1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline int result(flags const& state)
|
||||
{
|
||||
return state.inside_flag ? 1 : -1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
}} // namespace strategy::within
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_POLY_CROSSINGS_MULTIPLY_HPP
|
||||
118
test/external/boost/geometry/strategies/cartesian/point_in_poly_franklin.hpp
vendored
Normal file
118
test/external/boost/geometry/strategies/cartesian/point_in_poly_franklin.hpp
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_POLY_FRANKLIN_HPP
|
||||
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_POLY_FRANKLIN_HPP
|
||||
|
||||
|
||||
#include <boost/geometry/core/coordinate_type.hpp>
|
||||
#include <boost/geometry/util/select_calculation_type.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
namespace strategy { namespace within
|
||||
{
|
||||
|
||||
/*!
|
||||
\brief Within detection using cross counting
|
||||
\ingroup strategies
|
||||
\tparam Point \tparam_point
|
||||
\tparam PointOfSegment \tparam_segment_point
|
||||
\tparam CalculationType \tparam_calculation
|
||||
\author adapted from Randolph Franklin algorithm
|
||||
\author Barend and Maarten, 1995
|
||||
\author Revised for templatized library, Barend Gehrels, 2007
|
||||
\return true if point is in ring, works for closed rings in both directions
|
||||
\note Does NOT work correctly for point ON border
|
||||
|
||||
\qbk{
|
||||
[heading See also]
|
||||
[link geometry.reference.algorithms.within.within_3_with_strategy within (with strategy)]
|
||||
}
|
||||
*/
|
||||
|
||||
template
|
||||
<
|
||||
typename Point,
|
||||
typename PointOfSegment = Point,
|
||||
typename CalculationType = void
|
||||
>
|
||||
class franklin
|
||||
{
|
||||
typedef typename select_calculation_type
|
||||
<
|
||||
Point,
|
||||
PointOfSegment,
|
||||
CalculationType
|
||||
>::type calculation_type;
|
||||
|
||||
/*! subclass to keep state */
|
||||
class crossings
|
||||
{
|
||||
bool crosses;
|
||||
|
||||
public :
|
||||
|
||||
friend class franklin;
|
||||
inline crossings()
|
||||
: crosses(false)
|
||||
{}
|
||||
};
|
||||
|
||||
public :
|
||||
|
||||
typedef Point point_type;
|
||||
typedef PointOfSegment segment_point_type;
|
||||
typedef crossings state_type;
|
||||
|
||||
static inline bool apply(Point const& point,
|
||||
PointOfSegment const& seg1, PointOfSegment const& seg2,
|
||||
crossings& state)
|
||||
{
|
||||
calculation_type const& px = get<0>(point);
|
||||
calculation_type const& py = get<1>(point);
|
||||
calculation_type const& x1 = get<0>(seg1);
|
||||
calculation_type const& y1 = get<1>(seg1);
|
||||
calculation_type const& x2 = get<0>(seg2);
|
||||
calculation_type const& y2 = get<1>(seg2);
|
||||
|
||||
if (
|
||||
( (y2 <= py && py < y1) || (y1 <= py && py < y2) )
|
||||
&& (px < (x1 - x2) * (py - y2) / (y1 - y2) + x2)
|
||||
)
|
||||
{
|
||||
state.crosses = ! state.crosses;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline int result(crossings const& state)
|
||||
{
|
||||
return state.crosses ? 1 : -1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
}} // namespace strategy::within
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_POINT_IN_POLY_FRANKLIN_HPP
|
||||
118
test/external/boost/geometry/strategies/cartesian/side_by_triangle.hpp
vendored
Normal file
118
test/external/boost/geometry/strategies/cartesian/side_by_triangle.hpp
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2011 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2011 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2011 Mateusz Loskot, London, UK.
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_SIDE_BY_TRIANGLE_HPP
|
||||
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_SIDE_BY_TRIANGLE_HPP
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
|
||||
#include <boost/geometry/util/select_coordinate_type.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/side.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
namespace strategy { namespace side
|
||||
{
|
||||
|
||||
/*!
|
||||
\brief Check at which side of a segment a point lies:
|
||||
left of segment (> 0), right of segment (< 0), on segment (0)
|
||||
\ingroup strategies
|
||||
\tparam CalculationType \tparam_calculation
|
||||
*/
|
||||
template <typename CalculationType = void>
|
||||
class side_by_triangle
|
||||
{
|
||||
public :
|
||||
|
||||
// Template member function, because it is not always trivial
|
||||
// or convenient to explicitly mention the typenames in the
|
||||
// strategy-struct itself.
|
||||
|
||||
// Types can be all three different. Therefore it is
|
||||
// not implemented (anymore) as "segment"
|
||||
|
||||
template <typename P1, typename P2, typename P>
|
||||
static inline int apply(P1 const& p1, P2 const& p2, P const& p)
|
||||
{
|
||||
typedef typename boost::mpl::if_c
|
||||
<
|
||||
boost::is_void<CalculationType>::type::value,
|
||||
typename select_most_precise
|
||||
<
|
||||
typename select_most_precise
|
||||
<
|
||||
typename coordinate_type<P1>::type,
|
||||
typename coordinate_type<P2>::type
|
||||
>::type,
|
||||
typename coordinate_type<P>::type
|
||||
>::type,
|
||||
CalculationType
|
||||
>::type coordinate_type;
|
||||
|
||||
//std::cout << "side: " << typeid(coordinate_type).name() << std::endl;
|
||||
coordinate_type const x = get<0>(p);
|
||||
coordinate_type const y = get<1>(p);
|
||||
|
||||
coordinate_type const sx1 = get<0>(p1);
|
||||
coordinate_type const sy1 = get<1>(p1);
|
||||
coordinate_type const sx2 = get<0>(p2);
|
||||
coordinate_type const sy2 = get<1>(p2);
|
||||
|
||||
// Promote float->double, small int->int
|
||||
typedef typename select_most_precise
|
||||
<
|
||||
coordinate_type,
|
||||
double
|
||||
>::type promoted_type;
|
||||
|
||||
promoted_type const dx = sx2 - sx1;
|
||||
promoted_type const dy = sy2 - sy1;
|
||||
promoted_type const dpx = x - sx1;
|
||||
promoted_type const dpy = y - sy1;
|
||||
|
||||
promoted_type const s = dx * dpy - dy * dpx;
|
||||
|
||||
promoted_type const zero = promoted_type();
|
||||
return math::equals(s, zero) ? 0
|
||||
: s > zero ? 1
|
||||
: -1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
|
||||
namespace services
|
||||
{
|
||||
|
||||
template <typename CalculationType>
|
||||
struct default_strategy<cartesian_tag, CalculationType>
|
||||
{
|
||||
typedef side_by_triangle<CalculationType> type;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
}} // namespace strategy::side
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_SIDE_BY_TRIANGLE_HPP
|
||||
Reference in New Issue
Block a user