From b7a8ee44baa0c0a40a6544131cb35a946bad2a00 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Wed, 18 Sep 2013 13:21:15 -0400 Subject: [PATCH] Test and document quickhull algorithm --- spec/suites/QuickHullSpec.js | 47 ++++++++++++++++++++++++++++++++++ src/MarkerCluster.QuickHull.js | 38 +++++++++++++++++++++++---- 2 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 spec/suites/QuickHullSpec.js diff --git a/spec/suites/QuickHullSpec.js b/spec/suites/QuickHullSpec.js new file mode 100644 index 000000000..785f19e42 --- /dev/null +++ b/spec/suites/QuickHullSpec.js @@ -0,0 +1,47 @@ +describe('quickhull', function () { + describe('getDistant', function () { + it('zero distance', function () { + var bl = [ + { lat: 0, lng: 0 }, + { lat: 0, lng: 10 } + ]; + expect(L.QuickHull.getDistant({ lat: 0, lng: 0 }, bl)).to.eql(0); + }); + it('non-zero distance', function () { + var bl = [ + { lat: 0, lng: 0 }, + { lat: 0, lng: 10 } + ]; + expect(L.QuickHull.getDistant({ lat: 5, lng: 5 }, bl)).to.eql(-50); + }); + }); + + describe('getConvexHull', function () { + it('creates a hull', function () { + expect(L.QuickHull.getConvexHull([ + { lat: 0, lng: 0 }, + { lat: 10, lng: 0 }, + { lat: 10, lng: 10 }, + { lat: 0, lng: 10 }, + { lat: 5, lng: 5 }, + ])).to.eql([ + [ + { lat: 0, lng: 10 }, + { lat: 10, lng: 10 } + ], + [ + { lat: 10, lng: 10 }, + { lat: 10, lng: 0 }, + ], + [ + { lat: 10, lng: 0 }, + { lat: 0, lng: 0 } + ], + [ + { lat: 0, lng: 0 }, + { lat: 0, lng: 10 } + ] + ]); + }); + }); +}); diff --git a/src/MarkerCluster.QuickHull.js b/src/MarkerCluster.QuickHull.js index 8f033bce3..b95ea268a 100644 --- a/src/MarkerCluster.QuickHull.js +++ b/src/MarkerCluster.QuickHull.js @@ -26,13 +26,26 @@ Retrieved from: http://en.literateprograms.org/Quickhull_(Javascript)?oldid=1843 (function () { L.QuickHull = { + + /* + * @param {Object} cpt a point to be measured from the baseline + * @param {Array} bl the baseline, as represented by a two-element + * array of latlng objects. + * @returns {Number} an approximate distance measure + */ getDistant: function (cpt, bl) { var vY = bl[1].lat - bl[0].lat, vX = bl[0].lng - bl[1].lng; return (vX * (cpt.lat - bl[0].lat) + vY * (cpt.lng - bl[0].lng)); }, - + /* + * @param {Array} baseLine a two-element array of latlng objects + * representing the baseline to project from + * @param {Array} latLngs an array of latlng objects + * @returns {Object} the maximum point and all new points to stay + * in consideration for the hull. + */ findMostDistantPointFromBaseLine: function (baseLine, latLngs) { var maxD = 0, maxPt = null, @@ -53,11 +66,19 @@ Retrieved from: http://en.literateprograms.org/Quickhull_(Javascript)?oldid=1843 maxD = d; maxPt = pt; } - } - return { 'maxPoint': maxPt, 'newPoints': newPoints }; + + return { maxPoint: maxPt, newPoints: newPoints }; }, + + /* + * Given a baseline, compute the convex hull of latLngs as an array + * of latLngs. + * + * @param {Array} latLngs + * @returns {Array} + */ buildConvexHull: function (baseLine, latLngs) { var convexHullBaseLines = [], t = this.findMostDistantPointFromBaseLine(baseLine, latLngs); @@ -77,8 +98,15 @@ Retrieved from: http://en.literateprograms.org/Quickhull_(Javascript)?oldid=1843 } }, + /* + * Given an array of latlngs, compute a convex hull as an array + * of latlngs + * + * @param {Array} latLngs + * @returns {Array} + */ getConvexHull: function (latLngs) { - //find first baseline + // find first baseline var maxLat = false, minLat = false, maxPt = null, minPt = null, i; @@ -121,4 +149,4 @@ L.MarkerCluster.include({ return hullLatLng; } -}); \ No newline at end of file +});