Skip to content

Commit

Permalink
Add LatLonEllipsoidal_Vincenty.intermediatePointTo()
Browse files Browse the repository at this point in the history
Also include other @examples in tests.
  • Loading branch information
chrisveness committed Nov 4, 2020
1 parent b9f6595 commit f132a9d
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 5 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
- Fix parsing of 'H' 500km squares (Scottish islands)
- Fix Dms.wrap90(), Dms.wrap180() to work for all -ve degrees

### Added

- LatLonEllipsoidal_Vincenty.intermediatePointTo()

## [2.2.1] - 2020-04-22

### Fixed
Expand Down
28 changes: 26 additions & 2 deletions latlon-ellipsoidal-vincenty.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Vincenty Direct and Inverse Solution of Geodesics on the Ellipsoid (c) Chris Veness 2002-2019 */
/* Vincenty Direct and Inverse Solution of Geodesics on the Ellipsoid (c) Chris Veness 2002-2020 */
/* MIT Licence */
/* www.movable-type.co.uk/scripts/latlong-ellipsoidal-vincenty.html */
/* www.movable-type.co.uk/scripts/geodesy-library.html#latlon-ellipsoidal-vincenty */
Expand Down Expand Up @@ -141,14 +141,38 @@ class LatLonEllipsoidal_Vincenty extends LatLonEllipsoidal {
*
* @example
* const p1 = new LatLon(-37.95103, 144.42487);
* const b2 = p1.finalBearingOn(306.86816, 54972.271); // 307.1736°
* const b2 = p1.finalBearingOn(54972.271, 306.86816); // 307.1736°
*/
finalBearingOn(distance, initialBearing) {
const brng = this.direct(Number(distance), Number(initialBearing)).finalBearing;
return Number(brng.toFixed(7)); // round to 0.001″ precision
}


/**
* Returns the point at given fraction between ‘this’ point and given point.
*
* @param {LatLon} point - Latitude/longitude of destination point.
* @param {number} fraction - Fraction between the two points (0 = this point, 1 = specified point).
* @returns {LatLon} Intermediate point between this point and destination point.
*
* @example
* const p1 = new LatLon(50.06632, -5.71475);
* const p2 = new LatLon(58.64402, -3.07009);
* const pInt = p1.intermediatePointTo(p2, 0.5); // 54.3639°N, 004.5304°W
*/
intermediatePointTo(point, fraction) {
if (fraction == 0) return this;
const inverse = this.inverse(point);
const dist = inverse.distance;
const brng = inverse.initialBearing;
return isNaN(brng) ? this : this.destinationPoint(dist*fraction, brng);
}


/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */


/**
* Vincenty direct calculation.
*
Expand Down
2 changes: 1 addition & 1 deletion latlon-nvector-spherical.js
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ class LatLonNvectorSpherical {
* @example
* const p1 = new LatLon(52.205, 0.119);
* const p2 = new LatLon(48.857, 2.351);
* const pInt = p1.intermediatePointTo(p2, 0.25); // 51.3723°N, 000.7072°E
* const pInt = p1.intermediatePointTo(p2, 0.25); // 51.3721°N, 000.7072°E
*/
intermediatePointTo(point, fraction) {
if (!(point instanceof LatLonNvectorSpherical)) throw new TypeError(`invalid point ‘${point}’`);
Expand Down
13 changes: 11 additions & 2 deletions test/latlon-ellipsoidal-vincenty-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ describe('latlon-ellipsoidal-vincenty', function() {
const circEquatorial = 40075016.686; // eslint-disable-line no-unused-vars
const circMeridional = 40007862.918;

describe('@examples', function() {
test('distanceTo', () => new LatLon(50.06632, -5.71475).distanceTo(new LatLon(58.64402, -3.07009)).toFixed(3).should.equal('969954.166'));
test('initialBearingTo', () => new LatLon(50.06632, -5.71475).initialBearingTo(new LatLon(58.64402, -3.07009)).toFixed(4).should.equal('9.1419'));
test('finalBearingTo', () => new LatLon(50.06632, -5.71475).finalBearingTo(new LatLon(58.64402, -3.07009)).toFixed(4).should.equal('11.2972'));
test('destinationPoint', () => new LatLon(-37.95103, 144.42487).destinationPoint(54972.271, 306.86816).toString().should.equal('37.6528°S, 143.9265°E'));
test('finalBearingOn', () => new LatLon(-37.95103, 144.42487).finalBearingOn(54972.271, 306.86816).toFixed(4).should.equal('307.1736'));
test('intermediatePointTo', () => new LatLon(50.06632, -5.71475).intermediatePointTo(new LatLon(58.64402, -3.07009), 0.5).toString().should.equal('54.3639°N, 004.5304°W'));
});

describe('UK', function() {
const le = new LatLon(50.06632, -5.71475), jog = new LatLon(58.64402, -3.07009);
const dist = 969954.166, brngInit = 9.1418775, brngFinal = 11.2972204;
Expand Down Expand Up @@ -93,8 +102,8 @@ describe('latlon-ellipsoidal-vincenty', function() {
test('distanceTo (fail)', () => should.Throw(function() { le.distanceTo(jog); }, RangeError, 'point must be on the surface of the ellipsoid'));
test('initialBearingTo (fail)', () => should.Throw(function() { le.initialBearingTo(jog); }, RangeError, 'point must be on the surface of the ellipsoid'));
test('finalBearingTo (fail)', () => should.Throw(function() { le.finalBearingTo(jog); }, RangeError, 'point must be on the surface of the ellipsoid'));
test('destinationPoint (fail)', () => should.Throw(function() { le.destinationPoint(0, 0); }, RangeError, 'point must be on the surface of the ellipsoid'));
test('finalBearingOn (fail)', () => should.Throw(function() { le.finalBearingOn(0, 0); }, RangeError, 'point must be on the surface of the ellipsoid'));
test('destinationPoint (fail)', () => should.Throw(function() { le.destinationPoint(1, 0); }, RangeError, 'point must be on the surface of the ellipsoid'));
test('finalBearingOn (fail)', () => should.Throw(function() { le.finalBearingOn(1, 0); }, RangeError, 'point must be on the surface of the ellipsoid'));
});

describe('convergence', function() {
Expand Down

0 comments on commit f132a9d

Please sign in to comment.