11# -*- coding: utf-8 -*-
22
3- from numpy import arctan2 , array , array2string , cos , exp , sin , sqrt
3+ from numpy import (
4+ arctan2 , array , array2string , asarray , cos , exp , float64 , sin , sqrt
5+ )
6+
47from .constants import ANGVEL , DAY_S , RAD2DEG , T0 , pi , tau
58from .earthlib import refract
69from .framelib import itrs
@@ -212,12 +215,18 @@ def height_of(self, position):
212215
213216 """
214217 xyz_au , x , y , aC , R , lat = self ._compute_latitude (position )
215- if R > 1.e-12 :
216- height_au = R / cos (lat ) - aC
217- else :
218- height_au = abs (xyz_au [2 ]) - self .semi_minor_axis .au
218+ height_au = self ._compute_height (R , lat , aC , xyz_au )
219219 return Distance (height_au )
220220
221+ def _compute_height (self , R , lat , aC , xyz_au ):
222+ height_au = asarray (R )
223+ near_pole = height_au <= 1.e-12
224+ if near_pole .any ():
225+ height_au [near_pole ] = abs (xyz_au [2 ]) - self .semi_minor_axis .au
226+ else :
227+ height_au [~ near_pole ] = R / cos (lat ) - aC
228+ return float64 (height_au )
229+
221230 def geographic_position_of (self , position ):
222231 """Return the `GeographicPosition` of a ``position``.
223232
@@ -229,10 +238,7 @@ def geographic_position_of(self, position):
229238 """
230239 xyz_au , x , y , aC , R , lat = self ._compute_latitude (position )
231240 lon = (arctan2 (y , x ) - pi ) % tau - pi
232- if R > 1.e-12 :
233- height_au = R / cos (lat ) - aC
234- else :
235- height_au = abs (xyz_au [2 ]) - self .semi_minor_axis .au
241+ height_au = self ._compute_height (R , lat , aC , xyz_au )
236242 return GeographicPosition (
237243 latitude = Angle (radians = lat ),
238244 longitude = Angle (radians = lon ),
@@ -280,12 +286,13 @@ def intersection_of(self, position, direction):
280286 """Return the surface point intersected by a vector.
281287
282288 The ``position`` and ``direction`` describe the tail and orientation
283- of the vector to intersect the ellipsoid, respectively. The vector must
284- be provided in ICRF coordinates with a ``.center``` of 399, the center
285- of the Earth. The direction should be an |xyz| unit vector. Returns a
286- `GeographicPosition` giving the geodetic ``latitude`` and ``longitude``
287- at the point that the ray intersects the surface of the Earth.
288-
289+ of the vector to intersect the ellipsoid, respectively. The position
290+ must be provided in ICRF coordinates with a ``.center``` of 399, the
291+ center of the Earth. The direction should be an |xyz| unit vector in
292+ the same coordinate frame. Returns a `GeographicPosition` giving the
293+ geodetic ``latitude`` and ``longitude`` at the point that the ray
294+ intersects the surface of the Earth.
295+
289296 The main calculation implemented here is based on JPL's NAIF toolkit;
290297 https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/ellipses.html
291298 """
@@ -309,7 +316,7 @@ def intersection_of(self, position, direction):
309316
310317 # Define a distortion matrix to map the ellipsoid into a unit sphere
311318 a = self .radius .au
312- c = a * ( 1.0 - 1.0 / self .inverse_flattening )
319+ c = self .semi_minor_axis . au
313320 d_matrix = array (
314321 [[1.0 / a , 0.0 , 0.0 ], [0.0 , 1.0 / a , 0.0 ], [0.0 , 0.0 , 1.0 / c ]]
315322 )
@@ -344,9 +351,9 @@ def intersection_of(self, position, direction):
344351 )
345352
346353 # Retrieve latitude and longitude
347- intersection_latlon = self .geographic_position_of (intersection )
354+ geo_intersection = self .geographic_position_of (intersection )
348355
349- return intersection_latlon
356+ return geo_intersection
350357
351358wgs84 = Geoid ('WGS84' , 6378137.0 , 298.257223563 )
352359iers2010 = Geoid ('IERS2010' , 6378136.6 , 298.25642 )
0 commit comments