diff --git a/index.js b/index.js index 46c86a9..b006cf7 100644 --- a/index.js +++ b/index.js @@ -1,20 +1,41 @@ -'use strict'; -var utils = require('./utils'); -function midPoint (line) { - var len = line.length; - var start = 0; - var end = len - 1; - var diff = 0; +import {getLength, findMidpoint} from './utils.js' +const midPoint = (line) => { + let start = 0; + let end = line.length - 1; + let diff = 0; + let lastStart = 0; + let lastEnd = 0; while (start + 1 !== end) { if (diff <= 0) { - diff += utils.getLength(line[start], line[++start]); + lastStart = getLength(line[start], line[++start]); + diff += lastStart; } else { - diff -= utils.getLength(line[end], line[--end]); + lastEnd = getLength(line[end], line[--end]); + diff -= lastEnd; } } - var hyp = utils.getLength(line[start], line[end]); - return utils.diffThingy(line[start], line[end], hyp, diff); + let hyp = getLength(line[start], line[end]); + + if (Math.abs(diff) > hyp) { + // our last segment is smaller than the current difference; + + // to correct this we + // 1. undo the last one that was too big + // 2. force it to do the segment at the other end that was previously the midpoint + // 3. recalculate the distance between the new last two points + if (diff > 0) { + diff -= lastStart; // 1. + start--;// 1. + diff -= getLength(line[end], line[--end]); // 2. + } else { + diff += lastEnd;// 1. + end++;// 1. + diff += getLength(line[start], line[++start]); // 2. + } + hyp = getLength(line[start], line[end]); // 3. + } + return findMidpoint(line[start], line[end], hyp, diff); } -module.exports = midPoint; \ No newline at end of file +export default midPoint; \ No newline at end of file diff --git a/package.json b/package.json index 6c84abf..090bd39 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "0.0.2", "description": "find the midpoint of a line", "main": "index.js", + "type":"module", "devDependencies": { "tap-spec": "~0.2.0", "tape": "~2.13.1" diff --git a/test.js b/test.js index 4a3f6c4..57ef499 100644 --- a/test.js +++ b/test.js @@ -1,26 +1,53 @@ 'use strict'; -var test = require('tape'); -var utils = require('./utils'); -var midPoint = require('./index'); +import test from 'tape'; +import {getLength} from './utils.js' +import midPoint from './index.js' -test('lengths', function (t) { +test('lengths', (t) => { var a = [0, 0]; var b = [1, 1]; var c = [-1, -1]; var root2 = Math.sqrt(2); var root8 = Math.sqrt(8); t.plan(6); - t.equals(utils.getLength(a, b), root2); - t.equals(utils.getLength(a, c), root2); - t.equals(utils.getLength(b, c), root8); - t.equals(utils.getLength(b, a), root2); - t.equals(utils.getLength(c, a), root2); - t.equals(utils.getLength(c, b), root8); + t.equals(getLength(a, b), root2); + t.equals(getLength(a, c), root2); + t.equals(getLength(b, c), root8); + t.equals(getLength(b, a), root2); + t.equals(getLength(c, a), root2); + t.equals(getLength(c, b), root8); }); test('mid points', function (t) { - t.deepEquals(midPoint([[0,0], [1,1], [2,2], [3,3]]), [1.5, 1.5], 'correct mid point'); - t.deepEquals(midPoint([[0,0], [1,1], [3,3]]), [1.5, 1.5], 'correct mid point'); - t.deepEquals(midPoint([[0,0], [1,1],[2,2]]), [1, 1], 'correct mid point'); + t.deepEquals(midPoint([[0,0], [1,1], [2,2], [3,3]]), [1.5, 1.5], 'correct mid point 1'); + t.deepEquals(midPoint([[0,0], [1,1], [3,3]]), [1.5, 1.5], 'correct mid point, 2'); + t.deepEquals(midPoint([[0,0], [1,1],[2,2]]), [1, 1], 'correct mid point, 3'); + t.deepEquals(midPoint([[0,0], [1, 0],[1,1],[7,1]]), [3, 1], 'correct mid point, 4'); + t.deepEquals(midPoint([[7,1], [1,1],[1,0],[0,0]]), [3, 1], 'correct mid point, 5'); + + t.end(); +}); + +test('weird', (t) => { + const path = [ + [ + -93.58900674667849, + 34.72896579327973 + ], + [ + -93.52014326672906, + 34.88244373300708 + ], + [ + -93.31354710277073, + 34.9711667901214 + ], + [ + -89.36857824131185, + 35.22873356176132 + ] + ] + t.deepEquals(midPoint(path), [-91.53717547300896, 35.08714598336179], 'correct forward') + t.deepEquals(midPoint(path.toReversed()), [-91.53717547300896, 35.08714598336179 ], 'correct backwards') t.end(); }); \ No newline at end of file diff --git a/utils.js b/utils.js index 7485edd..f27c03f 100644 --- a/utils.js +++ b/utils.js @@ -1,23 +1,22 @@ 'use strict'; -function getLength (p1, p2) { - var dx = p2[0] - p1[0]; - var dy = p2[1] - p1[1]; +export const getLength = (p1, p2) => { + const dx = p2[0] - p1[0]; + const dy = p2[1] - p1[1]; return Math.sqrt(dx * dx + dy * dy); } -exports.getLength = getLength; -function getDiff (p1, p2) { - var dx = p2[0] - p1[0]; - var dy = p2[1] - p1[1]; +const getDiff = (p1, p2) => { + const dx = p2[0] - p1[0]; + const dy = p2[1] - p1[1]; return [dx, dy]; } -function diffThingy(p1, p2, hyp, diff) { - var delta = getDiff(p1, p2); - var ratio = ((hyp - diff) / 2) / hyp; - return p1.map(function (p, i) { - return p + delta[i] * ratio; - }); +export const findMidpoint = (p1, p2, hyp, diff) => { + const delta = getDiff(p1, p2); + const ratio = ((hyp - diff) / 2) / hyp; + return [ + p1[0] + delta[0] * ratio, + p1[1] + delta[1] * ratio + ] } -exports.diffThingy = diffThingy; \ No newline at end of file