#716 closed defect (fixed)
Precision error causing polygons to not intersect
Reported by: | tokheim | Owned by: | strk |
---|---|---|---|
Priority: | major | Milestone: | 3.6.1 |
Component: | Core | Version: | 3.4.2 |
Severity: | Unassigned | Keywords: | |
Cc: | mloskot |
Description
A polygon containing another polygon with (almost) touching edges might in rare circumstances be viewed as disjoint. This happens when LineIntersector finds all vertices to be inside the polygon, while RayCrossingCounter finds a vertex to be outside. Example Polygons:
0103000000010000000400000001DA86DAF74BA83F2FA9595EF7FE1F408CF48F8922722440C9D18A61E80A41400000000000002440000000000000244001DA86DAF74BA83F2FA9595EF7FE1F40 010300000001000000040000000000000000002E400000000000001440FC0000505D92843FFFFF7762C29C1F40020018EA49852440000008012F1741400000000000002E400000000000001440
To avoid floating point precision errors, LineIntersector and RayCrossingCounter both need to use the same equation to determine which side of a line a point lies. See https://github.com/libgeos/libgeos/pull/42 for suggested patch
Change History (11)
comment:1 by , 9 years ago
comment:2 by , 9 years ago
strk: In these floating point precision issues it might very well boil down to which coordinate you subtract by before you send the directional vectors to robustDeterminant. Since RayCrossingCounter and orientationIndex can't use different implementations of this normalization, it should be performed by a common function. This is why the implementation was moved to RayCrossingCounter.
comment:3 by , 9 years ago
Would making RayCrossingCounter use CGAlgorithms implementation also work fine then ? It would seem a much smaller patch, only changing file would be RayCrossingCounter and only within the implementation of a function. Is that correct ?
comment:4 by , 9 years ago
Yes, but CGAlgorithms already depend on RayCrossingCounter, so it would require cyclic dependencies or some refactoring. Besides, deciding which side of a line a point is seems to fall well under the domain of a RayCrossingCounter.
comment:5 by , 9 years ago
Status: | new → assigned |
---|
comment:6 by , 9 years ago
NOTE: as of rev 926 JTS succeeds in running the testcase attached to the pull request
comment:7 by , 9 years ago
Cc: | added |
---|
As of rev 926 JTS uses CGAlgirithmsDD.orientationIndex (now I realize I already reported that). Mat, could you try your CGAlgorithmsDD port against the testcase attached to the pull request ?
comment:8 by , 9 years ago
At rev 427 JTS does not use CGAlgorithmsDD and indeed it fails the testcase.
comment:9 by , 9 years ago
Tested with x86-64 build of the CGAlgorithmsDD port
xmltester.exe bug716.xml Files: 1 Tests: 1 Failed: 0 Succeeded: 1
comment:10 by , 9 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
Mateusz you may also be interested in running the test attached to the ticket with the DoubleDouble change in place, as the JTS version of CGAlgorithms.orientationIndex runs CGAlgorithmsDD.orientationIndex, which may help.
Tokheim: it looks like you just moved CGAlgorithms::orientationIndex implementation to RayCrossingCounter, or how did the equation change ? Is the swapping in locatePointInRing what fixes the case ?