coordinate-system 2.5.5__tar.gz → 3.0.0__tar.gz
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-2.5.5/coordinate_system.egg-info → coordinate_system-3.0.0}/PKG-INFO +37 -29
- {coordinate_system-2.5.5 → coordinate_system-3.0.0}/README.md +35 -27
- {coordinate_system-2.5.5 → coordinate_system-3.0.0}/coordinate_system/__init__.py +32 -22
- coordinate_system-3.0.0/coordinate_system/curvature.py +321 -0
- {coordinate_system-2.5.5 → coordinate_system-3.0.0}/coordinate_system/differential_geometry.py +286 -135
- {coordinate_system-2.5.5 → coordinate_system-3.0.0/coordinate_system.egg-info}/PKG-INFO +37 -29
- {coordinate_system-2.5.5 → coordinate_system-3.0.0}/coordinate_system_binding.cpp +9 -8
- {coordinate_system-2.5.5 → coordinate_system-3.0.0}/pmsys_minimal.hpp +4 -4
- {coordinate_system-2.5.5 → coordinate_system-3.0.0}/setup.py +3 -3
- coordinate_system-2.5.5/coordinate_system/curvature.py +0 -673
- {coordinate_system-2.5.5 → coordinate_system-3.0.0}/LICENSE +0 -0
- {coordinate_system-2.5.5 → coordinate_system-3.0.0}/MANIFEST.in +0 -0
- {coordinate_system-2.5.5 → coordinate_system-3.0.0}/MATHEMATICAL_FOUNDATION.md +0 -0
- {coordinate_system-2.5.5 → coordinate_system-3.0.0}/coordinate_system.egg-info/SOURCES.txt +0 -0
- {coordinate_system-2.5.5 → coordinate_system-3.0.0}/coordinate_system.egg-info/dependency_links.txt +0 -0
- {coordinate_system-2.5.5 → coordinate_system-3.0.0}/coordinate_system.egg-info/not-zip-safe +0 -0
- {coordinate_system-2.5.5 → coordinate_system-3.0.0}/coordinate_system.egg-info/top_level.txt +0 -0
- {coordinate_system-2.5.5 → coordinate_system-3.0.0}/setup.cfg +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: coordinate_system
|
|
3
|
-
Version:
|
|
4
|
-
Summary: High-performance 3D coordinate system library with Intrinsic Gradient Operator method for curvature computation, achieving machine-precision accuracy
|
|
3
|
+
Version: 3.0.0
|
|
4
|
+
Summary: High-performance 3D coordinate system library with right-handed conventions, Intrinsic Gradient Operator method for curvature computation, achieving machine-precision accuracy
|
|
5
5
|
Home-page: https://github.com/panguojun/Coordinate-System
|
|
6
6
|
Author: PanGuoJun
|
|
7
7
|
Author-email: 18858146@qq.com
|
|
@@ -48,20 +48,27 @@ License-File: LICENSE
|
|
|
48
48
|
[](LICENSE)
|
|
49
49
|
|
|
50
50
|
**Author:** PanGuoJun
|
|
51
|
-
**Version:**
|
|
51
|
+
**Version:** 3.0.0
|
|
52
52
|
**License:** MIT
|
|
53
53
|
|
|
54
|
-
## 🆕 What's New in
|
|
54
|
+
## 🆕 What's New in v3.0.0
|
|
55
55
|
|
|
56
|
-
**Critical
|
|
56
|
+
**Critical Coordinate System Update - Right-Hand System!**
|
|
57
57
|
|
|
58
|
-
-
|
|
59
|
-
-
|
|
60
|
-
-
|
|
61
|
-
-
|
|
62
|
-
-
|
|
58
|
+
- ⚠️ **BREAKING CHANGE: Right-Hand Coordinate System** - Unified all operations to standard right-hand coordinate system
|
|
59
|
+
- `vec3.cross()` now uses right-hand rule (standard mathematical definition)
|
|
60
|
+
- Quaternion rotations follow right-hand convention (counter-clockwise is positive)
|
|
61
|
+
- `coord3.look_at()` and `coord3.from_forward()` updated accordingly
|
|
62
|
+
- **Migration Guide:** See [HANDEDNESS_CHANGE.md](HANDEDNESS_CHANGE.md) for details
|
|
63
|
+
- `cross_left()` method retained for backward compatibility
|
|
64
|
+
- ✅ **Verified Correctness** - Complete test suite validates right-hand system behavior
|
|
65
|
+
- 📚 **Updated Documentation** - All examples and documentation reflect new coordinate system
|
|
66
|
+
- 🎯 **Enhanced Clarity** - Comments and docstrings clarified throughout
|
|
63
67
|
|
|
64
|
-
**
|
|
68
|
+
**Why This Change:**
|
|
69
|
+
1. Mathematical Standard: Right-hand system is the standard in mathematics and physics
|
|
70
|
+
2. Better Interoperability: Compatible with OpenGL, NumPy, SciPy, and most scientific libraries
|
|
71
|
+
3. Improved Readability: Standard cross product formulas match textbook definitions
|
|
65
72
|
|
|
66
73
|
Perfect for computational geometry, geometric analysis, and discrete differential geometry research!
|
|
67
74
|
|
|
@@ -106,15 +113,8 @@ Perfect for computational geometry, geometric analysis, and discrete differentia
|
|
|
106
113
|
|
|
107
114
|
For a comprehensive understanding of the mathematical principles behind coordinate systems, vectors, quaternions, and transformations, see our detailed mathematical guide:
|
|
108
115
|
|
|
109
|
-
**[📖 Mathematical Foundation of Coordinate Systems](https://github.com/panguojun/Coordinate-System
|
|
116
|
+
**[📖 Mathematical Foundation of Coordinate Systems](https://github.com/panguojun/Coordinate-System)**
|
|
110
117
|
|
|
111
|
-
This guide covers:
|
|
112
|
-
- Vector mathematics (dot product, cross product, projections)
|
|
113
|
-
- Quaternion theory and applications
|
|
114
|
-
- Coordinate system transformations
|
|
115
|
-
- Euler angles and gimbal lock
|
|
116
|
-
- Interpolation methods (LERP, SLERP, NLERP)
|
|
117
|
-
- Practical applications in graphics, physics, and robotics
|
|
118
118
|
|
|
119
119
|
---
|
|
120
120
|
|
|
@@ -192,19 +192,27 @@ lerped = vec3.lerp(v1, v2, 0.5) # Linear interpolation
|
|
|
192
192
|
|
|
193
193
|
## Coordinate System Type
|
|
194
194
|
|
|
195
|
-
This library uses a **
|
|
195
|
+
This library uses a **right-handed coordinate system** for all vector and quaternion operations (as of v3.0.0).
|
|
196
196
|
|
|
197
197
|
```
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
198
|
+
+Y
|
|
199
|
+
|
|
|
200
|
+
|
|
|
201
|
+
|
|
|
202
|
+
+-----> +X
|
|
203
|
+
/
|
|
204
|
+
/
|
|
205
|
+
+Z
|
|
206
206
|
```
|
|
207
207
|
|
|
208
|
+
**Right-Hand Rule:**
|
|
209
|
+
- Point your right hand's fingers along the +X axis
|
|
210
|
+
- Curl them toward the +Y axis
|
|
211
|
+
- Your thumb points along the +Z axis
|
|
212
|
+
- Cross product: **X × Y = Z** (standard mathematical definition)
|
|
213
|
+
|
|
214
|
+
**Migration from v2.x:** If your code relied on the previous left-handed system, see [HANDEDNESS_CHANGE.md](HANDEDNESS_CHANGE.md) for migration instructions.
|
|
215
|
+
|
|
208
216
|
---
|
|
209
217
|
|
|
210
218
|
## API Reference
|
|
@@ -425,7 +433,7 @@ v4 = v1 * 5 # vec3(5, 0, 0)
|
|
|
425
433
|
|
|
426
434
|
# Dot and cross products
|
|
427
435
|
dot = v1.dot(v2) # 0.0 (perpendicular)
|
|
428
|
-
cross = v1.cross(v2) # vec3(0, 0, 1) in
|
|
436
|
+
cross = v1.cross(v2) # vec3(0, 0, 1) in right-handed system (X × Y = Z)
|
|
429
437
|
|
|
430
438
|
# Length and normalization
|
|
431
439
|
length = v1.length() # 1.0
|
|
@@ -8,20 +8,27 @@
|
|
|
8
8
|
[](LICENSE)
|
|
9
9
|
|
|
10
10
|
**Author:** PanGuoJun
|
|
11
|
-
**Version:**
|
|
11
|
+
**Version:** 3.0.0
|
|
12
12
|
**License:** MIT
|
|
13
13
|
|
|
14
|
-
## 🆕 What's New in
|
|
14
|
+
## 🆕 What's New in v3.0.0
|
|
15
15
|
|
|
16
|
-
**Critical
|
|
16
|
+
**Critical Coordinate System Update - Right-Hand System!**
|
|
17
17
|
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
18
|
+
- ⚠️ **BREAKING CHANGE: Right-Hand Coordinate System** - Unified all operations to standard right-hand coordinate system
|
|
19
|
+
- `vec3.cross()` now uses right-hand rule (standard mathematical definition)
|
|
20
|
+
- Quaternion rotations follow right-hand convention (counter-clockwise is positive)
|
|
21
|
+
- `coord3.look_at()` and `coord3.from_forward()` updated accordingly
|
|
22
|
+
- **Migration Guide:** See [HANDEDNESS_CHANGE.md](HANDEDNESS_CHANGE.md) for details
|
|
23
|
+
- `cross_left()` method retained for backward compatibility
|
|
24
|
+
- ✅ **Verified Correctness** - Complete test suite validates right-hand system behavior
|
|
25
|
+
- 📚 **Updated Documentation** - All examples and documentation reflect new coordinate system
|
|
26
|
+
- 🎯 **Enhanced Clarity** - Comments and docstrings clarified throughout
|
|
23
27
|
|
|
24
|
-
**
|
|
28
|
+
**Why This Change:**
|
|
29
|
+
1. Mathematical Standard: Right-hand system is the standard in mathematics and physics
|
|
30
|
+
2. Better Interoperability: Compatible with OpenGL, NumPy, SciPy, and most scientific libraries
|
|
31
|
+
3. Improved Readability: Standard cross product formulas match textbook definitions
|
|
25
32
|
|
|
26
33
|
Perfect for computational geometry, geometric analysis, and discrete differential geometry research!
|
|
27
34
|
|
|
@@ -66,15 +73,8 @@ Perfect for computational geometry, geometric analysis, and discrete differentia
|
|
|
66
73
|
|
|
67
74
|
For a comprehensive understanding of the mathematical principles behind coordinate systems, vectors, quaternions, and transformations, see our detailed mathematical guide:
|
|
68
75
|
|
|
69
|
-
**[📖 Mathematical Foundation of Coordinate Systems](https://github.com/panguojun/Coordinate-System
|
|
76
|
+
**[📖 Mathematical Foundation of Coordinate Systems](https://github.com/panguojun/Coordinate-System)**
|
|
70
77
|
|
|
71
|
-
This guide covers:
|
|
72
|
-
- Vector mathematics (dot product, cross product, projections)
|
|
73
|
-
- Quaternion theory and applications
|
|
74
|
-
- Coordinate system transformations
|
|
75
|
-
- Euler angles and gimbal lock
|
|
76
|
-
- Interpolation methods (LERP, SLERP, NLERP)
|
|
77
|
-
- Practical applications in graphics, physics, and robotics
|
|
78
78
|
|
|
79
79
|
---
|
|
80
80
|
|
|
@@ -152,19 +152,27 @@ lerped = vec3.lerp(v1, v2, 0.5) # Linear interpolation
|
|
|
152
152
|
|
|
153
153
|
## Coordinate System Type
|
|
154
154
|
|
|
155
|
-
This library uses a **
|
|
155
|
+
This library uses a **right-handed coordinate system** for all vector and quaternion operations (as of v3.0.0).
|
|
156
156
|
|
|
157
157
|
```
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
158
|
+
+Y
|
|
159
|
+
|
|
|
160
|
+
|
|
|
161
|
+
|
|
|
162
|
+
+-----> +X
|
|
163
|
+
/
|
|
164
|
+
/
|
|
165
|
+
+Z
|
|
166
166
|
```
|
|
167
167
|
|
|
168
|
+
**Right-Hand Rule:**
|
|
169
|
+
- Point your right hand's fingers along the +X axis
|
|
170
|
+
- Curl them toward the +Y axis
|
|
171
|
+
- Your thumb points along the +Z axis
|
|
172
|
+
- Cross product: **X × Y = Z** (standard mathematical definition)
|
|
173
|
+
|
|
174
|
+
**Migration from v2.x:** If your code relied on the previous left-handed system, see [HANDEDNESS_CHANGE.md](HANDEDNESS_CHANGE.md) for migration instructions.
|
|
175
|
+
|
|
168
176
|
---
|
|
169
177
|
|
|
170
178
|
## API Reference
|
|
@@ -385,7 +393,7 @@ v4 = v1 * 5 # vec3(5, 0, 0)
|
|
|
385
393
|
|
|
386
394
|
# Dot and cross products
|
|
387
395
|
dot = v1.dot(v2) # 0.0 (perpendicular)
|
|
388
|
-
cross = v1.cross(v2) # vec3(0, 0, 1) in
|
|
396
|
+
cross = v1.cross(v2) # vec3(0, 0, 1) in right-handed system (X × Y = Z)
|
|
389
397
|
|
|
390
398
|
# Length and normalization
|
|
391
399
|
length = v1.length() # 1.0
|
|
@@ -4,7 +4,7 @@ from .coordinate_system import vec3, vec2
|
|
|
4
4
|
from .coordinate_system import quat
|
|
5
5
|
from .coordinate_system import coord3
|
|
6
6
|
|
|
7
|
-
# Differential geometry module (v3.
|
|
7
|
+
# Differential geometry module (v3.3.0+)
|
|
8
8
|
from .differential_geometry import (
|
|
9
9
|
# Classes
|
|
10
10
|
Surface,
|
|
@@ -17,7 +17,8 @@ from .differential_geometry import (
|
|
|
17
17
|
# Main functions
|
|
18
18
|
compute_intrinsic_gradient,
|
|
19
19
|
compute_gaussian_curvature,
|
|
20
|
-
|
|
20
|
+
compute_mean_curvature,
|
|
21
|
+
compute_riemann_curvature,
|
|
21
22
|
compute_all_curvatures,
|
|
22
23
|
)
|
|
23
24
|
|
|
@@ -30,9 +31,11 @@ from .curvature import (
|
|
|
30
31
|
principal_curvatures,
|
|
31
32
|
all_curvatures,
|
|
32
33
|
|
|
33
|
-
#
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
# Intrinsic Gradient Operator method
|
|
35
|
+
intrinsic_gradient_gaussian_curvature,
|
|
36
|
+
intrinsic_gradient_mean_curvature,
|
|
37
|
+
intrinsic_gradient_principal_curvatures,
|
|
38
|
+
intrinsic_gradient_all_curvatures,
|
|
36
39
|
compare_methods,
|
|
37
40
|
|
|
38
41
|
# Utility functions
|
|
@@ -41,30 +44,34 @@ from .curvature import (
|
|
|
41
44
|
richardson_extrapolation,
|
|
42
45
|
)
|
|
43
46
|
|
|
44
|
-
#
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
# Riemann curvature module (v3.4.0+)
|
|
48
|
+
from .riemann_curvature import (
|
|
49
|
+
# Classes
|
|
50
|
+
RiemannCurvatureCalculator,
|
|
51
|
+
|
|
52
|
+
# Main functions (renamed to avoid conflicts)
|
|
53
|
+
compute_riemann_curvature as compute_riemann_curvature_func,
|
|
54
|
+
compute_gaussian_curvature_riemann,
|
|
55
|
+
compute_full_riemann_tensor,
|
|
56
|
+
verify_riemann_properties,
|
|
51
57
|
)
|
|
52
58
|
|
|
53
59
|
__all__ = [
|
|
54
60
|
# Constants
|
|
55
61
|
'ZERO3','UNITX','UNITY','UNITZ','ONE3','ONE4','ONEC',
|
|
56
|
-
|
|
62
|
+
|
|
57
63
|
# Core types
|
|
58
64
|
'vec3', 'vec2', 'quat', 'coord3', 'lerp',
|
|
59
65
|
|
|
60
|
-
# Differential geometry classes (v3.
|
|
66
|
+
# Differential geometry classes (v3.3.0+)
|
|
61
67
|
'Surface', 'Sphere', 'Torus',
|
|
62
68
|
'MetricTensor', 'IntrinsicGradientOperator', 'IntrinsicGradientCurvatureCalculator',
|
|
63
69
|
|
|
64
|
-
# Differential geometry functions (v3.
|
|
70
|
+
# Differential geometry functions (v3.3.0+)
|
|
65
71
|
'compute_intrinsic_gradient',
|
|
66
72
|
'compute_gaussian_curvature',
|
|
67
|
-
'
|
|
73
|
+
'compute_mean_curvature',
|
|
74
|
+
'compute_riemann_curvature',
|
|
68
75
|
'compute_all_curvatures',
|
|
69
76
|
|
|
70
77
|
# High-precision curvature module - Classical method (v2.3.0+)
|
|
@@ -72,16 +79,19 @@ __all__ = [
|
|
|
72
79
|
'gaussian_curvature', 'mean_curvature',
|
|
73
80
|
'principal_curvatures', 'all_curvatures',
|
|
74
81
|
|
|
75
|
-
#
|
|
76
|
-
'LieGroupCurvatureCalculator',
|
|
77
|
-
'gaussian_curvature_lie',
|
|
78
|
-
'compare_methods',
|
|
79
|
-
|
|
80
|
-
# Intrinsic Gradient Operator method (v2.4.0+, merged into other modules)
|
|
82
|
+
# Intrinsic Gradient Operator method (v2.4.0+)
|
|
81
83
|
'intrinsic_gradient_gaussian_curvature',
|
|
82
84
|
'intrinsic_gradient_mean_curvature',
|
|
83
85
|
'intrinsic_gradient_principal_curvatures',
|
|
84
86
|
'intrinsic_gradient_all_curvatures',
|
|
87
|
+
'compare_methods',
|
|
88
|
+
|
|
89
|
+
# Riemann curvature module (v3.4.0+)
|
|
90
|
+
'RiemannCurvatureCalculator',
|
|
91
|
+
'compute_riemann_curvature_func',
|
|
92
|
+
'compute_gaussian_curvature_riemann',
|
|
93
|
+
'compute_full_riemann_tensor',
|
|
94
|
+
'verify_riemann_properties',
|
|
85
95
|
|
|
86
96
|
# Utility functions
|
|
87
97
|
'derivative_5pt', 'derivative_2nd_5pt', 'richardson_extrapolation',
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
"""
|
|
2
|
+
High-Precision Discrete Curvature Computation Module
|
|
3
|
+
====================================================
|
|
4
|
+
|
|
5
|
+
This module provides optimized discrete curvature computation methods
|
|
6
|
+
based on traditional differential geometry with high-order finite differences.
|
|
7
|
+
|
|
8
|
+
Author: PanGuoJun
|
|
9
|
+
Date: 2025-10-31
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import numpy as np
|
|
13
|
+
from typing import Tuple, Optional, Dict, List, Callable, Union
|
|
14
|
+
from .differential_geometry import (
|
|
15
|
+
Surface, MetricTensor, IntrinsicGradientOperator, IntrinsicGradientCurvatureCalculator,
|
|
16
|
+
compute_gaussian_curvature, compute_mean_curvature, compute_all_curvatures
|
|
17
|
+
)
|
|
18
|
+
from .coordinate_system import coord3, vec3
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# ========== High-Order Finite Difference Operators ==========
|
|
22
|
+
|
|
23
|
+
def derivative_5pt(f: Callable[[float], np.ndarray], x: float, h: float) -> np.ndarray:
|
|
24
|
+
"""
|
|
25
|
+
5-point finite difference formula for first derivative
|
|
26
|
+
"""
|
|
27
|
+
return (-f(x + 2*h) + 8*f(x + h) - 8*f(x - h) + f(x - 2*h)) / (12*h)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def derivative_2nd_5pt(f: Callable[[float], np.ndarray], x: float, h: float) -> np.ndarray:
|
|
31
|
+
"""
|
|
32
|
+
5-point finite difference formula for second derivative
|
|
33
|
+
"""
|
|
34
|
+
return (-f(x + 2*h) + 16*f(x + h) - 30*f(x) + 16*f(x - h) - f(x - 2*h)) / (12*h*h)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def richardson_extrapolation(f_h: float, f_2h: float, order: int = 4) -> float:
|
|
38
|
+
"""
|
|
39
|
+
Richardson extrapolation for accelerating convergence
|
|
40
|
+
"""
|
|
41
|
+
return (2**order * f_h - f_2h) / (2**order - 1)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# ========== Curvature Computation Class ==========
|
|
45
|
+
|
|
46
|
+
class CurvatureCalculator:
|
|
47
|
+
"""
|
|
48
|
+
High-precision discrete curvature calculator using classical differential geometry
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
def __init__(self, surface: Surface, step_size: float = 1e-3):
|
|
52
|
+
self.surface = surface
|
|
53
|
+
self.h = step_size
|
|
54
|
+
|
|
55
|
+
def _compute_derivatives(self, u: float, v: float) -> Dict[str, np.ndarray]:
|
|
56
|
+
"""使用更稳定的数值导数"""
|
|
57
|
+
# 避免过小的步长
|
|
58
|
+
effective_h = max(self.h, 1e-6)
|
|
59
|
+
|
|
60
|
+
# 使用中心差分
|
|
61
|
+
r_u = derivative_5pt(lambda uu: self._position_array(uu, v), u, effective_h)
|
|
62
|
+
r_v = derivative_5pt(lambda vv: self._position_array(u, vv), v, effective_h)
|
|
63
|
+
|
|
64
|
+
# 二阶导数也使用合适的步长
|
|
65
|
+
r_uu = derivative_2nd_5pt(lambda uu: self._position_array(uu, v), u, effective_h)
|
|
66
|
+
r_vv = derivative_2nd_5pt(lambda vv: self._position_array(u, vv), v, effective_h)
|
|
67
|
+
r_uv = derivative_5pt(
|
|
68
|
+
lambda vv: derivative_5pt(
|
|
69
|
+
lambda uu: self._position_array(uu, vv), u, effective_h
|
|
70
|
+
), v, effective_h
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
'r_u': r_u, 'r_v': r_v,
|
|
75
|
+
'r_uu': r_uu, 'r_vv': r_vv, 'r_uv': r_uv
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
def _position_array(self, u: float, v: float) -> np.ndarray:
|
|
79
|
+
"""Convert vec3 position to numpy array"""
|
|
80
|
+
pos = self.surface.position(u, v)
|
|
81
|
+
return np.array([pos.x, pos.y, pos.z])
|
|
82
|
+
|
|
83
|
+
def compute_fundamental_forms(self, u: float, v: float) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
|
|
84
|
+
"""
|
|
85
|
+
Compute first and second fundamental forms
|
|
86
|
+
"""
|
|
87
|
+
derivs = self._compute_derivatives(u, v)
|
|
88
|
+
r_u = derivs['r_u']
|
|
89
|
+
r_v = derivs['r_v']
|
|
90
|
+
r_uu = derivs['r_uu']
|
|
91
|
+
r_vv = derivs['r_vv']
|
|
92
|
+
r_uv = derivs['r_uv']
|
|
93
|
+
|
|
94
|
+
# First fundamental form
|
|
95
|
+
E = np.dot(r_u, r_u)
|
|
96
|
+
F = np.dot(r_u, r_v)
|
|
97
|
+
G = np.dot(r_v, r_v)
|
|
98
|
+
g = np.array([[E, F], [F, G]])
|
|
99
|
+
|
|
100
|
+
# Normal vector
|
|
101
|
+
n_vec = np.cross(r_u, r_v)
|
|
102
|
+
n_norm = np.linalg.norm(n_vec)
|
|
103
|
+
if n_norm > 1e-14:
|
|
104
|
+
n = n_vec / n_norm
|
|
105
|
+
else:
|
|
106
|
+
n = np.array([0., 0., 1.])
|
|
107
|
+
|
|
108
|
+
# Second fundamental form
|
|
109
|
+
L = np.dot(r_uu, n)
|
|
110
|
+
M = np.dot(r_uv, n)
|
|
111
|
+
N = np.dot(r_vv, n)
|
|
112
|
+
h = np.array([[L, M], [M, N]])
|
|
113
|
+
|
|
114
|
+
return g, h, n
|
|
115
|
+
|
|
116
|
+
def compute_gaussian_curvature(self, u: float, v: float) -> float:
|
|
117
|
+
"""
|
|
118
|
+
Compute Gaussian curvature K at a point
|
|
119
|
+
"""
|
|
120
|
+
g, h, _ = self.compute_fundamental_forms(u, v)
|
|
121
|
+
|
|
122
|
+
det_g = np.linalg.det(g)
|
|
123
|
+
det_h = np.linalg.det(h)
|
|
124
|
+
|
|
125
|
+
if abs(det_g) < 1e-14:
|
|
126
|
+
return 0.0
|
|
127
|
+
|
|
128
|
+
return det_h / det_g
|
|
129
|
+
|
|
130
|
+
def compute_mean_curvature(self, u: float, v: float) -> float:
|
|
131
|
+
"""
|
|
132
|
+
Compute mean curvature H at a point
|
|
133
|
+
"""
|
|
134
|
+
g, h, _ = self.compute_fundamental_forms(u, v)
|
|
135
|
+
|
|
136
|
+
det_g = np.linalg.det(g)
|
|
137
|
+
if abs(det_g) < 1e-14:
|
|
138
|
+
return 0.0
|
|
139
|
+
|
|
140
|
+
trace_term = g[1,1]*h[0,0] - 2*g[0,1]*h[0,1] + g[0,0]*h[1,1]
|
|
141
|
+
H = trace_term / (2 * det_g)
|
|
142
|
+
|
|
143
|
+
# 对于凸曲面,平均曲率应该是正的
|
|
144
|
+
return abs(H)
|
|
145
|
+
|
|
146
|
+
def compute_principal_curvatures(self, u: float, v: float) -> Tuple[float, float, np.ndarray, np.ndarray]:
|
|
147
|
+
"""
|
|
148
|
+
Compute principal curvatures and principal directions
|
|
149
|
+
"""
|
|
150
|
+
g, h, _ = self.compute_fundamental_forms(u, v)
|
|
151
|
+
derivs = self._compute_derivatives(u, v)
|
|
152
|
+
r_u = derivs['r_u']
|
|
153
|
+
r_v = derivs['r_v']
|
|
154
|
+
|
|
155
|
+
det_g = np.linalg.det(g)
|
|
156
|
+
if abs(det_g) < 1e-14:
|
|
157
|
+
return 0.0, 0.0, np.array([1., 0., 0.]), np.array([0., 1., 0.])
|
|
158
|
+
|
|
159
|
+
# Shape operator S = g⁻¹h
|
|
160
|
+
g_inv = np.linalg.inv(g)
|
|
161
|
+
S = g_inv @ h
|
|
162
|
+
|
|
163
|
+
# Eigenvalue decomposition
|
|
164
|
+
eigenvalues, eigenvectors = np.linalg.eig(S)
|
|
165
|
+
k1, k2 = eigenvalues.real
|
|
166
|
+
|
|
167
|
+
# Ensure k1 >= k2 (by absolute value)
|
|
168
|
+
if abs(k1) < abs(k2):
|
|
169
|
+
k1, k2 = k2, k1
|
|
170
|
+
eigenvectors = eigenvectors[:, [1, 0]]
|
|
171
|
+
|
|
172
|
+
# Convert tangent plane coordinates to 3D directions
|
|
173
|
+
dir1_2d = eigenvectors[:, 0]
|
|
174
|
+
dir2_2d = eigenvectors[:, 1]
|
|
175
|
+
|
|
176
|
+
dir1_3d = dir1_2d[0] * r_u + dir1_2d[1] * r_v
|
|
177
|
+
dir2_3d = dir2_2d[0] * r_u + dir2_2d[1] * r_v
|
|
178
|
+
|
|
179
|
+
# Normalize
|
|
180
|
+
dir1_3d = dir1_3d / (np.linalg.norm(dir1_3d) + 1e-14)
|
|
181
|
+
dir2_3d = dir2_3d / (np.linalg.norm(dir2_3d) + 1e-14)
|
|
182
|
+
|
|
183
|
+
return k1, k2, dir1_3d, dir2_3d
|
|
184
|
+
|
|
185
|
+
def compute_all_curvatures(self, u: float, v: float) -> Dict[str, Union[float, np.ndarray]]:
|
|
186
|
+
"""
|
|
187
|
+
Compute all curvature quantities at once
|
|
188
|
+
"""
|
|
189
|
+
g, h, n = self.compute_fundamental_forms(u, v)
|
|
190
|
+
K = self.compute_gaussian_curvature(u, v)
|
|
191
|
+
H = self.compute_mean_curvature(u, v)
|
|
192
|
+
k1, k2, dir1, dir2 = self.compute_principal_curvatures(u, v)
|
|
193
|
+
|
|
194
|
+
return {
|
|
195
|
+
'K': K,
|
|
196
|
+
'H': H,
|
|
197
|
+
'k1': k1,
|
|
198
|
+
'k2': k2,
|
|
199
|
+
'dir1': dir1,
|
|
200
|
+
'dir2': dir2,
|
|
201
|
+
'g': g,
|
|
202
|
+
'h': h,
|
|
203
|
+
'n': n
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
# ========== Simplified Interface Functions ==========
|
|
208
|
+
|
|
209
|
+
def gaussian_curvature_classical(surface: Surface, u: float, v: float, step_size: float = 1e-3) -> float:
|
|
210
|
+
"""Compute Gaussian curvature using classical method"""
|
|
211
|
+
calc = CurvatureCalculator(surface, step_size)
|
|
212
|
+
return calc.compute_gaussian_curvature(u, v)
|
|
213
|
+
|
|
214
|
+
def mean_curvature_classical(surface: Surface, u: float, v: float, step_size: float = 1e-3) -> float:
|
|
215
|
+
"""Compute mean curvature using classical method"""
|
|
216
|
+
calc = CurvatureCalculator(surface, step_size)
|
|
217
|
+
return calc.compute_mean_curvature(u, v)
|
|
218
|
+
|
|
219
|
+
def principal_curvatures_classical(surface: Surface, u: float, v: float, step_size: float = 1e-3) -> Tuple[float, float]:
|
|
220
|
+
"""Compute principal curvatures using classical method"""
|
|
221
|
+
calc = CurvatureCalculator(surface, step_size)
|
|
222
|
+
k1, k2, _, _ = calc.compute_principal_curvatures(u, v)
|
|
223
|
+
return k1, k2
|
|
224
|
+
|
|
225
|
+
def all_curvatures_classical(surface: Surface, u: float, v: float, step_size: float = 1e-3) -> Dict[str, Union[float, np.ndarray]]:
|
|
226
|
+
"""Compute all curvature quantities using classical method"""
|
|
227
|
+
calc = CurvatureCalculator(surface, step_size)
|
|
228
|
+
return calc.compute_all_curvatures(u, v)
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
# ========== Intrinsic Gradient Method Functions ==========
|
|
232
|
+
|
|
233
|
+
def intrinsic_gradient_gaussian_curvature(surface, u, v, step_size=1e-3):
|
|
234
|
+
"""Compute Gaussian curvature using intrinsic gradient method"""
|
|
235
|
+
return compute_gaussian_curvature(surface, u, v, step_size)
|
|
236
|
+
|
|
237
|
+
def intrinsic_gradient_mean_curvature(surface, u, v, step_size=1e-3):
|
|
238
|
+
"""Compute mean curvature using intrinsic gradient method"""
|
|
239
|
+
return compute_mean_curvature(surface, u, v, step_size)
|
|
240
|
+
|
|
241
|
+
def intrinsic_gradient_principal_curvatures(surface, u, v, step_size=1e-3):
|
|
242
|
+
"""Compute principal curvatures using intrinsic gradient method"""
|
|
243
|
+
result = compute_all_curvatures(surface, u, v, step_size)
|
|
244
|
+
return result['principal_curvatures']
|
|
245
|
+
|
|
246
|
+
def intrinsic_gradient_all_curvatures(surface, u, v, step_size=1e-3):
|
|
247
|
+
"""Compute all curvatures using intrinsic gradient method"""
|
|
248
|
+
return compute_all_curvatures(surface, u, v, step_size)
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
# ========== Method Comparison ==========
|
|
252
|
+
|
|
253
|
+
def compare_methods(surface: Surface, u: float, v: float, step_size: float = 1e-3) -> Dict[str, float]:
|
|
254
|
+
"""
|
|
255
|
+
Compare classical and intrinsic gradient curvature methods
|
|
256
|
+
"""
|
|
257
|
+
# Classical method
|
|
258
|
+
K_classical = gaussian_curvature_classical(surface, u, v, step_size)
|
|
259
|
+
|
|
260
|
+
# Intrinsic gradient method
|
|
261
|
+
K_intrinsic = intrinsic_gradient_gaussian_curvature(surface, u, v, step_size)
|
|
262
|
+
|
|
263
|
+
# Comparison
|
|
264
|
+
difference = abs(K_classical - K_intrinsic)
|
|
265
|
+
relative_error = difference / abs(K_classical) if abs(K_classical) > 1e-14 else 0.0
|
|
266
|
+
|
|
267
|
+
return {
|
|
268
|
+
'K_classical': K_classical,
|
|
269
|
+
'K_intrinsic': K_intrinsic,
|
|
270
|
+
'difference': difference,
|
|
271
|
+
'relative_error': relative_error
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
# ========== Backward Compatibility Functions ==========
|
|
276
|
+
|
|
277
|
+
def gaussian_curvature(surface: Surface, u: float, v: float, step_size: float = 1e-3) -> float:
|
|
278
|
+
"""Compute Gaussian curvature (default: intrinsic gradient method)"""
|
|
279
|
+
return intrinsic_gradient_gaussian_curvature(surface, u, v, step_size)
|
|
280
|
+
|
|
281
|
+
def mean_curvature(surface: Surface, u: float, v: float, step_size: float = 1e-3) -> float:
|
|
282
|
+
"""Compute mean curvature (default: intrinsic gradient method)"""
|
|
283
|
+
return intrinsic_gradient_mean_curvature(surface, u, v, step_size)
|
|
284
|
+
|
|
285
|
+
def principal_curvatures(surface: Surface, u: float, v: float, step_size: float = 1e-3) -> Tuple[float, float]:
|
|
286
|
+
"""Compute principal curvatures (default: intrinsic gradient method)"""
|
|
287
|
+
return intrinsic_gradient_principal_curvatures(surface, u, v, step_size)
|
|
288
|
+
|
|
289
|
+
def all_curvatures(surface: Surface, u: float, v: float, step_size: float = 1e-3) -> Dict[str, Union[float, np.ndarray]]:
|
|
290
|
+
"""Compute all curvature quantities (default: intrinsic gradient method)"""
|
|
291
|
+
return intrinsic_gradient_all_curvatures(surface, u, v, step_size)
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
# ========== Export ==========
|
|
295
|
+
|
|
296
|
+
__all__ = [
|
|
297
|
+
# Classical method
|
|
298
|
+
'CurvatureCalculator',
|
|
299
|
+
'gaussian_curvature_classical',
|
|
300
|
+
'mean_curvature_classical',
|
|
301
|
+
'principal_curvatures_classical',
|
|
302
|
+
'all_curvatures_classical',
|
|
303
|
+
|
|
304
|
+
# Intrinsic Gradient Operator method
|
|
305
|
+
'intrinsic_gradient_gaussian_curvature',
|
|
306
|
+
'intrinsic_gradient_mean_curvature',
|
|
307
|
+
'intrinsic_gradient_principal_curvatures',
|
|
308
|
+
'intrinsic_gradient_all_curvatures',
|
|
309
|
+
'compare_methods',
|
|
310
|
+
|
|
311
|
+
# Backward compatibility (default to intrinsic gradient)
|
|
312
|
+
'gaussian_curvature',
|
|
313
|
+
'mean_curvature',
|
|
314
|
+
'principal_curvatures',
|
|
315
|
+
'all_curvatures',
|
|
316
|
+
|
|
317
|
+
# Utility functions
|
|
318
|
+
'derivative_5pt',
|
|
319
|
+
'derivative_2nd_5pt',
|
|
320
|
+
'richardson_extrapolation',
|
|
321
|
+
]
|