Use winding number algorithm for linearRingContainsXY

This commit is contained in:
Björn Harrtell
2016-11-05 14:34:09 +01:00
parent 6c644186ba
commit 656af72615
2 changed files with 16 additions and 8 deletions
+15 -7
View File
@@ -36,22 +36,30 @@ ol.geom.flat.contains.linearRingContainsExtent = function(flatCoordinates, offse
* @return {boolean} Contains (x, y). * @return {boolean} Contains (x, y).
*/ */
ol.geom.flat.contains.linearRingContainsXY = function(flatCoordinates, offset, end, stride, x, y) { ol.geom.flat.contains.linearRingContainsXY = function(flatCoordinates, offset, end, stride, x, y) {
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html // http://geomalgorithms.com/a03-_inclusion.html
var contains = false; // Copyright 2000 softSurfer, 2012 Dan Sunday
// This code may be freely used and modified for any purpose
// providing that this copyright notice is included with it.
// SoftSurfer makes no warranty for this code, and cannot be held
// liable for any real or imagined damage resulting from its use.
// Users of this code must verify correctness for their application.
var wn = 0;
var x1 = flatCoordinates[end - stride]; var x1 = flatCoordinates[end - stride];
var y1 = flatCoordinates[end - stride + 1]; var y1 = flatCoordinates[end - stride + 1];
for (; offset < end; offset += stride) { for (; offset < end; offset += stride) {
var x2 = flatCoordinates[offset]; var x2 = flatCoordinates[offset];
var y2 = flatCoordinates[offset + 1]; var y2 = flatCoordinates[offset + 1];
var intersect = ((y1 > y) != (y2 > y)) && if (y1 <= y) {
(x < (x2 - x1) * (y - y1) / (y2 - y1) + x1); if (y2 > y && ((x2 - x1) * (y - y1)) - ((x - x1) * (y2 - y1)) > 0) {
if (intersect) { wn++;
contains = !contains; }
} else if (y2 <= y && ((x2 - x1) * (y - y1)) - ((x - x1) * (y2 - y1)) < 0) {
wn--;
} }
x1 = x2; x1 = x2;
y1 = y2; y1 = y2;
} }
return contains; return wn !== 0;
}; };
+1 -1
View File
@@ -10,7 +10,7 @@ describe('ol.geom.flat.contains', function() {
var flatCoordinatesSimple = [0, 0, 1, 0, 1, 1, 0, 1]; var flatCoordinatesSimple = [0, 0, 1, 0, 1, 1, 0, 1];
var flatCoordinatesNonSimple = [0, 0, 4, 0, 4, 3, 1, 3, 1, 2, 3, 2, 3, 1, 2, 1, 2, 4, 0, 4]; var flatCoordinatesNonSimple = [0, 0, 4, 0, 4, 3, 1, 3, 1, 2, 3, 2, 3, 1, 2, 1, 2, 4, 0, 4];
describe('ol.geom.flat.closest.getMaxSquaredDelta', function() { describe('ol.geom.flat.contains.linearRingContainsXY', function() {
it('returns true for point inside a simple polygon', function() { it('returns true for point inside a simple polygon', function() {
expect(ol.geom.flat.contains.linearRingContainsXY( expect(ol.geom.flat.contains.linearRingContainsXY(