coordinate-system 7.1.0__cp313-cp313-win_amd64.whl → 7.1.1__cp313-cp313-win_amd64.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.
- coordinate_system/__init__.py +2 -2
- coordinate_system/complex_geometric_physics.py +2 -2
- coordinate_system/differential_geometry.py +356 -112
- {coordinate_system-7.1.0.dist-info → coordinate_system-7.1.1.dist-info}/METADATA +15 -2
- coordinate_system-7.1.1.dist-info/RECORD +13 -0
- coordinate_system-7.1.0.dist-info/RECORD +0 -13
- {coordinate_system-7.1.0.dist-info → coordinate_system-7.1.1.dist-info}/LICENSE +0 -0
- {coordinate_system-7.1.0.dist-info → coordinate_system-7.1.1.dist-info}/WHEEL +0 -0
- {coordinate_system-7.1.0.dist-info → coordinate_system-7.1.1.dist-info}/top_level.txt +0 -0
coordinate_system/__init__.py
CHANGED
|
@@ -24,11 +24,11 @@ Group Correspondence:
|
|
|
24
24
|
- U3Frame ∈ U(3) = SU(3) × U(1)
|
|
25
25
|
|
|
26
26
|
**Authors:** Pan Guojun
|
|
27
|
-
Version: 7.1.
|
|
27
|
+
Version: 7.1.1
|
|
28
28
|
**DOI:** https://doi.org/10.5281/zenodo.14435613
|
|
29
29
|
"""
|
|
30
30
|
|
|
31
|
-
__version__ = '7.1.
|
|
31
|
+
__version__ = '7.1.1'
|
|
32
32
|
|
|
33
33
|
from .coordinate_system import (
|
|
34
34
|
vec3,
|
|
@@ -26,11 +26,11 @@ Physical Interpretation:
|
|
|
26
26
|
|
|
27
27
|
**Authors:** Pan Guojun
|
|
28
28
|
Date: 2025-01-14
|
|
29
|
-
Version: 7.1.
|
|
29
|
+
Version: 7.1.1
|
|
30
30
|
**DOI:** https://doi.org/10.5281/zenodo.14435613
|
|
31
31
|
"""
|
|
32
32
|
|
|
33
|
-
__version__ = '7.1.
|
|
33
|
+
__version__ = '7.1.1'
|
|
34
34
|
|
|
35
35
|
import numpy as np
|
|
36
36
|
from typing import Tuple, Optional, Callable, Dict, Any
|
|
@@ -18,6 +18,7 @@ Date: 2025-12-03
|
|
|
18
18
|
"""
|
|
19
19
|
|
|
20
20
|
import math
|
|
21
|
+
import weakref
|
|
21
22
|
import numpy as np
|
|
22
23
|
from typing import Tuple, Optional, Callable, Union, Dict, List
|
|
23
24
|
from .coordinate_system import coord3, vec3
|
|
@@ -38,6 +39,7 @@ def _safe_normal_from_tangents(r_u: vec3, r_v: vec3) -> vec3:
|
|
|
38
39
|
return n * (1.0 / length)
|
|
39
40
|
return vec3(0.0, 0.0, 1.0)
|
|
40
41
|
|
|
42
|
+
|
|
41
43
|
def derivative_5pt(f: Callable[[float], np.ndarray], x: float, h: float) -> np.ndarray:
|
|
42
44
|
"""
|
|
43
45
|
5-point finite difference formula for first derivative.
|
|
@@ -328,7 +330,6 @@ class IntrinsicGradientOperator:
|
|
|
328
330
|
n = _safe_normal_from_tangents(r_theta, r_phi)
|
|
329
331
|
e1 = r_theta.normalized()
|
|
330
332
|
e2 = r_phi.normalized()
|
|
331
|
-
|
|
332
333
|
elif isinstance(self.surface, Torus):
|
|
333
334
|
R = self.surface.R
|
|
334
335
|
r = self.surface.r
|
|
@@ -351,7 +352,6 @@ class IntrinsicGradientOperator:
|
|
|
351
352
|
n = _safe_normal_from_tangents(r_u, r_v)
|
|
352
353
|
e1 = r_u.normalized()
|
|
353
354
|
e2 = r_v.normalized()
|
|
354
|
-
|
|
355
355
|
else:
|
|
356
356
|
# Numerical method for general surfaces
|
|
357
357
|
pos = self.surface.position(u, v)
|
|
@@ -361,14 +361,12 @@ class IntrinsicGradientOperator:
|
|
|
361
361
|
n = _safe_normal_from_tangents(r_u, r_v)
|
|
362
362
|
e1 = r_u.normalized()
|
|
363
363
|
e2 = r_v.normalized()
|
|
364
|
-
|
|
365
364
|
# Create intrinsic frame
|
|
366
365
|
frame = coord3()
|
|
367
366
|
frame.o = pos
|
|
368
367
|
frame.ux = e1
|
|
369
368
|
frame.uy = e2
|
|
370
369
|
frame.uz = n
|
|
371
|
-
|
|
372
370
|
return frame
|
|
373
371
|
|
|
374
372
|
def compute_both(self, u: float, v: float) -> Tuple[GradientResult, GradientResult, coord3]:
|
|
@@ -426,6 +424,9 @@ class IntrinsicGradientCurvatureCalculator:
|
|
|
426
424
|
self.surface = surface
|
|
427
425
|
self.h = step_size
|
|
428
426
|
self.grad_op = IntrinsicGradientOperator(surface, step_size)
|
|
427
|
+
self._cache_u: Optional[float] = None
|
|
428
|
+
self._cache_v: Optional[float] = None
|
|
429
|
+
self._cache_terms: Optional[Tuple[float, float, float, float, float, float, float, float]] = None
|
|
429
430
|
|
|
430
431
|
def _get_tangent_vectors(self, u: float, v: float) -> Tuple[vec3, vec3]:
|
|
431
432
|
"""Get tangent vectors (analytical for known surfaces, numerical otherwise)."""
|
|
@@ -461,9 +462,12 @@ class IntrinsicGradientCurvatureCalculator:
|
|
|
461
462
|
|
|
462
463
|
return r_u, r_v
|
|
463
464
|
|
|
464
|
-
def
|
|
465
|
+
def _compute_shape_terms(self, u: float, v: float) -> Tuple[float, float, float, float, float, float, float, float]:
|
|
465
466
|
"""
|
|
466
|
-
Compute
|
|
467
|
+
Compute shared shape-operator terms used by multiple curvature routines.
|
|
468
|
+
|
|
469
|
+
Returns:
|
|
470
|
+
(E, F, G, metric_det, L, M, N, M_uv)
|
|
467
471
|
"""
|
|
468
472
|
G_u, G_v, _ = self.grad_op.compute_both(u, v)
|
|
469
473
|
r_u, r_v = self._get_tangent_vectors(u, v)
|
|
@@ -477,45 +481,39 @@ class IntrinsicGradientCurvatureCalculator:
|
|
|
477
481
|
G = r_v.dot(r_v)
|
|
478
482
|
metric_det = E * G - F * F
|
|
479
483
|
|
|
480
|
-
# Second fundamental form
|
|
484
|
+
# Second fundamental form components
|
|
481
485
|
L = -dn_du.dot(r_u)
|
|
482
|
-
|
|
483
|
-
|
|
486
|
+
M_uv = -dn_du.dot(r_v)
|
|
487
|
+
M_vu = -dn_dv.dot(r_u)
|
|
484
488
|
N = -dn_dv.dot(r_v)
|
|
485
|
-
M = (
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
489
|
+
M = (M_uv + M_vu) / 2.0
|
|
490
|
+
|
|
491
|
+
return E, F, G, metric_det, L, M, N, M_uv
|
|
492
|
+
|
|
493
|
+
def _get_terms_cached(self, u: float, v: float) -> Tuple[float, float, float, float, float, float, float, float]:
|
|
494
|
+
if self._cache_terms is not None and u == self._cache_u and v == self._cache_v:
|
|
495
|
+
return self._cache_terms
|
|
496
|
+
terms = self._compute_shape_terms(u, v)
|
|
497
|
+
self._cache_u = u
|
|
498
|
+
self._cache_v = v
|
|
499
|
+
self._cache_terms = terms
|
|
500
|
+
return terms
|
|
501
|
+
|
|
502
|
+
def _compute_curvatures_from_terms(
|
|
503
|
+
self,
|
|
504
|
+
u: float,
|
|
505
|
+
terms: Tuple[float, float, float, float, float, float, float, float]
|
|
506
|
+
) -> Tuple[float, float]:
|
|
496
507
|
"""
|
|
497
|
-
Compute mean curvature
|
|
508
|
+
Compute Gaussian and mean curvature from shared terms.
|
|
498
509
|
"""
|
|
499
|
-
|
|
500
|
-
r_u, r_v = self._get_tangent_vectors(u, v)
|
|
501
|
-
|
|
502
|
-
dn_du = G_u.dn
|
|
503
|
-
dn_dv = G_v.dn
|
|
504
|
-
|
|
505
|
-
E = r_u.dot(r_u)
|
|
506
|
-
F = r_u.dot(r_v)
|
|
507
|
-
G = r_v.dot(r_v)
|
|
508
|
-
metric_det = E * G - F * F
|
|
509
|
-
|
|
510
|
-
L = -dn_du.dot(r_u)
|
|
511
|
-
M1 = -dn_du.dot(r_v)
|
|
512
|
-
M2 = -dn_dv.dot(r_u)
|
|
513
|
-
N = -dn_dv.dot(r_v)
|
|
514
|
-
M = (M1 + M2) / 2.0
|
|
510
|
+
E, F, G, metric_det, L, M, N, _ = terms
|
|
515
511
|
|
|
516
512
|
if abs(metric_det) > 1e-14:
|
|
513
|
+
K = (L * N - M * M) / metric_det
|
|
517
514
|
H = (G * L - 2 * F * M + E * N) / (2 * metric_det)
|
|
518
515
|
else:
|
|
516
|
+
K = 0.0
|
|
519
517
|
H = 0.0
|
|
520
518
|
|
|
521
519
|
if isinstance(self.surface, Sphere):
|
|
@@ -527,6 +525,22 @@ class IntrinsicGradientCurvatureCalculator:
|
|
|
527
525
|
if theory != 0.0:
|
|
528
526
|
H = math.copysign(abs(H), theory)
|
|
529
527
|
|
|
528
|
+
return K, H
|
|
529
|
+
|
|
530
|
+
def compute_gaussian_curvature(self, u: float, v: float) -> float:
|
|
531
|
+
"""
|
|
532
|
+
Compute Gaussian curvature K = det(II) / det(I).
|
|
533
|
+
"""
|
|
534
|
+
terms = self._get_terms_cached(u, v)
|
|
535
|
+
K, _ = self._compute_curvatures_from_terms(u, terms)
|
|
536
|
+
return K
|
|
537
|
+
|
|
538
|
+
def compute_mean_curvature(self, u: float, v: float) -> float:
|
|
539
|
+
"""
|
|
540
|
+
Compute mean curvature H = (EN - 2FM + GL) / (2*det(I)).
|
|
541
|
+
"""
|
|
542
|
+
terms = self._get_terms_cached(u, v)
|
|
543
|
+
_, H = self._compute_curvatures_from_terms(u, terms)
|
|
530
544
|
return H
|
|
531
545
|
|
|
532
546
|
def compute_riemann_curvature(self, u: float, v: float) -> float:
|
|
@@ -535,17 +549,9 @@ class IntrinsicGradientCurvatureCalculator:
|
|
|
535
549
|
|
|
536
550
|
For 2D surfaces: R^1_212 = K * det(g) = LN - M^2
|
|
537
551
|
"""
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
dn_du = G_u.dn
|
|
542
|
-
dn_dv = G_v.dn
|
|
543
|
-
|
|
544
|
-
L = -dn_du.dot(r_u)
|
|
545
|
-
M = -dn_du.dot(r_v)
|
|
546
|
-
N = -dn_dv.dot(r_v)
|
|
547
|
-
|
|
548
|
-
R_1212 = L * N - M * M
|
|
552
|
+
terms = self._get_terms_cached(u, v)
|
|
553
|
+
_, _, _, _, L, _, N, M_uv = terms
|
|
554
|
+
R_1212 = L * N - M_uv * M_uv
|
|
549
555
|
return R_1212
|
|
550
556
|
|
|
551
557
|
def compute_principal_curvatures(self, u: float, v: float) -> Tuple[float, float]:
|
|
@@ -554,8 +560,8 @@ class IntrinsicGradientCurvatureCalculator:
|
|
|
554
560
|
|
|
555
561
|
Uses: k1,k2 = H +/- sqrt(H^2 - K)
|
|
556
562
|
"""
|
|
557
|
-
|
|
558
|
-
H = self.
|
|
563
|
+
terms = self._get_terms_cached(u, v)
|
|
564
|
+
K, H = self._compute_curvatures_from_terms(u, terms)
|
|
559
565
|
|
|
560
566
|
discriminant = max(0, H * H - K)
|
|
561
567
|
sqrt_disc = discriminant ** 0.5
|
|
@@ -569,8 +575,8 @@ class IntrinsicGradientCurvatureCalculator:
|
|
|
569
575
|
"""
|
|
570
576
|
Compute all curvature quantities at once.
|
|
571
577
|
"""
|
|
572
|
-
|
|
573
|
-
H = self.
|
|
578
|
+
terms = self._get_terms_cached(u, v)
|
|
579
|
+
K, H = self._compute_curvatures_from_terms(u, terms)
|
|
574
580
|
|
|
575
581
|
discriminant = max(0, H * H - K)
|
|
576
582
|
sqrt_disc = discriminant ** 0.5
|
|
@@ -599,6 +605,28 @@ class CurvatureCalculator:
|
|
|
599
605
|
def __init__(self, surface: Surface, step_size: float = 1e-3):
|
|
600
606
|
self.surface = surface
|
|
601
607
|
self.h = step_size
|
|
608
|
+
self._cache_u: Optional[float] = None
|
|
609
|
+
self._cache_v: Optional[float] = None
|
|
610
|
+
self._cache_derivs: Optional[Dict[str, np.ndarray]] = None
|
|
611
|
+
self._cache_forms: Optional[Tuple[np.ndarray, np.ndarray, np.ndarray]] = None
|
|
612
|
+
|
|
613
|
+
def _get_derivs_cached(self, u: float, v: float) -> Dict[str, np.ndarray]:
|
|
614
|
+
if self._cache_derivs is not None and u == self._cache_u and v == self._cache_v:
|
|
615
|
+
return self._cache_derivs
|
|
616
|
+
derivs = self._compute_derivatives(u, v)
|
|
617
|
+
self._cache_u = u
|
|
618
|
+
self._cache_v = v
|
|
619
|
+
self._cache_derivs = derivs
|
|
620
|
+
self._cache_forms = None
|
|
621
|
+
return derivs
|
|
622
|
+
|
|
623
|
+
def _get_forms_cached(self, u: float, v: float) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
|
|
624
|
+
if self._cache_forms is not None and u == self._cache_u and v == self._cache_v:
|
|
625
|
+
return self._cache_forms
|
|
626
|
+
derivs = self._get_derivs_cached(u, v)
|
|
627
|
+
forms = self.compute_fundamental_forms(u, v, derivs)
|
|
628
|
+
self._cache_forms = forms
|
|
629
|
+
return forms
|
|
602
630
|
|
|
603
631
|
def _position_array(self, u: float, v: float) -> np.ndarray:
|
|
604
632
|
"""Convert vec3 position to numpy array."""
|
|
@@ -608,31 +636,62 @@ class CurvatureCalculator:
|
|
|
608
636
|
def _compute_derivatives(self, u: float, v: float) -> Dict[str, np.ndarray]:
|
|
609
637
|
"""Compute surface derivatives using high-order finite differences."""
|
|
610
638
|
effective_h = max(self.h, 1e-6)
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
639
|
+
h = effective_h
|
|
640
|
+
|
|
641
|
+
offsets = (-2, -1, 0, 1, 2)
|
|
642
|
+
pos = {}
|
|
643
|
+
for du in offsets:
|
|
644
|
+
u_offset = u + du * h
|
|
645
|
+
for dv in offsets:
|
|
646
|
+
pos[(du, dv)] = self._position_array(u_offset, v + dv * h)
|
|
647
|
+
|
|
648
|
+
# 5-point first-derivative coefficients
|
|
649
|
+
c1 = { -2: 1.0, -1: -8.0, 1: 8.0, 2: -1.0 }
|
|
650
|
+
|
|
651
|
+
# First derivatives
|
|
652
|
+
r_u = (
|
|
653
|
+
pos[(-2, 0)] - 8.0 * pos[(-1, 0)] + 8.0 * pos[(1, 0)] - pos[(2, 0)]
|
|
654
|
+
) / (12.0 * h)
|
|
655
|
+
r_v = (
|
|
656
|
+
pos[(0, -2)] - 8.0 * pos[(0, -1)] + 8.0 * pos[(0, 1)] - pos[(0, 2)]
|
|
657
|
+
) / (12.0 * h)
|
|
658
|
+
|
|
659
|
+
# 5-point second derivatives
|
|
660
|
+
r_uu = (
|
|
661
|
+
-pos[(2, 0)] + 16.0 * pos[(1, 0)] - 30.0 * pos[(0, 0)] +
|
|
662
|
+
16.0 * pos[(-1, 0)] - pos[(-2, 0)]
|
|
663
|
+
) / (12.0 * h * h)
|
|
664
|
+
r_vv = (
|
|
665
|
+
-pos[(0, 2)] + 16.0 * pos[(0, 1)] - 30.0 * pos[(0, 0)] +
|
|
666
|
+
16.0 * pos[(0, -1)] - pos[(0, -2)]
|
|
667
|
+
) / (12.0 * h * h)
|
|
668
|
+
|
|
669
|
+
# Mixed derivative via separable 5-point stencil
|
|
670
|
+
r_uv = np.zeros(3, dtype=np.float64)
|
|
671
|
+
for du, cu in c1.items():
|
|
672
|
+
for dv, cv in c1.items():
|
|
673
|
+
r_uv += (cu * cv) * pos[(du, dv)]
|
|
674
|
+
r_uv /= (144.0 * h * h)
|
|
622
675
|
|
|
623
676
|
return {
|
|
624
677
|
'r_u': r_u, 'r_v': r_v,
|
|
625
678
|
'r_uu': r_uu, 'r_vv': r_vv, 'r_uv': r_uv
|
|
626
679
|
}
|
|
627
680
|
|
|
628
|
-
def compute_fundamental_forms(
|
|
681
|
+
def compute_fundamental_forms(
|
|
682
|
+
self,
|
|
683
|
+
u: float,
|
|
684
|
+
v: float,
|
|
685
|
+
derivs: Optional[Dict[str, np.ndarray]] = None
|
|
686
|
+
) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
|
|
629
687
|
"""
|
|
630
688
|
Compute first and second fundamental forms.
|
|
631
689
|
|
|
632
690
|
Returns:
|
|
633
691
|
(g, h, n): First form, second form, normal vector
|
|
634
692
|
"""
|
|
635
|
-
derivs
|
|
693
|
+
if derivs is None:
|
|
694
|
+
derivs = self._compute_derivatives(u, v)
|
|
636
695
|
r_u = derivs['r_u']
|
|
637
696
|
r_v = derivs['r_v']
|
|
638
697
|
r_uu = derivs['r_uu']
|
|
@@ -661,40 +720,31 @@ class CurvatureCalculator:
|
|
|
661
720
|
|
|
662
721
|
return g, h, n
|
|
663
722
|
|
|
664
|
-
def
|
|
665
|
-
|
|
666
|
-
g
|
|
667
|
-
|
|
723
|
+
def _compute_curvatures_from_forms(
|
|
724
|
+
self,
|
|
725
|
+
g: np.ndarray,
|
|
726
|
+
h: np.ndarray
|
|
727
|
+
) -> Tuple[float, float]:
|
|
728
|
+
"""Compute Gaussian and mean curvature from fundamental forms."""
|
|
668
729
|
det_g = np.linalg.det(g)
|
|
669
|
-
det_h = np.linalg.det(h)
|
|
670
|
-
|
|
671
730
|
if abs(det_g) < 1e-14:
|
|
672
|
-
return 0.0
|
|
673
|
-
|
|
674
|
-
return det_h / det_g
|
|
731
|
+
return 0.0, 0.0
|
|
675
732
|
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
g, h, _ = self.compute_fundamental_forms(u, v)
|
|
679
|
-
|
|
680
|
-
det_g = np.linalg.det(g)
|
|
681
|
-
if abs(det_g) < 1e-14:
|
|
682
|
-
return 0.0
|
|
733
|
+
det_h = np.linalg.det(h)
|
|
734
|
+
K = det_h / det_g
|
|
683
735
|
|
|
684
736
|
trace_term = g[1, 1] * h[0, 0] - 2 * g[0, 1] * h[0, 1] + g[0, 0] * h[1, 1]
|
|
685
737
|
H = trace_term / (2 * det_g)
|
|
686
738
|
|
|
687
|
-
return abs(H)
|
|
739
|
+
return K, abs(H)
|
|
688
740
|
|
|
689
|
-
def
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
"""
|
|
696
|
-
g, h, _ = self.compute_fundamental_forms(u, v)
|
|
697
|
-
derivs = self._compute_derivatives(u, v)
|
|
741
|
+
def _compute_principal_from_forms(
|
|
742
|
+
self,
|
|
743
|
+
derivs: Dict[str, np.ndarray],
|
|
744
|
+
g: np.ndarray,
|
|
745
|
+
h: np.ndarray
|
|
746
|
+
) -> Tuple[float, float, np.ndarray, np.ndarray]:
|
|
747
|
+
"""Compute principal curvatures and directions from forms."""
|
|
698
748
|
r_u = derivs['r_u']
|
|
699
749
|
r_v = derivs['r_v']
|
|
700
750
|
|
|
@@ -702,20 +752,16 @@ class CurvatureCalculator:
|
|
|
702
752
|
if abs(det_g) < 1e-14:
|
|
703
753
|
return 0.0, 0.0, np.array([1., 0., 0.]), np.array([0., 1., 0.])
|
|
704
754
|
|
|
705
|
-
# Shape operator S = g^{-1} h
|
|
706
755
|
g_inv = np.linalg.inv(g)
|
|
707
756
|
S = g_inv @ h
|
|
708
757
|
|
|
709
|
-
# Eigenvalue decomposition
|
|
710
758
|
eigenvalues, eigenvectors = np.linalg.eig(S)
|
|
711
759
|
k1, k2 = eigenvalues.real
|
|
712
760
|
|
|
713
|
-
# Ensure k1 >= k2 by absolute value
|
|
714
761
|
if abs(k1) < abs(k2):
|
|
715
762
|
k1, k2 = k2, k1
|
|
716
763
|
eigenvectors = eigenvectors[:, [1, 0]]
|
|
717
764
|
|
|
718
|
-
# Convert to 3D directions
|
|
719
765
|
dir1_2d = eigenvectors[:, 0]
|
|
720
766
|
dir2_2d = eigenvectors[:, 1]
|
|
721
767
|
|
|
@@ -727,12 +773,35 @@ class CurvatureCalculator:
|
|
|
727
773
|
|
|
728
774
|
return k1, k2, dir1_3d, dir2_3d
|
|
729
775
|
|
|
776
|
+
def compute_gaussian_curvature(self, u: float, v: float) -> float:
|
|
777
|
+
"""Compute Gaussian curvature K = det(II) / det(I)."""
|
|
778
|
+
g, h, _ = self._get_forms_cached(u, v)
|
|
779
|
+
K, _ = self._compute_curvatures_from_forms(g, h)
|
|
780
|
+
return K
|
|
781
|
+
|
|
782
|
+
def compute_mean_curvature(self, u: float, v: float) -> float:
|
|
783
|
+
"""Compute mean curvature H."""
|
|
784
|
+
g, h, _ = self._get_forms_cached(u, v)
|
|
785
|
+
_, H = self._compute_curvatures_from_forms(g, h)
|
|
786
|
+
return H
|
|
787
|
+
|
|
788
|
+
def compute_principal_curvatures(self, u: float, v: float) -> Tuple[float, float, np.ndarray, np.ndarray]:
|
|
789
|
+
"""
|
|
790
|
+
Compute principal curvatures and principal directions.
|
|
791
|
+
|
|
792
|
+
Returns:
|
|
793
|
+
(k1, k2, dir1, dir2): Principal curvatures and directions
|
|
794
|
+
"""
|
|
795
|
+
derivs = self._get_derivs_cached(u, v)
|
|
796
|
+
g, h, _ = self._get_forms_cached(u, v)
|
|
797
|
+
return self._compute_principal_from_forms(derivs, g, h)
|
|
798
|
+
|
|
730
799
|
def compute_all_curvatures(self, u: float, v: float) -> Dict[str, Union[float, np.ndarray]]:
|
|
731
800
|
"""Compute all curvature quantities at once."""
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
H = self.
|
|
735
|
-
k1, k2, dir1, dir2 = self.
|
|
801
|
+
derivs = self._get_derivs_cached(u, v)
|
|
802
|
+
g, h, n = self._get_forms_cached(u, v)
|
|
803
|
+
K, H = self._compute_curvatures_from_forms(g, h)
|
|
804
|
+
k1, k2, dir1, dir2 = self._compute_principal_from_forms(derivs, g, h)
|
|
736
805
|
|
|
737
806
|
return {
|
|
738
807
|
'K': K,
|
|
@@ -751,6 +820,102 @@ class CurvatureCalculator:
|
|
|
751
820
|
# Convenience Functions - Intrinsic Gradient Method (Default)
|
|
752
821
|
# ============================================================
|
|
753
822
|
|
|
823
|
+
_intrinsic_calc_cache: "weakref.WeakKeyDictionary[Surface, Dict[float, IntrinsicGradientCurvatureCalculator]]" = weakref.WeakKeyDictionary()
|
|
824
|
+
_classical_calc_cache: "weakref.WeakKeyDictionary[Surface, Dict[float, CurvatureCalculator]]" = weakref.WeakKeyDictionary()
|
|
825
|
+
_intrinsic_grad_cache: "weakref.WeakKeyDictionary[Surface, Dict[float, IntrinsicGradientOperator]]" = weakref.WeakKeyDictionary()
|
|
826
|
+
|
|
827
|
+
|
|
828
|
+
def _get_cached_calc(cache, surface: Surface, step_size: float, ctor, attr_name: str):
|
|
829
|
+
try:
|
|
830
|
+
surf_dict = surface.__dict__
|
|
831
|
+
except Exception:
|
|
832
|
+
surf_dict = None
|
|
833
|
+
|
|
834
|
+
if surf_dict is not None:
|
|
835
|
+
step_map = surf_dict.get(attr_name)
|
|
836
|
+
if step_map is None:
|
|
837
|
+
step_map = {}
|
|
838
|
+
surf_dict[attr_name] = step_map
|
|
839
|
+
calc = step_map.get(step_size)
|
|
840
|
+
if calc is None:
|
|
841
|
+
calc = ctor(surface, step_size)
|
|
842
|
+
step_map[step_size] = calc
|
|
843
|
+
return calc
|
|
844
|
+
|
|
845
|
+
step_map = cache.get(surface)
|
|
846
|
+
if step_map is None:
|
|
847
|
+
step_map = {}
|
|
848
|
+
cache[surface] = step_map
|
|
849
|
+
calc = step_map.get(step_size)
|
|
850
|
+
if calc is None:
|
|
851
|
+
calc = ctor(surface, step_size)
|
|
852
|
+
step_map[step_size] = calc
|
|
853
|
+
return calc
|
|
854
|
+
|
|
855
|
+
|
|
856
|
+
def _curvatures_from_derivs(
|
|
857
|
+
r_u: vec3,
|
|
858
|
+
r_v: vec3,
|
|
859
|
+
r_uu: vec3,
|
|
860
|
+
r_uv: vec3,
|
|
861
|
+
r_vv: vec3
|
|
862
|
+
) -> Tuple[float, float]:
|
|
863
|
+
E = r_u.dot(r_u)
|
|
864
|
+
F = r_u.dot(r_v)
|
|
865
|
+
G = r_v.dot(r_v)
|
|
866
|
+
denom = E * G - F * F
|
|
867
|
+
if abs(denom) < 1e-14:
|
|
868
|
+
return 0.0, 0.0
|
|
869
|
+
n = _safe_normal_from_tangents(r_u, r_v)
|
|
870
|
+
L = r_uu.dot(n)
|
|
871
|
+
M = r_uv.dot(n)
|
|
872
|
+
N = r_vv.dot(n)
|
|
873
|
+
K = (L * N - M * M) / denom
|
|
874
|
+
H = (E * N - 2.0 * F * M + G * L) / (2.0 * denom)
|
|
875
|
+
return K, H
|
|
876
|
+
|
|
877
|
+
|
|
878
|
+
def _analytic_curvatures(surface: Surface, u: float, v: float) -> Optional[Tuple[float, float]]:
|
|
879
|
+
if not USE_ANALYTIC_DERIVS:
|
|
880
|
+
return None
|
|
881
|
+
if isinstance(surface, Sphere):
|
|
882
|
+
return surface.theoretical_gaussian_curvature, surface.theoretical_mean_curvature
|
|
883
|
+
if isinstance(surface, Torus):
|
|
884
|
+
return surface.theoretical_gaussian_curvature(u), surface.theoretical_mean_curvature(u)
|
|
885
|
+
if hasattr(surface, "analytic_KH"):
|
|
886
|
+
try:
|
|
887
|
+
return surface.analytic_KH(u, v)
|
|
888
|
+
except Exception:
|
|
889
|
+
pass
|
|
890
|
+
if hasattr(surface, "derivs"):
|
|
891
|
+
try:
|
|
892
|
+
r_u, r_v, r_uu, r_uv, r_vv = surface.derivs(u, v)
|
|
893
|
+
return _curvatures_from_derivs(r_u, r_v, r_uu, r_uv, r_vv)
|
|
894
|
+
except Exception:
|
|
895
|
+
pass
|
|
896
|
+
return None
|
|
897
|
+
|
|
898
|
+
|
|
899
|
+
_last_intrinsic: Dict[str, Union[Surface, float, Tuple[float, float], None]] = {
|
|
900
|
+
"surface": None,
|
|
901
|
+
"u": None,
|
|
902
|
+
"v": None,
|
|
903
|
+
"step": None,
|
|
904
|
+
"kh": None,
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
_last_classical: Dict[str, Union[Surface, float, Tuple[float, float], None]] = {
|
|
908
|
+
"surface": None,
|
|
909
|
+
"u": None,
|
|
910
|
+
"v": None,
|
|
911
|
+
"step": None,
|
|
912
|
+
"kh": None,
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
# Toggle analytic fast path (derivs/analytic_KH/theoretical formulas)
|
|
916
|
+
USE_ANALYTIC_DERIVS = True
|
|
917
|
+
|
|
918
|
+
|
|
754
919
|
def compute_gaussian_curvature(
|
|
755
920
|
surface: Surface,
|
|
756
921
|
u: float,
|
|
@@ -760,8 +925,24 @@ def compute_gaussian_curvature(
|
|
|
760
925
|
"""
|
|
761
926
|
Compute Gaussian curvature using intrinsic gradient method.
|
|
762
927
|
"""
|
|
763
|
-
|
|
764
|
-
|
|
928
|
+
if (
|
|
929
|
+
_last_intrinsic["surface"] is surface and
|
|
930
|
+
_last_intrinsic["u"] == u and
|
|
931
|
+
_last_intrinsic["v"] == v and
|
|
932
|
+
_last_intrinsic["step"] == step_size and
|
|
933
|
+
_last_intrinsic["kh"] is not None
|
|
934
|
+
):
|
|
935
|
+
return _last_intrinsic["kh"][0]
|
|
936
|
+
|
|
937
|
+
analytic = _analytic_curvatures(surface, u, v)
|
|
938
|
+
if analytic is not None:
|
|
939
|
+
_last_intrinsic.update({"surface": surface, "u": u, "v": v, "step": step_size, "kh": analytic})
|
|
940
|
+
return analytic[0]
|
|
941
|
+
|
|
942
|
+
calc = _get_cached_calc(_intrinsic_calc_cache, surface, step_size, IntrinsicGradientCurvatureCalculator, "_cs_intrinsic_calc")
|
|
943
|
+
K = calc.compute_gaussian_curvature(u, v)
|
|
944
|
+
_last_intrinsic.update({"surface": surface, "u": u, "v": v, "step": step_size, "kh": (K, None)})
|
|
945
|
+
return K
|
|
765
946
|
|
|
766
947
|
|
|
767
948
|
def compute_mean_curvature(
|
|
@@ -773,8 +954,25 @@ def compute_mean_curvature(
|
|
|
773
954
|
"""
|
|
774
955
|
Compute mean curvature using intrinsic gradient method.
|
|
775
956
|
"""
|
|
776
|
-
|
|
777
|
-
|
|
957
|
+
if (
|
|
958
|
+
_last_intrinsic["surface"] is surface and
|
|
959
|
+
_last_intrinsic["u"] == u and
|
|
960
|
+
_last_intrinsic["v"] == v and
|
|
961
|
+
_last_intrinsic["step"] == step_size and
|
|
962
|
+
_last_intrinsic["kh"] is not None and
|
|
963
|
+
_last_intrinsic["kh"][1] is not None
|
|
964
|
+
):
|
|
965
|
+
return _last_intrinsic["kh"][1]
|
|
966
|
+
|
|
967
|
+
analytic = _analytic_curvatures(surface, u, v)
|
|
968
|
+
if analytic is not None:
|
|
969
|
+
_last_intrinsic.update({"surface": surface, "u": u, "v": v, "step": step_size, "kh": analytic})
|
|
970
|
+
return analytic[1]
|
|
971
|
+
|
|
972
|
+
calc = _get_cached_calc(_intrinsic_calc_cache, surface, step_size, IntrinsicGradientCurvatureCalculator, "_cs_intrinsic_calc")
|
|
973
|
+
H = calc.compute_mean_curvature(u, v)
|
|
974
|
+
_last_intrinsic.update({"surface": surface, "u": u, "v": v, "step": step_size, "kh": (None, H)})
|
|
975
|
+
return H
|
|
778
976
|
|
|
779
977
|
|
|
780
978
|
def compute_riemann_curvature(
|
|
@@ -786,7 +984,7 @@ def compute_riemann_curvature(
|
|
|
786
984
|
"""
|
|
787
985
|
Compute Riemann curvature tensor component R^1_212.
|
|
788
986
|
"""
|
|
789
|
-
calc =
|
|
987
|
+
calc = _get_cached_calc(_intrinsic_calc_cache, surface, step_size, IntrinsicGradientCurvatureCalculator, "_cs_intrinsic_calc")
|
|
790
988
|
return calc.compute_riemann_curvature(u, v)
|
|
791
989
|
|
|
792
990
|
|
|
@@ -799,7 +997,20 @@ def compute_all_curvatures(
|
|
|
799
997
|
"""
|
|
800
998
|
Compute all curvature quantities using intrinsic gradient method.
|
|
801
999
|
"""
|
|
802
|
-
|
|
1000
|
+
analytic = _analytic_curvatures(surface, u, v)
|
|
1001
|
+
if analytic is not None:
|
|
1002
|
+
K, H = analytic
|
|
1003
|
+
discriminant = max(0, H * H - K)
|
|
1004
|
+
sqrt_disc = discriminant ** 0.5
|
|
1005
|
+
k1 = H + sqrt_disc
|
|
1006
|
+
k2 = H - sqrt_disc
|
|
1007
|
+
return {
|
|
1008
|
+
'gaussian_curvature': K,
|
|
1009
|
+
'mean_curvature': H,
|
|
1010
|
+
'principal_curvatures': (k1, k2)
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
calc = _get_cached_calc(_intrinsic_calc_cache, surface, step_size, IntrinsicGradientCurvatureCalculator, "_cs_intrinsic_calc")
|
|
803
1014
|
return calc.compute_all_curvatures(u, v)
|
|
804
1015
|
|
|
805
1016
|
|
|
@@ -822,7 +1033,7 @@ def compute_intrinsic_gradient(
|
|
|
822
1033
|
Returns:
|
|
823
1034
|
GradientResult object
|
|
824
1035
|
"""
|
|
825
|
-
grad_op =
|
|
1036
|
+
grad_op = _get_cached_calc(_intrinsic_grad_cache, surface, step_size, IntrinsicGradientOperator, "_cs_intrinsic_grad")
|
|
826
1037
|
|
|
827
1038
|
if direction == 'u':
|
|
828
1039
|
return grad_op.compute_u(u, v)
|
|
@@ -843,8 +1054,24 @@ def gaussian_curvature_classical(
|
|
|
843
1054
|
step_size: float = 1e-3
|
|
844
1055
|
) -> float:
|
|
845
1056
|
"""Compute Gaussian curvature using classical method."""
|
|
846
|
-
|
|
847
|
-
|
|
1057
|
+
if (
|
|
1058
|
+
_last_classical["surface"] is surface and
|
|
1059
|
+
_last_classical["u"] == u and
|
|
1060
|
+
_last_classical["v"] == v and
|
|
1061
|
+
_last_classical["step"] == step_size and
|
|
1062
|
+
_last_classical["kh"] is not None
|
|
1063
|
+
):
|
|
1064
|
+
return _last_classical["kh"][0]
|
|
1065
|
+
|
|
1066
|
+
analytic = _analytic_curvatures(surface, u, v)
|
|
1067
|
+
if analytic is not None:
|
|
1068
|
+
_last_classical.update({"surface": surface, "u": u, "v": v, "step": step_size, "kh": (analytic[0], abs(analytic[1]))})
|
|
1069
|
+
return analytic[0]
|
|
1070
|
+
|
|
1071
|
+
calc = _get_cached_calc(_classical_calc_cache, surface, step_size, CurvatureCalculator, "_cs_classical_calc")
|
|
1072
|
+
K = calc.compute_gaussian_curvature(u, v)
|
|
1073
|
+
_last_classical.update({"surface": surface, "u": u, "v": v, "step": step_size, "kh": (K, None)})
|
|
1074
|
+
return K
|
|
848
1075
|
|
|
849
1076
|
|
|
850
1077
|
def mean_curvature_classical(
|
|
@@ -854,8 +1081,25 @@ def mean_curvature_classical(
|
|
|
854
1081
|
step_size: float = 1e-3
|
|
855
1082
|
) -> float:
|
|
856
1083
|
"""Compute mean curvature using classical method."""
|
|
857
|
-
|
|
858
|
-
|
|
1084
|
+
if (
|
|
1085
|
+
_last_classical["surface"] is surface and
|
|
1086
|
+
_last_classical["u"] == u and
|
|
1087
|
+
_last_classical["v"] == v and
|
|
1088
|
+
_last_classical["step"] == step_size and
|
|
1089
|
+
_last_classical["kh"] is not None and
|
|
1090
|
+
_last_classical["kh"][1] is not None
|
|
1091
|
+
):
|
|
1092
|
+
return _last_classical["kh"][1]
|
|
1093
|
+
|
|
1094
|
+
analytic = _analytic_curvatures(surface, u, v)
|
|
1095
|
+
if analytic is not None:
|
|
1096
|
+
_last_classical.update({"surface": surface, "u": u, "v": v, "step": step_size, "kh": (analytic[0], abs(analytic[1]))})
|
|
1097
|
+
return abs(analytic[1])
|
|
1098
|
+
|
|
1099
|
+
calc = _get_cached_calc(_classical_calc_cache, surface, step_size, CurvatureCalculator, "_cs_classical_calc")
|
|
1100
|
+
H = calc.compute_mean_curvature(u, v)
|
|
1101
|
+
_last_classical.update({"surface": surface, "u": u, "v": v, "step": step_size, "kh": (None, H)})
|
|
1102
|
+
return H
|
|
859
1103
|
|
|
860
1104
|
|
|
861
1105
|
def principal_curvatures_classical(
|
|
@@ -865,7 +1109,7 @@ def principal_curvatures_classical(
|
|
|
865
1109
|
step_size: float = 1e-3
|
|
866
1110
|
) -> Tuple[float, float]:
|
|
867
1111
|
"""Compute principal curvatures using classical method."""
|
|
868
|
-
calc =
|
|
1112
|
+
calc = _get_cached_calc(_classical_calc_cache, surface, step_size, CurvatureCalculator, "_cs_classical_calc")
|
|
869
1113
|
k1, k2, _, _ = calc.compute_principal_curvatures(u, v)
|
|
870
1114
|
return k1, k2
|
|
871
1115
|
|
|
@@ -877,7 +1121,7 @@ def all_curvatures_classical(
|
|
|
877
1121
|
step_size: float = 1e-3
|
|
878
1122
|
) -> Dict[str, Union[float, np.ndarray]]:
|
|
879
1123
|
"""Compute all curvature quantities using classical method."""
|
|
880
|
-
calc =
|
|
1124
|
+
calc = _get_cached_calc(_classical_calc_cache, surface, step_size, CurvatureCalculator, "_cs_classical_calc")
|
|
881
1125
|
return calc.compute_all_curvatures(u, v)
|
|
882
1126
|
|
|
883
1127
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: coordinate_system
|
|
3
|
-
Version: 7.1.
|
|
3
|
+
Version: 7.1.1
|
|
4
4
|
Summary: High-performance 3D coordinate system library with unified differential geometry, quantum frame algebra, and Christmas Equation (CFUT)
|
|
5
5
|
Home-page: https://github.com/panguojun/Coordinate-System
|
|
6
6
|
Author: Pan Guojun
|
|
@@ -51,12 +51,19 @@ Requires-Dist: matplotlib>=3.3.0
|
|
|
51
51
|
[](LICENSE)
|
|
52
52
|
|
|
53
53
|
**Authors:** Pan Guojun
|
|
54
|
-
**Version:** 7.1.
|
|
54
|
+
**Version:** 7.1.1
|
|
55
55
|
**License:** MIT
|
|
56
56
|
**DOI:** https://doi.org/10.5281/zenodo.14435613
|
|
57
57
|
|
|
58
58
|
---
|
|
59
59
|
|
|
60
|
+
## What's New in v7.1.1 (2026-02-05)
|
|
61
|
+
|
|
62
|
+
- **Curvature Fast Path**: Analytical curvature for Sphere/Torus and any surface providing `derivs` or `analytic_KH` (toggle via `USE_ANALYTIC_DERIVS`)
|
|
63
|
+
- **Caching**: Reuse curvature calculators and last-call results to reduce per-sample overhead
|
|
64
|
+
- **Math Core**: Branchless handedness selection for cross product; optional SIMD alignment via `PMSYS_SIMD_ALIGN`
|
|
65
|
+
- **Build Flags**: AVX2 / fast-math enabled by default in build config for faster native builds
|
|
66
|
+
|
|
60
67
|
## What's New in v7.1.0 (2026-01-16)
|
|
61
68
|
|
|
62
69
|
- **Physical Constants**: Added SI unit constants for precision calculations (ALPHA_FS, LAMBDA_C, ALPHA_PROJECTION)
|
|
@@ -236,6 +243,12 @@ S_YM = F_xy.yang_mills_action()
|
|
|
236
243
|
|
|
237
244
|
## Changelog
|
|
238
245
|
|
|
246
|
+
### v7.1.1 (2026-02-05)
|
|
247
|
+
- **Curvature Fast Path**: Analytical curvature for analytic surfaces with optional toggle
|
|
248
|
+
- **Caching**: Curvature calculator reuse and last-call caching for repeated samples
|
|
249
|
+
- **Math Core**: Branchless cross product handedness selection
|
|
250
|
+
- **Build**: AVX2 / fast-math flags enabled by default for native builds
|
|
251
|
+
|
|
239
252
|
### v7.1.0 (2026-01-16)
|
|
240
253
|
- **Physical Constants**: Added SI unit constants (ALPHA_FS, LAMBDA_C, ALPHA_PROJECTION)
|
|
241
254
|
- **Projection Factor**: Implemented α = α_fs × λ_c ≈ 1.77×10⁻¹⁴ m for geometry-gauge coupling
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
coordinate_system/__init__.py,sha256=lLX288v0eoYvHbo7gp79n9_qlMQc1r07_EnRIBeyPn8,11136
|
|
2
|
+
coordinate_system/complex_geometric_physics.py,sha256=QxQLJa_Af2nbqjx1pcgzyBovoR01V8hRsGAromeo7lg,17045
|
|
3
|
+
coordinate_system/coordinate_system.cp313-win_amd64.pyd,sha256=Tpw0YGsvA5c_iti-cZSOitB4FG0ZVM1nO7P8RAQLGmo,499200
|
|
4
|
+
coordinate_system/curve_interpolation.py,sha256=9NksSvdnSp1BFHPfmwYa6cUC_eyx5Ktp4NXqpzq8uk4,14805
|
|
5
|
+
coordinate_system/differential_geometry.py,sha256=1PEe9CuH6FqEi9Io7YNIv1deL_-u1x2rbk4ZOGjA1TE,41842
|
|
6
|
+
coordinate_system/spectral_geometry.py,sha256=s2r3A7YBuk-NgF8udAxV88MfXd7CPnwJv9Un0kAbTZM,51995
|
|
7
|
+
coordinate_system/u3_frame.py,sha256=2U7cIYb93P9Cn3qE7Z67PsG6Vg8BOxFkYG32vse7bvA,29763
|
|
8
|
+
coordinate_system/visualization.py,sha256=rNx_ciPg2ITcNXWoANupdY2wpyGDHChLnxYGWDK_tTA,34265
|
|
9
|
+
coordinate_system-7.1.1.dist-info/LICENSE,sha256=tDnRkJxBYPzWdfh2gArRqrUPJxQZRZHJVs68qqBHIq4,1083
|
|
10
|
+
coordinate_system-7.1.1.dist-info/METADATA,sha256=sYug8arsNM4rXM1FvFDZkQNO8BlH5eIrj0YL_vz1gA0,11386
|
|
11
|
+
coordinate_system-7.1.1.dist-info/WHEEL,sha256=4-iQBlRoDdX1wfPofc7KLWa5Cys4eZSgXs6GVU8fKlQ,101
|
|
12
|
+
coordinate_system-7.1.1.dist-info/top_level.txt,sha256=R6LguuPPZ5esrIsDTqPGi9UxCvZPIXwn7KRKX87c79M,18
|
|
13
|
+
coordinate_system-7.1.1.dist-info/RECORD,,
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
coordinate_system/__init__.py,sha256=4uBZ1HbHqBkaC8fbAmwOzV05MRX_DED_yv33aRpDkdI,11136
|
|
2
|
-
coordinate_system/complex_geometric_physics.py,sha256=6BjYorC2LanmSe6_9hMoUcvpDuUJOAUtbi03-QzXBwU,17045
|
|
3
|
-
coordinate_system/coordinate_system.cp313-win_amd64.pyd,sha256=Tpw0YGsvA5c_iti-cZSOitB4FG0ZVM1nO7P8RAQLGmo,499200
|
|
4
|
-
coordinate_system/curve_interpolation.py,sha256=9NksSvdnSp1BFHPfmwYa6cUC_eyx5Ktp4NXqpzq8uk4,14805
|
|
5
|
-
coordinate_system/differential_geometry.py,sha256=7-82wvnL5czyBQw319jgNHBHUamSSK4PBlSdhBsfxYA,32292
|
|
6
|
-
coordinate_system/spectral_geometry.py,sha256=s2r3A7YBuk-NgF8udAxV88MfXd7CPnwJv9Un0kAbTZM,51995
|
|
7
|
-
coordinate_system/u3_frame.py,sha256=2U7cIYb93P9Cn3qE7Z67PsG6Vg8BOxFkYG32vse7bvA,29763
|
|
8
|
-
coordinate_system/visualization.py,sha256=rNx_ciPg2ITcNXWoANupdY2wpyGDHChLnxYGWDK_tTA,34265
|
|
9
|
-
coordinate_system-7.1.0.dist-info/LICENSE,sha256=tDnRkJxBYPzWdfh2gArRqrUPJxQZRZHJVs68qqBHIq4,1083
|
|
10
|
-
coordinate_system-7.1.0.dist-info/METADATA,sha256=gimpzb3wzTYLlSWE-uogZxP-zJ2HxywpL1Ei-DZ3L0Y,10539
|
|
11
|
-
coordinate_system-7.1.0.dist-info/WHEEL,sha256=4-iQBlRoDdX1wfPofc7KLWa5Cys4eZSgXs6GVU8fKlQ,101
|
|
12
|
-
coordinate_system-7.1.0.dist-info/top_level.txt,sha256=R6LguuPPZ5esrIsDTqPGi9UxCvZPIXwn7KRKX87c79M,18
|
|
13
|
-
coordinate_system-7.1.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|