def intersection(self, path): """ Return the intersection between the paths Parameters ---------- path: GeoPath object path to intersect Returns ------- point: GeoPoint point of intersection between paths """ frame = self.positionA.frame n_EA1_E, n_EA2_E = self.nvector_normals() n_EB1_E, n_EB2_E = path.nvector_normals() # Find the intersection between the two paths, n_EC_E: n_EC_E_tmp = unit(cross(cross(n_EA1_E, n_EA2_E, axis=0), cross(n_EB1_E, n_EB2_E, axis=0), axis=0), norm_zero_vector=np.nan) # n_EC_E_tmp is one of two solutions, the other is -n_EC_E_tmp. Select # the one that is closet to n_EA1_E, by selecting sign from the dot # product between n_EC_E_tmp and n_EA1_E: n_EC_E = np.sign(dot(n_EC_E_tmp.T, n_EA1_E)) * n_EC_E_tmp if np.any(np.isnan(n_EC_E)): warnings.warn('Paths are Equal. Intersection point undefined. ' 'NaN returned.') lat_EC, long_EC = n_E2lat_lon(n_EC_E, frame.R_Ee) return GeoPoint(lat_EC, long_EC, frame=frame)
def cross_track_distance(self, point, method='greatcircle', radius=None): """ Return cross track distance from the path to a point. Parameters ---------- point: GeoPoint, Nvector or ECEFvector object position to measure the cross track distance to. radius: real scalar radius of sphere in [m]. Default mean Earth radius method: string defining distance calculated. Options are: 'greatcircle' or 'euclidean' Returns ------- distance: real scalar distance in [m] """ if radius is None: radius = self._get_average_radius() c_E = unit(self._normal_to_great_circle()) n_EB_E = point.to_nvector() cos_angle = dot(c_E.T, n_EB_E.normal) if method[0].lower() == 'e': return self._euclidean_cross_track_distance(cos_angle, radius) return self._great_circle_cross_track_distance(cos_angle, radius)
def _cross_track_point(path, point): """Extend nvector package to find the projection point. The projection point is the closest point on path to the given point. Based on the nvector.cross_track_distance function. http://www.navlab.net/nvector/ :param path: GeoPath :param point: GeoPoint """ c_E = great_circle_normal(*path.nvector_normals()) n_EB_E = point.to_nvector().normal # type: np.array c_EP_E = np.cross(c_E, n_EB_E, axis=0) # Find intersection point C that is closest to point B frame = path.positionA.frame n_EA1_E = path.positionA.to_nvector( ).normal # should also be ok to use n_EB_C n_EC_E_tmp = unit(np.cross(c_E, c_EP_E, axis=0), norm_zero_vector=np.nan) n_EC_E = np.sign(np.dot(n_EC_E_tmp.T, n_EA1_E)) * n_EC_E_tmp if np.any(np.isnan(n_EC_E)): raise Exception( 'Paths are Equal. Intersection point undefined. NaN returned.') lat_C, long_C = n_E2lat_lon(n_EC_E, frame.R_Ee) return nv.GeoPoint(lat_C, long_C, frame=frame)
def interpolate(self, ti): """ Return the interpolated point along the path Parameters ---------- ti: real scalar interpolation time assuming position A and B is at t0=0 and t1=1, respectively. Returns ------- point: Nvector point of interpolation along path """ point_a, point_b = self.nvectors() point_c = point_a + (point_b - point_a) * ti point_c.normal = unit(point_c.normal, norm_zero_vector=np.nan) return point_c
def interpolate(self, ti): """ Return the interpolated point along the path Parameters ---------- ti: real scalar interpolation time assuming position A and B is at t0=0 and t1=1, respectively. Returns ------- point: Nvector point of interpolation along path """ n_EB_E_t0, n_EB_E_t1 = self.nvector_normals() n_EB_E_ti = unit(n_EB_E_t0 + ti * (n_EB_E_t1 - n_EB_E_t0)) zi = self.positionA.z + ti * (self.positionB.z-self.positionA.z) frame = self.positionA.frame return frame.Nvector(n_EB_E_ti, zi)
def unit(self): """Normalizes self to unit vector(s)""" self.normal = unit(self.normal)