From 02aa9bcc36f641dde9a4b63cba1ec8e8bc2d5845 Mon Sep 17 00:00:00 2001 From: tschaub Date: Mon, 16 Jan 2012 16:59:54 -0700 Subject: [PATCH] Tests with a description of the updated method. The old `containsPoint` method was sensitive to failure when looking for ray crossings with nearly vertical edges. These added tests demonstrate the simple cases where `containsPoint` succeeds. The tests also now include a case that covers the failure for polygons with nearly vertical edges. The previous `getX` method (within the `containsPoint` method) and the new one are mathematically equivalent. The updated version performs better in cases using coordinates with many significant figures. --- lib/OpenLayers/Geometry/LinearRing.js | 2 +- tests/Geometry/LinearRing.html | 106 +++++++++++++++++++++++--- 2 files changed, 98 insertions(+), 10 deletions(-) diff --git a/lib/OpenLayers/Geometry/LinearRing.js b/lib/OpenLayers/Geometry/LinearRing.js index bcb9ea4c4b..4c5450e82d 100644 --- a/lib/OpenLayers/Geometry/LinearRing.js +++ b/lib/OpenLayers/Geometry/LinearRing.js @@ -294,7 +294,7 @@ OpenLayers.Geometry.LinearRing = OpenLayers.Class( var px = approx(point.x, digs); var py = approx(point.y, digs); function getX(y, x1, y1, x2, y2) { - return (y-y2)*((x2-x1)/(y2-y1)) + x2; + return (y - y2) * ((x2 - x1) / (y2 - y1)) + x2; } var numSeg = this.components.length - 1; var start, end, x1, y1, x2, y2, cx, cy; diff --git a/tests/Geometry/LinearRing.html b/tests/Geometry/LinearRing.html index 20ef87efdd..cbbba2a0bc 100644 --- a/tests/Geometry/LinearRing.html +++ b/tests/Geometry/LinearRing.html @@ -250,21 +250,109 @@ "resize correctly adjusts y of component 4"); } - function test_LinearRing_containsPoint(t) { - t.plan(1); + function test_containsPoint(t) { + /** + * The ring: + * edge 3 + * (5, 10) __________ (15, 10) + * / / + * edge 4 / / edge 2 + * / / + * (0, 0) /_________/ (10, 0) + * edge 1 + */ var components = [ - new OpenLayers.Geometry.Point(-10812863.417266,3923827.912779), - new OpenLayers.Geometry.Point(-10812863.417264,3923951.5257855), - new OpenLayers.Geometry.Point(-10812309.24881,3923990.9386282), - new OpenLayers.Geometry.Point(-10812751.15038,3923798.0545649) + new OpenLayers.Geometry.Point(0, 0), + new OpenLayers.Geometry.Point(10, 0), + new OpenLayers.Geometry.Point(15, 10), + new OpenLayers.Geometry.Point(5, 10) ]; var ring = new OpenLayers.Geometry.LinearRing(components); - var point = new OpenLayers.Geometry.Point(-10812964.078829, 3923856.9524225); + + function p(x, y) { + return new OpenLayers.Geometry.Point(x, y); + } + + // contains: 1 (touches), true (within), false (outside) + var cases = [{ + point: p(5, 5), contains: true + }, { + point: p(20, 20), contains: false + }, { + point: p(15, 15), contains: false + }, { + point: p(0, 0), contains: 1 // lower left corner + }, { + point: p(10, 0), contains: 1 // lower right corner + }, { + point: p(15, 10), contains: 1 // upper right corner + }, { + point: p(5, 10), contains: 1 // upper left corner + }, { + point: p(5, 0), contains: 1 // on edge 1 + }, { + point: p(5, -0.1), contains: false // below edge 1 + }, { + point: p(5, 0.1), contains: true // above edge 1 + }, { + point: p(12.5, 5), contains: 1 // on edge 2 + }, { + point: p(12.4, 5), contains: true // left of edge 2 + }, { + point: p(12.6, 5), contains: false // right of edge 2 + }, { + point: p(10, 10), contains: 1 // on edge 3 + }, { + point: p(10, 9.9), contains: true // below edge 3 + }, { + point: p(10, 10.1), contains: false // above edge 3 + }, { + point: p(2.5, 5), contains: 1 // on edge 4 + }, { + point: p(2.4, 5), contains: false // left of edge 4 + }, { + point: p(2.6, 5), contains: true // right of edge 4 + }]; + + var len = cases.length; + t.plan(len); + var c; + for (var i=0; i