def to4xyzh(self, h=None): '''Return this n-vector's components as 4-tuple. @keyword h: Optional height, overriding this n-vector's height (C{meter}). @return: A L{Vector4Tuple}C{(x, y, z, h)}. ''' r = Vector4Tuple(self.x, self.y, self.z, self.h if h is None else h) return self._xnamed(r)
def toNvector(self, Nvector=None, datum=None, **kwds): # PYCHOK Datums.WGS84 '''Convert this cartesian to C{n-vector} components. @keyword Nvector: Optional (sub-)class to return the C{n-vector} components (C{Nvector}) or C{None}. @keyword datum: Optional datum (L{Datum}) overriding this cartesian's datum. @keyword kwds: Optional, additional B{C{Nvector}} keyword arguments, ignored if C{B{Nvector}=None}. @return: Unit vector B{C{Nvector}} or a L{Vector4Tuple}C{(x, y, z, h)} if B{C{Nvector}=None}. @raise ValueError: The B{C{Cartesian}} at origin. ''' d = datum or self.datum r = self._v4t if r is None or self.datum != d: E = d.ellipsoid x, y, z = self.to3xyz() # Kenneth Gade eqn 23 p = hypot2(x, y) * E.a2_ q = (z**2 * E.e12) * E.a2_ r = fsum_(p, q, -E.e4) / 6 s = (p * q * E.e4) / (4 * r**3) t = cbrt(fsum_(1, s, sqrt(s * (2 + s)))) u = r * fsum_(1, t, 1 / t) v = sqrt(u**2 + E.e4 * q) w = E.e2 * fsum_(u, v, -q) / (2 * v) k = sqrt(fsum_(u, v, w**2)) - w if abs(k) < EPS: raise ValueError('%s: %r' % ('origin', self)) e = k / (k + E.e2) t = hypot(e * hypot(x, y), z) if t < EPS: raise ValueError('%s: %r' % ('origin', self)) h = fsum_(k, E.e2, -1) / k * t s = e / t r = Vector4Tuple(x * s, y * s, z / t, h) self._v4t = r if d == self.datum else None if Nvector is not None: r = Nvector(r.x, r.y, r.z, h=r.h, datum=d, **kwds) return self._xnamed(r)
def to4xyzh(self, h=None): '''Convert this (geodetic) point to n-vector (normal to the earth's surface) x/y/z components and height. @keyword h: Optional height, overriding this point's height (C{meter}). @return: A L{Vector4Tuple}C{(x, y, z, h)}, all in (C{meter}). ''' # Kenneth Gade eqn (3), but using right-handed # vector x -> 0°E,0°N, y -> 90°E,0°N, z -> 90°N # a, b = self.to2ab() # sa, ca, sb, cb = sincos2(a, b) # x, y, z = ca * cb, ca * sb, sa # XXX don't use self.to3xyz() + .... x, y, z = LatLonHeightBase.to3xyz(self) r = Vector4Tuple(x, y, z, self.height if h is None else h) return self._xnamed(r)
def to4xyzh(self, h=None): # PYCHOK no cover '''DEPRECATED, use property C{xyzh} or C{xyz.to4Tuple}C{(}B{C{h}}C{)}. ''' return self.xyzh if h in (None, self.h) else \ self._xnamed(Vector4Tuple(self.x, self.y, self.z, h))
def toNvector(self, Nvector=None, datum=None, **Nvector_kwds): # PYCHOK Datums.WGS84 '''Convert this cartesian to C{n-vector} components. @kwarg Nvector: Optional class to return the C{n-vector} components (C{Nvector}) or C{None}. @kwarg datum: Optional datum (L{Datum}) overriding this cartesian's datum. @kwarg Nvector_kwds: Optional, additional B{C{Nvector}} keyword arguments, ignored if B{C{Nvector=None}}. @return: The C{unit, n-vector} components (B{C{Nvector}}) or a L{Vector4Tuple}C{(x, y, z, h)} if B{C{Nvector}} is C{None}. @raise ValueError: The B{C{Cartesian}} at origin. @example: >>> c = Cartesian(3980581, 97, 4966825) >>> n = c.toNvector() # (x=0.622818, y=0.00002, z=0.782367, h=0.242887) ''' d = datum or self.datum _xinstanceof(Datum, datum=d) r = self._v4t if r is None or d != self.datum: # <https://www.Movable-Type.co.UK/scripts/geodesy/docs/ # latlon-nvector-ellipsoidal.js.html#line309> E = d.ellipsoid x, y, z = self.xyz # Kenneth Gade eqn 23 p = hypot2(x, y) * E.a2_ q = (z**2 * E.e12) * E.a2_ r = fsum_(p, q, -E.e4) / 6 s = (p * q * E.e4) / (4 * r**3) t = cbrt(fsum_(1, s, sqrt(s * (2 + s)))) u = r * fsum_(1, t, 1 / t) v = sqrt(u**2 + E.e4 * q) w = E.e2 * fsum_(u, v, -q) / (2 * v) k = sqrt(fsum_(u, v, w**2)) - w if abs(k) < EPS: raise _ValueError(origin=self) e = k / (k + E.e2) # d = e * hypot(x, y) # tmp = 1 / hypot(d, z) == 1 / hypot(e * hypot(x, y), z) t = hypot_(e * x, e * y, z) # == 1 / tmp if t < EPS: raise _ValueError(origin=self) h = fsum_(k, E.e2, -1) / k * t s = e / t # == e * tmp r = Vector4Tuple(x * s, y * s, z / t, h) self._v4t = r if d == self.datum else None if Nvector is not None: r = Nvector(r.x, r.y, r.z, h=r.h, datum=d, **Nvector_kwds) return self._xnamed(r)