pygeodesy 24.5.15__py2.py3-none-any.whl → 24.5.24__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. {PyGeodesy-24.5.15.dist-info → PyGeodesy-24.5.24.dist-info}/METADATA +2 -2
  2. PyGeodesy-24.5.24.dist-info/RECORD +116 -0
  3. pygeodesy/__init__.py +1 -1
  4. pygeodesy/albers.py +41 -41
  5. pygeodesy/auxilats/__init__.py +1 -1
  6. pygeodesy/auxilats/auxAngle.py +32 -31
  7. pygeodesy/auxilats/auxLat.py +80 -51
  8. pygeodesy/azimuthal.py +123 -124
  9. pygeodesy/basics.py +8 -6
  10. pygeodesy/booleans.py +11 -12
  11. pygeodesy/cartesianBase.py +25 -23
  12. pygeodesy/clipy.py +3 -3
  13. pygeodesy/css.py +50 -42
  14. pygeodesy/datums.py +42 -41
  15. pygeodesy/dms.py +6 -6
  16. pygeodesy/ecef.py +23 -24
  17. pygeodesy/ellipsoidalBase.py +28 -27
  18. pygeodesy/ellipsoidalBaseDI.py +3 -4
  19. pygeodesy/ellipsoidalNvector.py +11 -12
  20. pygeodesy/ellipsoids.py +41 -35
  21. pygeodesy/elliptic.py +3 -4
  22. pygeodesy/epsg.py +4 -3
  23. pygeodesy/errors.py +34 -12
  24. pygeodesy/etm.py +62 -54
  25. pygeodesy/fmath.py +36 -30
  26. pygeodesy/formy.py +93 -65
  27. pygeodesy/frechet.py +117 -102
  28. pygeodesy/fstats.py +21 -14
  29. pygeodesy/fsums.py +67 -57
  30. pygeodesy/gars.py +10 -9
  31. pygeodesy/geodesicw.py +19 -17
  32. pygeodesy/geodesicx/__init__.py +1 -1
  33. pygeodesy/geodesicx/gx.py +40 -32
  34. pygeodesy/geodesicx/gxarea.py +12 -9
  35. pygeodesy/geodesicx/gxbases.py +3 -4
  36. pygeodesy/geodesicx/gxline.py +6 -8
  37. pygeodesy/geodsolve.py +28 -27
  38. pygeodesy/geohash.py +47 -44
  39. pygeodesy/geoids.py +34 -32
  40. pygeodesy/hausdorff.py +112 -99
  41. pygeodesy/heights.py +134 -127
  42. pygeodesy/internals.py +14 -9
  43. pygeodesy/interns.py +3 -6
  44. pygeodesy/iters.py +19 -17
  45. pygeodesy/karney.py +15 -12
  46. pygeodesy/ktm.py +25 -18
  47. pygeodesy/latlonBase.py +12 -11
  48. pygeodesy/lazily.py +4 -4
  49. pygeodesy/lcc.py +24 -25
  50. pygeodesy/ltp.py +83 -71
  51. pygeodesy/ltpTuples.py +7 -5
  52. pygeodesy/mgrs.py +3 -3
  53. pygeodesy/named.py +126 -42
  54. pygeodesy/namedTuples.py +33 -25
  55. pygeodesy/nvectorBase.py +7 -7
  56. pygeodesy/points.py +9 -9
  57. pygeodesy/rhumb/__init__.py +1 -1
  58. pygeodesy/solveBase.py +5 -5
  59. pygeodesy/sphericalTrigonometry.py +5 -5
  60. pygeodesy/streprs.py +5 -5
  61. pygeodesy/trf.py +5 -5
  62. pygeodesy/triaxials.py +67 -63
  63. pygeodesy/units.py +35 -35
  64. pygeodesy/unitsBase.py +24 -11
  65. pygeodesy/utm.py +53 -53
  66. pygeodesy/utmupsBase.py +10 -8
  67. pygeodesy/vector2d.py +6 -7
  68. pygeodesy/vector3d.py +16 -17
  69. pygeodesy/vector3dBase.py +4 -5
  70. PyGeodesy-24.5.15.dist-info/RECORD +0 -116
  71. {PyGeodesy-24.5.15.dist-info → PyGeodesy-24.5.24.dist-info}/WHEEL +0 -0
  72. {PyGeodesy-24.5.15.dist-info → PyGeodesy-24.5.24.dist-info}/top_level.txt +0 -0
pygeodesy/formy.py CHANGED
@@ -18,13 +18,15 @@ from pygeodesy.errors import IntersectionError, LimitError, limiterrors, \
18
18
  _TypeError, _ValueError, _xattr, _xError, \
19
19
  _xkwds, _xkwds_pop2
20
20
  from pygeodesy.fmath import euclid, hypot, hypot2, sqrt0
21
- from pygeodesy.fsums import fsumf_
22
- from pygeodesy.interns import NN, _delta_, _distant_, _inside_, _SPACE_, _too_
21
+ from pygeodesy.fsums import fsumf_, Fmt, unstr
22
+ # from pygeodesy.internals import _dunder_nameof # from .named
23
+ from pygeodesy.interns import _delta_, _distant_, _inside_, _not_, _SPACE_, _too_
23
24
  from pygeodesy.lazily import _ALL_LAZY, _ALL_MODS as _MODS
24
- from pygeodesy.named import _NamedTuple, _xnamed, Fmt, unstr
25
- from pygeodesy.namedTuples import Bearing2Tuple, Distance4Tuple, Intersection3Tuple, \
26
- LatLon2Tuple, PhiLam2Tuple, Vector3Tuple
27
- # from pygeodesy.streprs import Fmt, unstr # from .named
25
+ from pygeodesy.named import _name__, _name2__, _NamedTuple, _xnamed, \
26
+ _dunder_nameof
27
+ from pygeodesy.namedTuples import Bearing2Tuple, Distance4Tuple, LatLon2Tuple, \
28
+ Intersection3Tuple, PhiLam2Tuple, Vector3Tuple
29
+ # from pygeodesy.streprs import Fmt, unstr # from .fsums
28
30
  # from pygeodesy.triaxials import _hartzell2 # _MODS
29
31
  from pygeodesy.units import _isHeight, _isRadius, Bearing, Degrees_, Distance, \
30
32
  Distance_, Height, Lam_, Lat, Lon, Meter_, Phi_, \
@@ -40,7 +42,7 @@ from contextlib import contextmanager
40
42
  from math import asin, atan, atan2, cos, degrees, fabs, radians, sin, sqrt # pow
41
43
 
42
44
  __all__ = _ALL_LAZY.formy
43
- __version__ = '24.02.18'
45
+ __version__ = '24.05.24'
44
46
 
45
47
  _RADIANS2 = (PI / _180_0)**2 # degrees- to radians-squared
46
48
  _ratio_ = 'ratio'
@@ -59,36 +61,36 @@ def _anti2(a, b, n_2, n, n2):
59
61
  return float0_(r, b)
60
62
 
61
63
 
62
- def antipode(lat, lon, name=NN):
64
+ def antipode(lat, lon, **name):
63
65
  '''Return the antipode, the point diametrically opposite
64
66
  to a given point in C{degrees}.
65
67
 
66
68
  @arg lat: Latitude (C{degrees}).
67
69
  @arg lon: Longitude (C{degrees}).
68
- @kwarg name: Optional name (C{str}).
70
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
69
71
 
70
72
  @return: A L{LatLon2Tuple}C{(lat, lon)}.
71
73
 
72
74
  @see: Functions L{antipode_} and L{normal} and U{Geosphere
73
75
  <https://CRAN.R-Project.org/web/packages/geosphere/geosphere.pdf>}.
74
76
  '''
75
- return LatLon2Tuple(*_anti2(lat, lon, _90_0, _180_0, _360_0), name=name)
77
+ return LatLon2Tuple(*_anti2(lat, lon, _90_0, _180_0, _360_0), **name)
76
78
 
77
79
 
78
- def antipode_(phi, lam, name=NN):
80
+ def antipode_(phi, lam, **name):
79
81
  '''Return the antipode, the point diametrically opposite
80
82
  to a given point in C{radians}.
81
83
 
82
84
  @arg phi: Latitude (C{radians}).
83
85
  @arg lam: Longitude (C{radians}).
84
- @kwarg name: Optional name (C{str}).
86
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
85
87
 
86
88
  @return: A L{PhiLam2Tuple}C{(phi, lam)}.
87
89
 
88
90
  @see: Functions L{antipode} and L{normal_} and U{Geosphere
89
91
  <https://CRAN.R-Project.org/web/packages/geosphere/geosphere.pdf>}.
90
92
  '''
91
- return PhiLam2Tuple(*_anti2(phi, lam, PI_2, PI, PI2), name=name)
93
+ return PhiLam2Tuple(*_anti2(phi, lam, PI_2, PI, PI2), **name)
92
94
 
93
95
 
94
96
  def bearing(lat1, lon1, lat2, lon2, **final_wrap):
@@ -118,16 +120,17 @@ def bearing_(phi1, lam1, phi2, lam2, final=False, wrap=False):
118
120
  @arg lam1: Start longitude (C{radians}).
119
121
  @arg phi2: End latitude (C{radians}).
120
122
  @arg lam2: End longitude (C{radians}).
121
- @kwarg final: Return final bearing if C{True}, initial otherwise (C{bool}).
122
- @kwarg wrap: If C{True}, wrap or I{normalize} and unroll B{C{phi2}} and
123
- B{C{lam2}} (C{bool}).
123
+ @kwarg final: If C{True}, return the final, otherwise the initial
124
+ bearing (C{bool}).
125
+ @kwarg wrap: If C{True}, wrap or I{normalize} and unroll B{C{phi2}}
126
+ and B{C{lam2}} (C{bool}).
124
127
 
125
- @return: Initial or final bearing (compass C{radiansPI2}) or zero if start
126
- and end point coincide.
128
+ @return: Initial or final bearing (compass C{radiansPI2}) or zero if
129
+ start and end point coincide.
127
130
 
128
- @see: U{Bearing<https://www.Movable-Type.co.UK/scripts/latlong.html>}, U{Course
129
- between two points<https://www.EdWilliams.org/avform147.htm#Crs>} and
130
- U{Bearing Between Two Points<https://web.Archive.org/web/20020630205931/
131
+ @see: U{Bearing<https://www.Movable-Type.co.UK/scripts/latlong.html>},
132
+ U{Course between two points<https://www.EdWilliams.org/avform147.htm#Crs>}
133
+ and U{Bearing Between Two Points<https://web.Archive.org/web/20020630205931/
131
134
  https://MathForum.org/library/drmath/view/55417.html>}.
132
135
  '''
133
136
  db, phi2, lam2 = _Wrap.philam3(lam1, phi2, lam2, wrap)
@@ -154,7 +157,7 @@ def _bearingTo2(p1, p2, wrap=False): # for points.ispolar, sphericalTrigonometr
154
157
  t = p1.philam + p2.philam
155
158
  return Bearing2Tuple(degrees(bearing_(*t, final=False, wrap=wrap)),
156
159
  degrees(bearing_(*t, final=True, wrap=wrap)),
157
- name=_bearingTo2.__name__)
160
+ name__=_bearingTo2)
158
161
 
159
162
 
160
163
  def compassAngle(lat1, lon1, lat2, lon2, adjust=True, wrap=False):
@@ -416,7 +419,7 @@ def _ellipsoidal(earth, where):
416
419
  return _EWGS84 if earth in (_WGS84, _EWGS84) else (
417
420
  earth if isinstance(earth, Ellipsoid) else
418
421
  (earth if isinstance(earth, Datum) else # PYCHOK indent
419
- _ellipsoidal_datum(earth, name=where.__name__)).ellipsoid)
422
+ _ellipsoidal_datum(earth, name__=where)).ellipsoid)
420
423
 
421
424
 
422
425
  def equirectangular(lat1, lon1, lat2, lon2, radius=R_M, **adjust_limit_wrap):
@@ -940,7 +943,7 @@ def _hartzell(pov, los, earth, **kwds):
940
943
  if earth is None:
941
944
  earth = pov.datum
942
945
  else:
943
- earth = _spherical_datum(earth, name=hartzell.__name__)
946
+ earth = _spherical_datum(earth, name__=hartzell)
944
947
  pov = pov.toDatum(earth)
945
948
  h = pov.height
946
949
  if h < 0: # EPS0
@@ -949,26 +952,25 @@ def _hartzell(pov, los, earth, **kwds):
949
952
  return hartzell(pov, los=los, earth=earth, **kwds) if h > 0 else pov # EPS0
950
953
 
951
954
 
952
- def hartzell(pov, los=False, earth=_WGS84, name=NN, **LatLon_and_kwds):
955
+ def hartzell(pov, los=False, earth=_WGS84, **name_LatLon_and_kwds):
953
956
  '''Compute the intersection of the earth's surface and a Line-Of-Sight from
954
957
  a Point-Of-View in space.
955
958
 
956
959
  @arg pov: Point-Of-View outside the earth (C{LatLon}, C{Cartesian},
957
960
  L{Ecef9Tuple} or L{Vector3d}).
958
961
  @kwarg los: Line-Of-Sight, I{direction} to earth (L{Los}, L{Vector3d}),
959
- C{True} for the I{normal, plumb} onto the surface or
960
- C{False} or C{None} to point to the center of the earth.
962
+ C{True} for the I{normal, plumb} onto the surface or C{False}
963
+ or C{None} to point to the center of the earth.
961
964
  @kwarg earth: The earth model (L{Datum}, L{Ellipsoid}, L{Ellipsoid2},
962
965
  L{a_f2Tuple} or a C{scalar} earth radius in C{meter}).
963
- @kwarg name: Optional name (C{str}).
964
- @kwarg LatLon_and_kwds: Optional C{B{LatLon}=None} class to return the
965
- intersection plus additional C{LatLon} keyword
966
- arguments, include B{C{datum}} if different
967
- from B{C{earth}}.
966
+ @kwarg name_LatLon_and_kwds: Optional, overriding C{B{name}="hartzell"}
967
+ (C{str}), C{B{LatLon}=None} class to return the intersection
968
+ plus additional C{LatLon} keyword arguments, include the
969
+ B{C{datum}} if different from B{C{earth}}.
968
970
 
969
- @return: The intersection (L{Vector3d}, B{C{pov}}'s C{cartesian type} or
970
- the given B{C{LatLon}} instance) with attribute C{heigth} set
971
- to the distance to the B{C{pov}}.
971
+ @return: The intersection (L{Vector3d}, B{C{pov}}'s C{cartesian type} or the
972
+ given B{C{LatLon}} instance) with attribute C{heigth} set to the
973
+ distance to the B{C{pov}}.
972
974
 
973
975
  @raise IntersectionError: Invalid B{C{pov}} or B{C{pov}} inside the earth or
974
976
  invalid B{C{los}} or B{C{los}} points outside or
@@ -979,12 +981,12 @@ def hartzell(pov, los=False, earth=_WGS84, name=NN, **LatLon_and_kwds):
979
981
  @see: Class L{Los}, functions L{tyr3d} and L{hartzell4} and methods
980
982
  L{Ellipsoid.hartzell4} and any C{Cartesian.hartzell} and C{LatLon.hartzell}.
981
983
  '''
982
- n = hartzell.__name__
983
- D = earth if isinstance(earth, Datum) else _spherical_datum(earth, name=n)
984
+ D = _spherical_datum(earth, name__=hartzell)
985
+ n, LatLon_and_kwds = _name2__(name_LatLon_and_kwds, name__=hartzell)
984
986
  try:
985
987
  r, h, i = _MODS.triaxials._hartzell3(pov, los, D.ellipsoid._triaxial)
988
+ r = _xnamed(r, n)
986
989
 
987
- r = _xnamed(r, name or n)
988
990
  C = _MODS.cartesianBase.CartesianBase
989
991
  if LatLon_and_kwds:
990
992
  c = C(r, datum=D, name=r.name)
@@ -994,7 +996,8 @@ def hartzell(pov, los=False, earth=_WGS84, name=NN, **LatLon_and_kwds):
994
996
  if i:
995
997
  r._iteration = i
996
998
  except Exception as x:
997
- raise IntersectionError(pov=pov, los=los, earth=earth, cause=x, **LatLon_and_kwds)
999
+ raise IntersectionError(pov=pov, los=los, earth=earth, cause=x,
1000
+ **LatLon_and_kwds)
998
1001
  return r
999
1002
 
1000
1003
 
@@ -1139,8 +1142,8 @@ class _idllmn6(object): # see also .geodesicw._wargs, .latlonBase._toCartesian3
1139
1142
  if wrap:
1140
1143
  _, lat2, lon2 = _Wrap.latlon3(lon1, lat2, lon2, wrap)
1141
1144
  kwds = _xkwds(kwds, wrap=wrap) # for _xError
1142
- m = small if small is _100km else Meter_(small=small)
1143
- n = (intersections2 if s else intersection2).__name__
1145
+ m = small if small is _100km else Meter_(small=small)
1146
+ n = _dunder_nameof(intersections2 if s else intersection2)
1144
1147
  if datum is None or euclidean(lat1, lon1, lat2, lon2) < m:
1145
1148
  d, m = None, _MODS.vector3d
1146
1149
  _i = m._intersects2 if s else m._intersect3d3
@@ -1398,13 +1401,13 @@ def isnormal_(phi, lam, eps=0):
1398
1401
  return (PI_2 - fabs(phi)) >= eps and (PI - fabs(lam)) >= eps
1399
1402
 
1400
1403
 
1401
- def latlon2n_xyz(lat, lon, name=NN):
1404
+ def latlon2n_xyz(lat, lon, **name):
1402
1405
  '''Convert lat-, longitude to C{n-vector} (I{normal} to the
1403
1406
  earth's surface) X, Y and Z components.
1404
1407
 
1405
1408
  @arg lat: Latitude (C{degrees}).
1406
1409
  @arg lon: Longitude (C{degrees}).
1407
- @kwarg name: Optional name (C{str}).
1410
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
1408
1411
 
1409
1412
  @return: A L{Vector3Tuple}C{(x, y, z)}.
1410
1413
 
@@ -1429,12 +1432,12 @@ def _normal2(a, b, n_2, n, n2):
1429
1432
  return float0_(a, b)
1430
1433
 
1431
1434
 
1432
- def normal(lat, lon, name=NN):
1435
+ def normal(lat, lon, **name):
1433
1436
  '''Normalize a lat- I{and} longitude pair in C{degrees}.
1434
1437
 
1435
1438
  @arg lat: Latitude (C{degrees}).
1436
1439
  @arg lon: Longitude (C{degrees}).
1437
- @kwarg name: Optional name (C{str}).
1440
+ @kwarg name: Optional, overriding C{B{name}="normal"} (C{str}).
1438
1441
 
1439
1442
  @return: L{LatLon2Tuple}C{(lat, lon)} with C{abs(lat) <= 90}
1440
1443
  and C{abs(lon) <= 180}.
@@ -1442,15 +1445,15 @@ def normal(lat, lon, name=NN):
1442
1445
  @see: Functions L{normal_} and L{isnormal}.
1443
1446
  '''
1444
1447
  return LatLon2Tuple(*_normal2(lat, lon, _90_0, _180_0, _360_0),
1445
- name=name or normal.__name__)
1448
+ name=_name__(name, name__=normal))
1446
1449
 
1447
1450
 
1448
- def normal_(phi, lam, name=NN):
1451
+ def normal_(phi, lam, **name):
1449
1452
  '''Normalize a lat- I{and} longitude pair in C{radians}.
1450
1453
 
1451
1454
  @arg phi: Latitude (C{radians}).
1452
1455
  @arg lam: Longitude (C{radians}).
1453
- @kwarg name: Optional name (C{str}).
1456
+ @kwarg name: Optional, overriding C{B{name}="normal_"} (C{str}).
1454
1457
 
1455
1458
  @return: L{PhiLam2Tuple}C{(phi, lam)} with C{abs(phi) <= PI/2}
1456
1459
  and C{abs(lam) <= PI}.
@@ -1458,45 +1461,45 @@ def normal_(phi, lam, name=NN):
1458
1461
  @see: Functions L{normal} and L{isnormal_}.
1459
1462
  '''
1460
1463
  return PhiLam2Tuple(*_normal2(phi, lam, PI_2, PI, PI2),
1461
- name=name or normal_.__name__)
1464
+ name=_name__(name, name__=normal_))
1462
1465
 
1463
1466
 
1464
- def _2n_xyz(name, sa, ca, sb, cb):
1467
+ def _2n_xyz(name, sa, ca, sb, cb): # name always **name
1465
1468
  '''(INTERNAL) Helper for C{latlon2n_xyz} and C{philam2n_xyz}.
1466
1469
  '''
1467
1470
  # Kenneth Gade eqn 3, but using right-handed
1468
1471
  # vector x -> 0°E,0°N, y -> 90°E,0°N, z -> 90°N
1469
- return Vector3Tuple(ca * cb, ca * sb, sa, name=name)
1472
+ return Vector3Tuple(ca * cb, ca * sb, sa, **name)
1470
1473
 
1471
1474
 
1472
- def n_xyz2latlon(x, y, z, name=NN):
1475
+ def n_xyz2latlon(x, y, z, **name):
1473
1476
  '''Convert C{n-vector} components to lat- and longitude in C{degrees}.
1474
1477
 
1475
1478
  @arg x: X component (C{scalar}).
1476
1479
  @arg y: Y component (C{scalar}).
1477
1480
  @arg z: Z component (C{scalar}).
1478
- @kwarg name: Optional name (C{str}).
1481
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
1479
1482
 
1480
1483
  @return: A L{LatLon2Tuple}C{(lat, lon)}.
1481
1484
 
1482
1485
  @see: Function L{n_xyz2philam}.
1483
1486
  '''
1484
- return LatLon2Tuple(atan2d(z, hypot(x, y)), atan2d(y, x), name=name)
1487
+ return LatLon2Tuple(atan2d(z, hypot(x, y)), atan2d(y, x), **name)
1485
1488
 
1486
1489
 
1487
- def n_xyz2philam(x, y, z, name=NN):
1490
+ def n_xyz2philam(x, y, z, **name):
1488
1491
  '''Convert C{n-vector} components to lat- and longitude in C{radians}.
1489
1492
 
1490
1493
  @arg x: X component (C{scalar}).
1491
1494
  @arg y: Y component (C{scalar}).
1492
1495
  @arg z: Z component (C{scalar}).
1493
- @kwarg name: Optional name (C{str}).
1496
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
1494
1497
 
1495
1498
  @return: A L{PhiLam2Tuple}C{(phi, lam)}.
1496
1499
 
1497
1500
  @see: Function L{n_xyz2latlon}.
1498
1501
  '''
1499
- return PhiLam2Tuple(atan2(z, hypot(x, y)), atan2(y, x), name=name)
1502
+ return PhiLam2Tuple(atan2(z, hypot(x, y)), atan2(y, x), **name)
1500
1503
 
1501
1504
 
1502
1505
  def _opposes(d, m, n, n2):
@@ -1539,7 +1542,7 @@ def opposing_(radians1, radians2, margin=PI_2):
1539
1542
  return _opposes(radians2 - radians1, m, PI, PI2)
1540
1543
 
1541
1544
 
1542
- def philam2n_xyz(phi, lam, name=NN):
1545
+ def philam2n_xyz(phi, lam, **name):
1543
1546
  '''Convert lat-, longitude to C{n-vector} (I{normal} to the
1544
1547
  earth's surface) X, Y and Z components.
1545
1548
 
@@ -1557,14 +1560,38 @@ def philam2n_xyz(phi, lam, name=NN):
1557
1560
  return _2n_xyz(name, *sincos2_(phi, lam))
1558
1561
 
1559
1562
 
1560
- def _radical2(d, r1, r2): # in .ellipsoidalBaseDI, .sphericalTrigonometry, .vector3d
1563
+ def _Propy(inst, nargs, **_prop_func):
1564
+ '''(INTERNAL) Helper for the C{frechet.[-]Frechet**} and
1565
+ C{hausdorff.[-]Hausdorff*} classes.
1566
+ '''
1567
+ _prop, func = _prop_func.popitem() # _xkwds_item2(_func_func)
1568
+ if func is None: # getter
1569
+ try:
1570
+ return inst.__dict__[_prop]
1571
+ except KeyError:
1572
+ inst._notOverloaded(**inst.kwds)
1573
+ else: # setter
1574
+ try:
1575
+ if not callable(func):
1576
+ raise TypeError(_not_(callable.__name__))
1577
+ args = (0,) * nargs
1578
+ _ = func(*args, **inst.kwds)
1579
+ except Exception as x:
1580
+ t = unstr(func, **inst.kwds)
1581
+ raise _TypeError(t, cause=x)
1582
+ inst.__dict__[_prop] = func
1583
+ # return func
1584
+
1585
+
1586
+ def _radical2(d, r1, r2, **name): # in .ellipsoidalBaseDI, .sphericalTrigonometry, .vector3d
1561
1587
  # (INTERNAL) See C{radical2} below
1562
1588
  # assert d > EPS0
1563
- r = fsumf_(_1_0, (r1 / d)**2, -(r2 / d)**2) * _0_5
1564
- return Radical2Tuple(max(_0_0, min(_1_0, r)), r * d)
1589
+ r = fsumf_(_1_0, (r1 / d)**2, -(r2 / d)**2) * _0_5
1590
+ n = _name__(name, name__=radical2)
1591
+ return Radical2Tuple(max(_0_0, min(_1_0, r)), r * d, name=n)
1565
1592
 
1566
1593
 
1567
- def radical2(distance, radius1, radius2):
1594
+ def radical2(distance, radius1, radius2, **name):
1568
1595
  '''Compute the I{radical ratio} and I{radical line} of two
1569
1596
  U{intersecting circles<https://MathWorld.Wolfram.com/
1570
1597
  Circle-CircleIntersection.html>}.
@@ -1575,6 +1602,7 @@ def radical2(distance, radius1, radius2):
1575
1602
  @arg distance: Distance between the circle centers (C{scalar}).
1576
1603
  @arg radius1: Radius of the first circle (C{scalar}).
1577
1604
  @arg radius2: Radius of the second circle (C{scalar}).
1605
+ @kwarg name: Optional C{B{name}=NN} (C{str}).
1578
1606
 
1579
1607
  @return: A L{Radical2Tuple}C{(ratio, xline)} where C{0.0 <=
1580
1608
  ratio <= 1.0} and C{xline} is along the B{C{distance}}.
@@ -1594,8 +1622,8 @@ def radical2(distance, radius1, radius2):
1594
1622
  if d > (r1 + r2):
1595
1623
  raise IntersectionError(distance=d, radius1=r1, radius2=r2,
1596
1624
  txt=_too_(_distant_))
1597
- return _radical2(d, r1, r2) if d > EPS0 else \
1598
- Radical2Tuple(_0_5, _0_0)
1625
+ return _radical2(d, r1, r2, **name) if d > EPS0 else \
1626
+ Radical2Tuple(_0_5, _0_0, **name)
1599
1627
 
1600
1628
 
1601
1629
  class Radical2Tuple(_NamedTuple):
@@ -1607,7 +1635,7 @@ class Radical2Tuple(_NamedTuple):
1607
1635
 
1608
1636
 
1609
1637
  def _radistance(inst):
1610
- '''(INTERNAL) Helper for the L{frechet._FrecherMeterRadians}
1638
+ '''(INTERNAL) Helper for the L{frechet._FrechetMeterRadians}
1611
1639
  and L{hausdorff._HausdorffMeterRedians} classes.
1612
1640
  '''
1613
1641
  wrap_, kwds_ = _xkwds_pop2(inst._kwds, wrap=False)