test and check for direction of vectors;
Problem: when checking whether a point q creates a spike or not with respect to two (ordered)
points a and b, the first check performed is whether q, a and b are collinear; if so, then it
is determined whether the vectors q-b and b-a have the same direction or not; for points with
floating-point coordinates, due to rounding errors as well as due to the fact that equality to
zero is checked using some tolerance, the three points may be detected as collinear; however,
when the directions of the two vectors are checked, computations are done without taking into
account any tolerance and this can lead to inconsistent results;
Fix: when checking the directions of the vectors q-b and b-a, compute signs of differences using
numerical tolerances, that is using math::equals() instead of plain comparison operators;
If there are NaN coordinates the conditions cannot be reasonably
calculated, therefore if the condition isn't met check if NaN coordinates
were not involved. This is consistent with the general policy WRT invalid
geometries, the algorithm don't fail but may generate invalid result.
Bugs are related to the handling of interior rings intersecting the second
geometry.
touches(A,A) now calls relate(A,A) besides a Ring/Ring case bcause Rings
have no holes so the simpified version may be used.
originally reported by Jeremy Murphy (GitHub PR #326); the problem is that
when debug_print_complement_graph() is called, std::cout needs to be defined
which requires the inclusion of <iostream> even in non-debug mode; with this
commit the call to debug_print_complement_graph() is guarded by the appropriate
macro and the use inclusion of <iostream> is no longer needed in non-debug mode;
This allows the algorithms using sections to check spatial predicates
using raw operators < (e.g. in Box/Box disjoint). There is no need to
use less performant calls to math::smaller.
Replace math::smaller usage in section functions preceeding() and
exceeding() and therefore revert the change done recently.
In places where a check must be performed, if a Point is one of the
endpoints of a Linestring contained in a MultiLinestring, std::sort() and
std::equal_range() algorithms are used. With MSVC the assertion in
std::equal_range() fails if the elements cannot be reliably compared, i.e.
in the case when Points has NaN coordinates.
Add has_nan_coordinate() utility and use it in boundary_checker and
topology_check in relate() implementation.
- Instead of assertion failure there is no effect and 0 is returned.
- Handle the NULL root in a similar way in insert, remove and count.
- Add runtime asserts.