Remove rescaling from cartesian intersection strategy

This commit is contained in:
Vissarion Fisikopoulos 2024-05-29 13:21:34 +03:00
parent d3ed449e39
commit d769af0d2c

View File

@ -274,38 +274,15 @@ struct cartesian_segments
// IntersectionPoint = (x1 + r * dx_a, y1 + r * dy_a) // IntersectionPoint = (x1 + r * dx_a, y1 + r * dy_a)
} }
// Version for non-rescaled policies
template template
< <
typename UniqueSubRange1, typename UniqueSubRange1,
typename UniqueSubRange2, typename UniqueSubRange2,
typename Policy typename Policy
> >
static inline typename Policy::return_type static inline typename Policy::return_type apply(UniqueSubRange1 const& range_p,
apply(UniqueSubRange1 const& range_p, UniqueSubRange2 const& range_q,
UniqueSubRange2 const& range_q, Policy const& policy)
Policy const& policy)
{
// Pass the same ranges both as normal ranges and as modelled ranges
return apply(range_p, range_q, policy, range_p, range_q);
}
// Version for non rescaled versions.
// The "modelled" parameter might be rescaled (will be removed later)
template
<
typename UniqueSubRange1,
typename UniqueSubRange2,
typename Policy,
typename ModelledUniqueSubRange1,
typename ModelledUniqueSubRange2
>
static inline typename Policy::return_type
apply(UniqueSubRange1 const& range_p,
UniqueSubRange2 const& range_q,
Policy const& policy,
ModelledUniqueSubRange1 const& modelled_range_p,
ModelledUniqueSubRange2 const& modelled_range_q)
{ {
typedef typename UniqueSubRange1::point_type point1_type; typedef typename UniqueSubRange1::point_type point1_type;
typedef typename UniqueSubRange2::point_type point2_type; typedef typename UniqueSubRange2::point_type point2_type;
@ -318,18 +295,13 @@ struct cartesian_segments
point2_type const& q1 = range_q.at(0); point2_type const& q1 = range_q.at(0);
point2_type const& q2 = range_q.at(1); point2_type const& q2 = range_q.at(1);
// Declare segments, currently necessary for the policies
// (segment_crosses, segment_colinear, degenerate, one_degenerate, etc)
model::referring_segment<point1_type const> const p(p1, p2);
model::referring_segment<point2_type const> const q(q1, q2);
typedef typename select_most_precise typedef typename select_most_precise
< <
typename geometry::coordinate_type<typename ModelledUniqueSubRange1::point_type>::type, typename geometry::coordinate_type<point1_type>::type,
typename geometry::coordinate_type<typename ModelledUniqueSubRange1::point_type>::type typename geometry::coordinate_type<point2_type>::type
>::type modelled_coordinate_type; >::type coordinate_type;
typedef segment_ratio<modelled_coordinate_type> ratio_type; typedef segment_ratio<coordinate_type> ratio_type;
segment_intersection_info segment_intersection_info
< <
typename select_calculation_type<point1_type, point2_type, CalculationType>::type, typename select_calculation_type<point1_type, point2_type, CalculationType>::type,
@ -341,7 +313,7 @@ struct cartesian_segments
sinfo.dy_a = get<1>(p2) - get<1>(p1); // distance in y-dir sinfo.dy_a = get<1>(p2) - get<1>(p1); // distance in y-dir
sinfo.dy_b = get<1>(q2) - get<1>(q1); sinfo.dy_b = get<1>(q2) - get<1>(q1);
return unified<ratio_type>(sinfo, p, q, policy, modelled_range_p, modelled_range_q); return unified<ratio_type>(sinfo, range_p, range_q, policy);
} }
//! Returns true if two segments do not overlap. //! Returns true if two segments do not overlap.
@ -375,39 +347,36 @@ struct cartesian_segments
return math::smaller(maxp, minq) || math::smaller(maxq, minp); return math::smaller(maxp, minq) || math::smaller(maxq, minp);
} }
// Implementation for either rescaled or non rescaled versions.
template template
< <
typename RatioType, typename RatioType,
typename SegmentInfo, typename SegmentInfo,
typename Segment1,
typename Segment2,
typename Policy,
typename UniqueSubRange1, typename UniqueSubRange1,
typename UniqueSubRange2 typename UniqueSubRange2,
typename Policy
> >
static inline typename Policy::return_type static inline typename Policy::return_type
unified(SegmentInfo& sinfo, unified(SegmentInfo& sinfo,
Segment1 const& p, Segment2 const& q, Policy const&,
UniqueSubRange1 const& range_p, UniqueSubRange1 const& range_p,
UniqueSubRange2 const& range_q) UniqueSubRange2 const& range_q,
Policy const&)
{ {
typedef typename UniqueSubRange1::point_type point1_type; typedef typename UniqueSubRange1::point_type point1_type;
typedef typename UniqueSubRange2::point_type point2_type; typedef typename UniqueSubRange2::point_type point2_type;
typedef typename select_most_precise
<
typename geometry::coordinate_type<point1_type>::type,
typename geometry::coordinate_type<point2_type>::type
>::type coordinate_type;
point1_type const& p1 = p.first; point1_type const& p1 = range_p.at(0);
point1_type const& p2 = p.second; point1_type const& p2 = range_p.at(1);
point2_type const& q1 = q.first; point2_type const& q1 = range_q.at(0);
point2_type const& q2 = q.second; point2_type const& q2 = range_q.at(1);
bool const p_is_point = equals_point_point(p1, p2); bool const p_is_point = equals_point_point(p1, p2);
bool const q_is_point = equals_point_point(q1, q2); bool const q_is_point = equals_point_point(q1, q2);
// Declare segments, currently necessary for the policies
// (segment_crosses, segment_colinear, degenerate, one_degenerate, etc)
model::referring_segment<point1_type const> const p(p1, p2);
model::referring_segment<point2_type const> const q(q1, q2);
if (p_is_point && q_is_point) if (p_is_point && q_is_point)
{ {
return equals_point_point(p1, q2) return equals_point_point(p1, q2)
@ -450,8 +419,16 @@ struct cartesian_segments
// (only calculated for non-collinear segments) // (only calculated for non-collinear segments)
if (! collinear) if (! collinear)
{ {
coordinate_type denominator_a, nominator_a; typedef typename select_most_precise
coordinate_type denominator_b, nominator_b; <
typename geometry::coordinate_type<point1_type>::type,
typename geometry::coordinate_type<point2_type>::type
>::type coordinate_type;
coordinate_type denominator_a;
coordinate_type nominator_a;
coordinate_type denominator_b;
coordinate_type nominator_b;
cramers_rule(sinfo.dx_a, sinfo.dy_a, sinfo.dx_b, sinfo.dy_b, cramers_rule(sinfo.dx_a, sinfo.dy_a, sinfo.dx_b, sinfo.dy_b,
get<0>(p1) - get<0>(q1), get<0>(p1) - get<0>(q1),
@ -470,7 +447,6 @@ struct cartesian_segments
if (math::detail::equals_by_policy(denominator_a, zero, policy) if (math::detail::equals_by_policy(denominator_a, zero, policy)
|| math::detail::equals_by_policy(denominator_b, zero, policy)) || math::detail::equals_by_policy(denominator_b, zero, policy))
{ {
// If this is the case, no rescaling is done for FP precision.
// We set it to collinear, but it indicates a robustness issue. // We set it to collinear, but it indicates a robustness issue.
sides.set<0>(0, 0); sides.set<0>(0, 0);
sides.set<1>(0, 0); sides.set<1>(0, 0);