Skip to content

Commit

Permalink
fix: prevent getDistanceFromLine to return NaN due to floating point …
Browse files Browse the repository at this point in the history
…arithmetic. fixes #227
  • Loading branch information
manuelbieh committed May 24, 2020
1 parent 4f69a9f commit 0a606f1
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 13 deletions.
13 changes: 2 additions & 11 deletions src/getDistance.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,10 @@
import getLatitude from './getLatitude';
import getLongitude from './getLongitude';
import toRad from './toRad';
import robustAcos from './robustAcos';
import { earthRadius } from './constants';
import { GeolibInputCoordinates } from './types';

const normalizeACosArg = (val: number): number => {
if (val > 1) {
return 1;
}
if (val < -1) {
return -1;
}
return val;
};

// Calculates the distance between two points.
// This method is simple but also more inaccurate
const getDistance = (
Expand All @@ -31,7 +22,7 @@ const getDistance = (

const distance =
Math.acos(
normalizeACosArg(
robustAcos(
Math.sin(toRad(toLat)) * Math.sin(toRad(fromLat)) +
Math.cos(toRad(toLat)) *
Math.cos(toRad(fromLat)) *
Expand Down
19 changes: 19 additions & 0 deletions src/getDistanceFromLine.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,23 @@ describe('getDistanceFromLine', () => {
)
).toEqual(188.5131192933101);
});

it('should not break if line start and line end are too close', () => {
const point = {
longitude: -75.63287336843746,
latitude: 6.278381350919607,
};

const lineStart = {
longitude: -75.6220658304469,
latitude: 6.285304104233529,
};

const lineEnd = {
longitude: -75.62216373107594,
latitude: 6.285232119894652,
};

expect(getDistanceFromLine(point, lineStart, lineEnd)).toEqual(1409);
});
});
9 changes: 7 additions & 2 deletions src/getDistanceFromLine.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import getDistance from './getDistance';
import robustAcos from './robustAcos';
import { GeolibInputCoordinates } from './types';

// Returns the minimum distance from a point to a line
Expand All @@ -12,10 +13,14 @@ const getDistanceFromLine = (
const d3 = getDistance(lineStart, lineEnd);

// alpha is the angle between the line from start to point, and from start to end
const alpha = Math.acos((d1 * d1 + d3 * d3 - d2 * d2) / (2 * d1 * d3));
const alpha = Math.acos(
robustAcos((d1 * d1 + d3 * d3 - d2 * d2) / (2 * d1 * d3))
);

// beta is the angle between the line from end to point and from end to start //
const beta = Math.acos((d2 * d2 + d3 * d3 - d1 * d1) / (2 * d2 * d3));
const beta = Math.acos(
robustAcos((d2 * d2 + d3 * d3 - d1 * d1) / (2 * d2 * d3))
);

// if the angle is greater than 90 degrees, then the minimum distance is the
// line from the start to the point
Expand Down

0 comments on commit 0a606f1

Please sign in to comment.