5.2.18. nvector.core.on_great_circle

on_great_circle(path, n_EB_E, radius=6371009.0, atol=1e-08)[source]

Returns True if position B is on great circle through path A.

Parameters
path: tuple of 2 n-vectors

2 n-vectors of positions defining path A, decomposed in E.

n_EB_E: 3 x m array

n-vector(s) of position B to check to.

radius: real scalar

radius of sphere. (default 6371009.0)

atol: real scalar

The absolute tolerance parameter (See notes).

Returns
onbool array of length max(n, m)

True if position B is on great circle through path A.

Notes

The default value of atol is not zero, and is used to determine what small values should be considered close to zero. The default value is appropriate for expected values of order unity. However, atol should be carefully selected for the use case at hand. Typically the value should be set to the accepted error tolerance. For GPS data the error ranges from 0.01 m to 15 m.

Examples

Example 10: “Cross track distance”

https://raw.githubusercontent.com/pbrod/Nvector/master/docs/tutorials/images/ex10img.png

Path A is given by the two positions A1 and A2 (similar to the previous example).

Find the cross track distance sxt between the path A (i.e. the great circle through A1 and A2) and the position B (i.e. the shortest distance at the surface, between the great circle and B).

Also find the Euclidean distance dxt between B and the plane defined by the great circle. Use Earth radius 6371e3.

Finally, find the intersection point on the great circle and determine if it is between position A1 and A2.

Solution:
>>> import numpy as np
>>> import nvector as nv
>>> from nvector import rad, deg
>>> n_EA1_E = nv.lat_lon2n_E(rad(0), rad(0))
>>> n_EA2_E = nv.lat_lon2n_E(rad(10), rad(0))
>>> n_EB_E = nv.lat_lon2n_E(rad(1), rad(0.1))
>>> path = (n_EA1_E, n_EA2_E)
>>> radius = 6371e3  # mean earth radius [m]
>>> s_xt = nv.cross_track_distance(path, n_EB_E, radius=radius)
>>> d_xt = nv.cross_track_distance(path, n_EB_E, method='euclidean',
...                                radius=radius)
>>> val_txt = '{:4.2f} km, {:4.2f} km'.format(s_xt[0]/1000, d_xt[0]/1000)
>>> 'Ex10: Cross track distance: s_xt, d_xt = {0}'.format(val_txt)
'Ex10: Cross track distance: s_xt, d_xt = 11.12 km, 11.12 km'
>>> n_EC_E = nv.closest_point_on_great_circle(path, n_EB_E)
>>> np.allclose(nv.on_great_circle_path(path, n_EC_E, radius), True)
True
Alternative solution 2:
>>> s_xt2 = nv.great_circle_distance(n_EB_E, n_EC_E, radius)
>>> d_xt2 = nv.euclidean_distance(n_EB_E, n_EC_E, radius)
>>> np.allclose(s_xt, s_xt2), np.allclose(d_xt, d_xt2)
(True, True)
Alternative solution 3:
>>> c_E = nv.great_circle_normal(n_EA1_E, n_EA2_E)
>>> sin_theta = -np.dot(c_E.T, n_EB_E).ravel()
>>> s_xt3 = np.arcsin(sin_theta) * radius
>>> d_xt3 = sin_theta * radius
>>> np.allclose(s_xt, s_xt3), np.allclose(d_xt, d_xt3)
(True, True)