IP coordinates rounded to the nearest value instead of a cast in segments_intersection_points if coordinate_type is integer

This commit is contained in:
Adam Wulkiewicz
2014-02-24 15:16:37 +01:00
parent a68d9f5855
commit 7033337149

View File

@@ -22,13 +22,42 @@
#include <boost/geometry/util/select_calculation_type.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
namespace boost { namespace geometry
{
namespace policies { namespace relate
{
template <typename Result, bool IsInteger = std::numeric_limits<Result>::is_integer>
struct round_dispatch
{
template <typename T>
static inline Result apply(T const& v)
{
return v < 0 ?
boost::numeric_cast<Result>(ceil(v - 0.5f)) :
boost::numeric_cast<Result>(floor(v + 0.5f));
}
};
template <typename Result>
struct round_dispatch<Result, false>
{
template <typename T>
static inline Result apply(T const& v)
{
return boost::numeric_cast<Result>(v);
}
};
template <typename Result, typename T>
inline Result round(T const& v)
{
// NOTE: boost::round() could be used instead but it throws in some situations
//BOOST_STATIC_ASSERT(!std::numeric_limits<T>::is_integer);
return round_dispatch<Result>::apply(v);
}
template <typename S1, typename S2, typename ReturnType, typename CalculationType = void>
struct segments_intersection_points
@@ -60,9 +89,9 @@ struct segments_intersection_points
return_type result;
result.count = 1;
set<0>(result.intersections[0],
boost::numeric_cast<return_coordinate_type>(R(s1x) + r * R(dx1)));
round<return_coordinate_type>(R(s1x) + r * R(dx1)));
set<1>(result.intersections[0],
boost::numeric_cast<return_coordinate_type>(R(s1y) + r * R(dy1)));
round<return_coordinate_type>(R(s1y) + r * R(dy1)));
return result;
}