mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-11 11:52:11 +00:00
Fixed wrong behaviour for intersects/disjoint algorithms for pair of linestrings which were degenerate, or collinear, or one starting in the middle from the other.
Also removed the never-used parallel option. Throws an error at unexpected input (robustness errors) [SVN r76859]
This commit is contained in:
@@ -30,6 +30,9 @@ namespace detail { namespace overlay
|
||||
*/
|
||||
struct calculate_distance_policy
|
||||
{
|
||||
static bool const include_no_turn = false;
|
||||
static bool const include_degenerate = false;
|
||||
|
||||
template <typename Point1, typename Point2, typename Info>
|
||||
static inline void apply(Info& info, Point1 const& p1, Point2 const& p2)
|
||||
{
|
||||
|
||||
@@ -23,6 +23,25 @@
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#if ! defined(BOOST_GEOMETRY_OVERLAY_NO_THROW)
|
||||
class turn_info_exception : public geometry::exception
|
||||
{
|
||||
std::string message;
|
||||
public:
|
||||
|
||||
// NOTE: "char" will be replaced by enum in future version
|
||||
inline turn_info_exception(char const method)
|
||||
{
|
||||
message = "Boost.Geometry Turn exception: ";
|
||||
message += method;
|
||||
}
|
||||
|
||||
virtual char const* what() const throw()
|
||||
{
|
||||
return message.c_str();
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace overlay
|
||||
@@ -677,6 +696,18 @@ struct crosses : public base_turn_handler
|
||||
}
|
||||
};
|
||||
|
||||
template<typename TurnInfo>
|
||||
struct only_convert
|
||||
{
|
||||
template<typename IntersectionInfo>
|
||||
static inline void apply(TurnInfo& ti, IntersectionInfo const& intersection_info)
|
||||
{
|
||||
ti.method = method_collinear;
|
||||
geometry::convert(intersection_info.intersections[0], ti.point);
|
||||
ti.operations[0].operation = operation_continue;
|
||||
ti.operations[1].operation = operation_continue;
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
\brief Policy doing nothing
|
||||
@@ -686,6 +717,9 @@ struct crosses : public base_turn_handler
|
||||
*/
|
||||
struct assign_null_policy
|
||||
{
|
||||
static bool const include_no_turn = false;
|
||||
static bool const include_degenerate = false;
|
||||
|
||||
template <typename Point1, typename Point2, typename Info>
|
||||
static inline void apply(Info& , Point1 const& , Point2 const& )
|
||||
{}
|
||||
@@ -703,14 +737,16 @@ struct assign_null_policy
|
||||
\tparam TurnInfo type of class getting intersection and turn info
|
||||
\tparam AssignPolicy policy to assign extra info,
|
||||
e.g. to calculate distance from segment's first points
|
||||
to intersection points
|
||||
to intersection points.
|
||||
It also defines if a certain class of points
|
||||
(degenerate, non-turns) should be included.
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename Point1,
|
||||
typename Point2,
|
||||
typename TurnInfo,
|
||||
typename AssignPolicy = assign_null_policy
|
||||
typename AssignPolicy
|
||||
>
|
||||
struct get_turn_info
|
||||
{
|
||||
@@ -749,10 +785,20 @@ struct get_turn_info
|
||||
// Select method and apply
|
||||
switch(method)
|
||||
{
|
||||
case 'a' :
|
||||
case 'f' :
|
||||
case 's' :
|
||||
case 'd' :
|
||||
case 'a' : // collinear, "at"
|
||||
case 'f' : // collinear, "from"
|
||||
case 's' : // starts from the middle
|
||||
if (AssignPolicy::include_no_turn
|
||||
&& result.template get<0>().count > 0)
|
||||
{
|
||||
only_convert<TurnInfo>::apply(tp,
|
||||
result.template get<0>());
|
||||
AssignPolicy::apply(tp, pi, qi);
|
||||
*out++ = tp;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'd' : // disjoint: never do anything
|
||||
break;
|
||||
|
||||
case 'm' :
|
||||
@@ -873,13 +919,23 @@ struct get_turn_info
|
||||
}
|
||||
break;
|
||||
case '0' :
|
||||
// degenerate points
|
||||
break;
|
||||
{
|
||||
// degenerate points
|
||||
if (AssignPolicy::include_degenerate)
|
||||
{
|
||||
only_convert<TurnInfo>::apply(tp, result.template get<0>());
|
||||
AssignPolicy::apply(tp, pi, qi);
|
||||
*out++ = tp;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default :
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_GET_TURNS
|
||||
std::cout << "get_turns, nyi: " << method << std::endl;
|
||||
{
|
||||
#if ! defined(BOOST_GEOMETRY_OVERLAY_NO_THROW)
|
||||
throw turn_info_exception(method);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return out;
|
||||
|
||||
@@ -44,6 +44,19 @@ namespace boost { namespace geometry
|
||||
namespace detail { namespace disjoint
|
||||
{
|
||||
|
||||
struct assign_disjoint_policy
|
||||
{
|
||||
// We want to include all points:
|
||||
static bool const include_no_turn = true;
|
||||
static bool const include_degenerate = true;
|
||||
|
||||
// We don't assign extra info:
|
||||
template <typename Point1, typename Point2, typename Info>
|
||||
static inline void apply(Info& , Point1 const& , Point2 const& )
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct disjoint_linear
|
||||
{
|
||||
@@ -54,12 +67,14 @@ struct disjoint_linear
|
||||
typedef overlay::turn_info<point_type> turn_info;
|
||||
std::deque<turn_info> turns;
|
||||
|
||||
// Get (and stop on) any intersection
|
||||
// Specify two policies:
|
||||
// 1) Stop at any intersection
|
||||
// 2) In assignment, include also degenerate points (which are normally skipped)
|
||||
disjoint_interrupt_policy policy;
|
||||
geometry::get_turns
|
||||
<
|
||||
false, false,
|
||||
overlay::assign_null_policy
|
||||
false, false,
|
||||
assign_disjoint_policy
|
||||
>(geometry1, geometry2, turns, policy);
|
||||
if (policy.has_intersections)
|
||||
{
|
||||
|
||||
@@ -167,14 +167,6 @@ struct segments_de9im
|
||||
true);
|
||||
}
|
||||
|
||||
|
||||
static inline return_type parallel()
|
||||
{
|
||||
return de9im_segment(0,0,
|
||||
-1, -1, 1,
|
||||
-1, -1, 0,
|
||||
1, 0, 2, false, false, true);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@ namespace policies { namespace relate
|
||||
|
||||
struct direction_type
|
||||
{
|
||||
// NOTE: "char" will be replaced by enum in future version
|
||||
|
||||
inline direction_type(side_info const& s, char h,
|
||||
int ha, int hb,
|
||||
int da = 0, int db = 0,
|
||||
@@ -61,6 +63,8 @@ struct direction_type
|
||||
}
|
||||
|
||||
|
||||
// TODO: replace this
|
||||
// NOTE: "char" will be replaced by enum in future version
|
||||
// "How" is the intersection formed?
|
||||
char how;
|
||||
|
||||
@@ -236,16 +240,12 @@ struct segments_direction
|
||||
return return_type('d', false);
|
||||
}
|
||||
|
||||
|
||||
static inline return_type parallel()
|
||||
{
|
||||
return return_type('p', false);
|
||||
}
|
||||
|
||||
static inline return_type error(std::string const&)
|
||||
{
|
||||
// msg
|
||||
return return_type('d', false);
|
||||
// Return "E" to denote error
|
||||
// This will throw an error in get_turn_info
|
||||
// TODO: change to enum or similar
|
||||
return return_type('E', false);
|
||||
}
|
||||
|
||||
private :
|
||||
|
||||
@@ -169,10 +169,7 @@ struct segments_intersection_points
|
||||
{
|
||||
return return_type();
|
||||
}
|
||||
static inline return_type parallel()
|
||||
{
|
||||
return return_type();
|
||||
}
|
||||
|
||||
static inline return_type degenerate(S1 const& s, bool)
|
||||
{
|
||||
return_type result;
|
||||
|
||||
@@ -164,15 +164,6 @@ struct segments_tupled
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
static inline return_type parallel()
|
||||
{
|
||||
return boost::make_tuple
|
||||
(
|
||||
Policy1::parallel(),
|
||||
Policy2::parallel()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace policies::relate
|
||||
|
||||
Reference in New Issue
Block a user