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 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
@@ -16,4 +16,9 @@ def difference(a, b):
16
16
  bd=np.abs(d3) < np.abs(d1)
17
17
  d1[bd] = d3[bd]
18
18
 
19
- return d1
19
+ return d1
20
+
21
+
22
+ def wrap_to_pi(angles: npt.NDArray) -> npt.NDArray:
23
+ """Wrap angles to the range [-pi, pi]."""
24
+ return (angles + np.pi) % (2 * np.pi) - np.pi
@@ -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=2, color=colors.pop(0))
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 a.cos_angle_between(b) * abs(a)
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 is_perpendicular(a: Point, b: Point, tolerance=1e-6):
297
- return abs(a.dot(b)) < tolerance
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 min_angle_between(p1: Point, p2: Point):
302
- angle = angle_between(p1, p2) % np.pi
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 * 25)), minpoints),
33
+ npoints if npoints else max(int(np.ceil(duration * freq)), minpoints),
34
34
  )
35
35
  )
36
36
 
@@ -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.19
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,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.27.0
2
+ Generator: hatchling 1.28.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -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,,