pfc-geometry 0.2.19__py3-none-any.whl → 0.2.21__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.
- geometry/__init__.py +2 -1
- geometry/air.py +20 -0
- geometry/angles.py +6 -1
- geometry/coordinate_frame.py +4 -2
- geometry/point.py +13 -8
- geometry/time.py +2 -2
- geometry/transformation.py +2 -1
- {pfc_geometry-0.2.19.dist-info → pfc_geometry-0.2.21.dist-info}/METADATA +1 -2
- pfc_geometry-0.2.21.dist-info/RECORD +18 -0
- {pfc_geometry-0.2.19.dist-info → pfc_geometry-0.2.21.dist-info}/WHEEL +1 -1
- pfc_geometry-0.2.19.dist-info/RECORD +0 -17
- {pfc_geometry-0.2.19.dist-info → pfc_geometry-0.2.21.dist-info}/licenses/LICENSE +0 -0
geometry/__init__.py
CHANGED
|
@@ -18,7 +18,8 @@ from .gps import GPS
|
|
|
18
18
|
from .coordinate_frame import Coord
|
|
19
19
|
from .transformation import Transformation
|
|
20
20
|
from .mass import Mass
|
|
21
|
-
|
|
21
|
+
from .air import Air
|
|
22
|
+
from .angles import wrap_to_pi
|
|
22
23
|
|
|
23
24
|
def Euler(*args, **kwargs) -> Quaternion:
|
|
24
25
|
return Quaternion.from_euler(Point(*args, **kwargs))
|
geometry/air.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from geometry.base import Base
|
|
2
|
+
|
|
3
|
+
R = 287.058
|
|
4
|
+
GAMMA = 1.4
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def get_rho(pressure, temperature):
|
|
8
|
+
return pressure / (R * temperature)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Air(Base):
|
|
12
|
+
cols = ["P", "T", "rho"]
|
|
13
|
+
|
|
14
|
+
@staticmethod
|
|
15
|
+
def iso_sea_level(length: int):
|
|
16
|
+
return Air(101325, 288.15, get_rho(101325, 288.15)).tile(length)
|
|
17
|
+
|
|
18
|
+
@staticmethod
|
|
19
|
+
def from_pt(pressure, temperature):
|
|
20
|
+
return Air(pressure, temperature, get_rho(pressure, temperature))
|
geometry/angles.py
CHANGED
geometry/coordinate_frame.py
CHANGED
|
@@ -88,7 +88,7 @@ class Coord(Base):
|
|
|
88
88
|
def axes(self):
|
|
89
89
|
return Point.concatenate([self.x_axis, self.y_axis, self.z_axis])
|
|
90
90
|
|
|
91
|
-
def plot(self, fig=None, scale=1, label: str = None):
|
|
91
|
+
def plot(self, fig=None, scale=1, width=2, label: str = None):
|
|
92
92
|
import plotly.graph_objects as go
|
|
93
93
|
if fig is None:
|
|
94
94
|
fig = go.Figure(layout=dict(scene=dict(aspectmode="data")))
|
|
@@ -105,6 +105,7 @@ class Coord(Base):
|
|
|
105
105
|
mode="markers",
|
|
106
106
|
name="Origin",
|
|
107
107
|
marker=dict(size=5, color="black"),
|
|
108
|
+
showlegend=False
|
|
108
109
|
)
|
|
109
110
|
)
|
|
110
111
|
colors = ["red", "green", "blue"]
|
|
@@ -116,7 +117,8 @@ class Coord(Base):
|
|
|
116
117
|
z=[self.origin.z[0], (self.origin.z + axis.z * scale)[0]],
|
|
117
118
|
mode="lines",
|
|
118
119
|
name=f"{label or 'Axis'} {Point.cols[i]}",
|
|
119
|
-
line=dict(width=
|
|
120
|
+
line=dict(width=width, color=colors.pop(0)),
|
|
121
|
+
showlegend=False
|
|
120
122
|
)
|
|
121
123
|
)
|
|
122
124
|
return fig
|
geometry/point.py
CHANGED
|
@@ -12,8 +12,6 @@ this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
12
12
|
|
|
13
13
|
from __future__ import annotations
|
|
14
14
|
from typing import Literal
|
|
15
|
-
|
|
16
|
-
from sqlalchemy import literal
|
|
17
15
|
from .base import Base
|
|
18
16
|
import numpy as np
|
|
19
17
|
import pandas as pd
|
|
@@ -274,7 +272,7 @@ def angle_between(a: Point, b: Point) -> np.ndarray:
|
|
|
274
272
|
|
|
275
273
|
@ppmeth
|
|
276
274
|
def scalar_projection(a: Point, b: Point) -> Point:
|
|
277
|
-
return
|
|
275
|
+
return cos_angle_between(a, b) * abs(a)
|
|
278
276
|
|
|
279
277
|
|
|
280
278
|
@ppmeth
|
|
@@ -286,21 +284,28 @@ def vector_projection(a: Point, b: Point) -> Point:
|
|
|
286
284
|
def vector_rejection(a: Point, b: Point) -> Point:
|
|
287
285
|
return a - ((Point.dot(a, b)) / Point.dot(b, b)) * b
|
|
288
286
|
|
|
287
|
+
@ppmeth
|
|
288
|
+
def min_angle_between(p1: Point, p2: Point):
|
|
289
|
+
angle = angle_between(p1, p2) % np.pi
|
|
290
|
+
return np.minimum(angle, np.pi - angle)
|
|
289
291
|
|
|
290
292
|
@ppmeth
|
|
291
293
|
def is_parallel(a: Point, b: Point, tolerance=1e-6):
|
|
292
294
|
return abs(a.cos_angle_between(b) - 1) < tolerance
|
|
293
295
|
|
|
296
|
+
@ppmeth
|
|
297
|
+
def is_anti_parallel(a: Point, b: Point, tolerance=1e-6):
|
|
298
|
+
return abs(a.cos_angle_between(-b) - 1) < tolerance
|
|
299
|
+
|
|
294
300
|
|
|
295
301
|
@ppmeth
|
|
296
|
-
def
|
|
297
|
-
return
|
|
302
|
+
def is_either_parallel(a: Point, b: Point, tolerance=1e-6):
|
|
303
|
+
return min_angle_between(a, b) < tolerance
|
|
298
304
|
|
|
299
305
|
|
|
300
306
|
@ppmeth
|
|
301
|
-
def
|
|
302
|
-
|
|
303
|
-
return np.minimum(angle, np.pi - angle)
|
|
307
|
+
def is_perpendicular(a: Point, b: Point, tolerance=1e-6):
|
|
308
|
+
return abs(a.dot(b)) < tolerance
|
|
304
309
|
|
|
305
310
|
|
|
306
311
|
def vector_norm(point: Point):
|
geometry/time.py
CHANGED
|
@@ -25,12 +25,12 @@ class Time(Base):
|
|
|
25
25
|
return Time(t, dt)
|
|
26
26
|
|
|
27
27
|
@staticmethod
|
|
28
|
-
def uniform(duration: float, npoints: int | None, minpoints: int = 1) -> Time:
|
|
28
|
+
def uniform(duration: float, npoints: int | None, minpoints: int = 1, freq=25) -> Time:
|
|
29
29
|
return Time.from_t(
|
|
30
30
|
np.linspace(
|
|
31
31
|
0,
|
|
32
32
|
duration,
|
|
33
|
-
npoints if npoints else max(int(np.ceil(duration *
|
|
33
|
+
npoints if npoints else max(int(np.ceil(duration * freq)), minpoints),
|
|
34
34
|
)
|
|
35
35
|
)
|
|
36
36
|
|
geometry/transformation.py
CHANGED
|
@@ -9,6 +9,7 @@ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
|
9
9
|
You should have received a copy of the GNU General Public License along with
|
|
10
10
|
this program. If not, see <http://www.gnu.org/licenses/>.
|
|
11
11
|
"""
|
|
12
|
+
from __future__ import annotations
|
|
12
13
|
from geometry import Base, Point, Quaternion, P0, Q0, Coord
|
|
13
14
|
|
|
14
15
|
import numpy as np
|
|
@@ -54,7 +55,7 @@ class Transformation(Base):
|
|
|
54
55
|
raise AttributeError(name)
|
|
55
56
|
|
|
56
57
|
@staticmethod
|
|
57
|
-
def build(p:Point, q:Quaternion):
|
|
58
|
+
def build(p:Point, q:Quaternion) -> Transformation:
|
|
58
59
|
if len(p) == len(q):
|
|
59
60
|
return Transformation(np.concatenate([
|
|
60
61
|
p.data,
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pfc-geometry
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.21
|
|
4
4
|
Summary: A library for working with 3D geometry.
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Requires-Python: >=3.12
|
|
7
|
-
Requires-Dist: numpy-quaternion>=2024.0.7
|
|
8
7
|
Requires-Dist: numpy>=2.1.3
|
|
9
8
|
Requires-Dist: pandas>=2.2.3
|
|
10
9
|
Requires-Dist: rowan>=1.3.2
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
geometry/__init__.py,sha256=YT9pVH7zbfi26MLehrcCjcBf39aiCeq8aMuTtB3hC8Y,1133
|
|
2
|
+
geometry/air.py,sha256=cmOoUiVYmCWccDAy_7u-bfOvkKnRW5gWUxcD8X-ukvM,443
|
|
3
|
+
geometry/angles.py,sha256=OxuYcjFGexuOputr_eo9xHXnGCc44H3o3S5GQPp1geY,630
|
|
4
|
+
geometry/base.py,sha256=6bM4J7VGhstel6qu-C4xU39vU4dZ71S9FZMY9Y7xDZY,14966
|
|
5
|
+
geometry/checks.py,sha256=o8yMBAdU5Vy0EspBYaof4fPGgRSFZhRDhzBjRPsLd0M,375
|
|
6
|
+
geometry/coordinate_frame.py,sha256=FeQn7TBAnbik4Rv0ErDUCaY-W480trVYspH46uS1NXw,4442
|
|
7
|
+
geometry/gps.py,sha256=EsokABt40ZoltpAQfKrRc4kA-Lc2ScP_ltJNF7pvAWc,3654
|
|
8
|
+
geometry/mass.py,sha256=BUWBSITwpdRfpJR5-oJTd16BI7FLZt8rhxdzr0cx1HY,1675
|
|
9
|
+
geometry/point.py,sha256=zsF7LVvwdVPsH-17RTPDiE-FqDpo1BiaDn6DosOLuwo,8716
|
|
10
|
+
geometry/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
+
geometry/quaternion.py,sha256=dZwpViiVPwHUhRk7DhOwNab3pLhIWXyHk3DVh9mukSk,12143
|
|
12
|
+
geometry/time.py,sha256=VQEklZtZkwMthMsrH5QT83V8e3n78S06fWjyEqLHYbk,2706
|
|
13
|
+
geometry/transformation.py,sha256=-FQ_55l3_MykSQQuEIJ3MqWS5MHKR0HNWWCKpEEgRT0,5592
|
|
14
|
+
geometry/utils.py,sha256=q7-aaxDzRDwl78-3XzdpcJuh5iL7I8lN5agk2WNWjSY,3443
|
|
15
|
+
pfc_geometry-0.2.21.dist-info/METADATA,sha256=oDLhxh45eF3JL3JBtv_qZM8c9j9S6vgCqL8tt2xFzR4,1587
|
|
16
|
+
pfc_geometry-0.2.21.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
17
|
+
pfc_geometry-0.2.21.dist-info/licenses/LICENSE,sha256=z72U6pv-bQgJ_Svr4uCXnMjemsp38aSerhHEdEAOMJ4,7632
|
|
18
|
+
pfc_geometry-0.2.21.dist-info/RECORD,,
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
geometry/__init__.py,sha256=Qipz0oxyBg-C_-sFLVI8LKW9Yq8_keR-CbyuseAvTGg,1082
|
|
2
|
-
geometry/angles.py,sha256=Gw4PXr2kQMvvKECsugmi5kNiqOnK8T3PZSo3IKUpxPY,480
|
|
3
|
-
geometry/base.py,sha256=6bM4J7VGhstel6qu-C4xU39vU4dZ71S9FZMY9Y7xDZY,14966
|
|
4
|
-
geometry/checks.py,sha256=o8yMBAdU5Vy0EspBYaof4fPGgRSFZhRDhzBjRPsLd0M,375
|
|
5
|
-
geometry/coordinate_frame.py,sha256=6KzRu0sSPzmHj5vLIuX5Efi0OWdEF6gQtKPf63wsaRk,4358
|
|
6
|
-
geometry/gps.py,sha256=EsokABt40ZoltpAQfKrRc4kA-Lc2ScP_ltJNF7pvAWc,3654
|
|
7
|
-
geometry/mass.py,sha256=BUWBSITwpdRfpJR5-oJTd16BI7FLZt8rhxdzr0cx1HY,1675
|
|
8
|
-
geometry/point.py,sha256=M_drBU0z4qMih1Iquy92f5PZNqnRmGvqXLyuQnN9CfE,8509
|
|
9
|
-
geometry/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
-
geometry/quaternion.py,sha256=dZwpViiVPwHUhRk7DhOwNab3pLhIWXyHk3DVh9mukSk,12143
|
|
11
|
-
geometry/time.py,sha256=VTfMHLxhcws8YESYvxxP8W_vSePvl4lwKRXHxFWhJeA,2695
|
|
12
|
-
geometry/transformation.py,sha256=wnxoDN9-IeapVlrS_Da4hXyxtPCyoa_UcCsB8QVgxuo,5539
|
|
13
|
-
geometry/utils.py,sha256=q7-aaxDzRDwl78-3XzdpcJuh5iL7I8lN5agk2WNWjSY,3443
|
|
14
|
-
pfc_geometry-0.2.19.dist-info/METADATA,sha256=nvPgPFp1VzTmqFa0B7i5YJ6NmcaMvu9Aek0KQlEv2zM,1629
|
|
15
|
-
pfc_geometry-0.2.19.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
16
|
-
pfc_geometry-0.2.19.dist-info/licenses/LICENSE,sha256=z72U6pv-bQgJ_Svr4uCXnMjemsp38aSerhHEdEAOMJ4,7632
|
|
17
|
-
pfc_geometry-0.2.19.dist-info/RECORD,,
|
|
File without changes
|