Skip to content

Conversation

@awulkiew
Copy link
Member

This PR is an attempt to fix the inconsistent results of sides and segment's intersection calculation on various platforms. For now I tested it on msvc10, msvc13 msvc12 and mingw-w64 4.9.1 on which different results was generated before.

Before, for floating-point coordinates, the results of determinant (side_by_triangle, cramer's rule) was compared with 0, scaling the machine epsilon by the greatest absolute of compared value. This wasn't a good solution since for nearly collinear segments the results are very small. For all of them factor 1 was always used (raw epsilon) no matter how long were the segments, what coordinates were used, so how great was the error. Furthermore on various platforms different instructions are generated for the determinant expression. For some instructions sets the error of the result is proportional to the input (so a difference of coordinates). The code added in this PR scales the epsilon by the greatest absolute value of the difference of points' coordinates passed into the determinant formula. For this purpose the support for EqualsPolicy was added which can be passed to math::detail::equals_by_policy() where is used to retrieve the epsilon factor.

This PR is related to this one: #259, which was the previous attempt and this ticket: https://svn.boost.org/trac/boost/ticket/8379.

As a side effect some of the tests (e.g. difference) previously failing now passes.

This PR doesn't solve all inconsistencies, there are tests which are still failing (e.g. get_turns, enabled with a macro) but now they're doing it in a more consistent way, i.e. similar ones generates the same, wrong output.

NOTE: The PR: #267 is a part of this one so it should be merged first.

Compare both ratios' potential denominators, corresponding to both
segments. Furthermore, take into account the machine epsilon.
Add the support for policy calculating epsilon factor in equals().
Add greatest() algorithm - max() equivalent taking more than 2 parameters.
Add specialization of abs() for floating-point numbers.
Compare the floating-point results of cramer's rule (denominators) using the epsilon
scaled by the greatest of the differences of coordinates of the segments'
endpoints (the input of the determinant formula).
Compare the floating-point results of determinant (denominators) using
the epsilon scaled by the greatest of the differences of coordinates of
the points passed into the determinant formula.
Instead of expecting invalid results, disable 2 still failing tests.
@awulkiew
Copy link
Member Author

The tests pass also on Linux GCC 4.8.2 and Clang 3.4.

@awulkiew awulkiew added the bug label Mar 15, 2015
To avoid returning reference to temporary object.

Add equals_factor_policy "empty" specialization for integral types.
@barendgehrels
Copy link
Collaborator

This is a larger changelist. I'm OK with this. I'm curious how it would work, also for in case areal/areal overlay operations do not use integer. But you don't have to test that, I will do that later. I'm OK with merging this.

awulkiew added a commit that referenced this pull request Mar 22, 2015
Fix for cart_intersect and side_by_triangle - inconsistencies on MinGW and more (robustness)
@awulkiew awulkiew merged commit e8fafc9 into boostorg:develop Mar 22, 2015
@awulkiew awulkiew deleted the fix/cart_intersect2 branch April 9, 2015 01:15
mloskot added a commit to mloskot/geometry that referenced this pull request Jun 19, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants