pfc-geometry 0.2.20__tar.gz → 0.2.21__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.
Files changed (34) hide show
  1. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/PKG-INFO +1 -2
  2. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/pyproject.toml +1 -2
  3. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/src/geometry/__init__.py +2 -1
  4. pfc_geometry-0.2.21/src/geometry/air.py +20 -0
  5. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/src/geometry/angles.py +6 -1
  6. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/src/geometry/coordinate_frame.py +4 -2
  7. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/src/geometry/point.py +13 -6
  8. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/src/geometry/time.py +2 -2
  9. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/src/geometry/transformation.py +2 -1
  10. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/tests/test_quaternion.py +0 -2
  11. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/.dockerignore +0 -0
  12. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/.github/workflows/publish_pypi.yml +0 -0
  13. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/.gitignore +0 -0
  14. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/LICENSE +0 -0
  15. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/README.md +0 -0
  16. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/src/geometry/base.py +0 -0
  17. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/src/geometry/checks.py +0 -0
  18. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/src/geometry/gps.py +0 -0
  19. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/src/geometry/mass.py +0 -0
  20. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/src/geometry/py.typed +0 -0
  21. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/src/geometry/quaternion.py +0 -0
  22. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/src/geometry/utils.py +0 -0
  23. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/tests/__init__.py +0 -0
  24. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/tests/test_angles.py +0 -0
  25. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/tests/test_base.py +0 -0
  26. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/tests/test_coord.py +0 -0
  27. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/tests/test_gps.py +0 -0
  28. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/tests/test_mass.py +0 -0
  29. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/tests/test_point.py +0 -0
  30. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/tests/test_remove_outliers.csv +0 -0
  31. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/tests/test_time.py +0 -0
  32. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/tests/test_transform.py +0 -0
  33. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/tests/test_utils.py +0 -0
  34. {pfc_geometry-0.2.20 → pfc_geometry-0.2.21}/uv.lock +0 -0
@@ -1,10 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pfc-geometry
3
- Version: 0.2.20
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
@@ -1,11 +1,10 @@
1
1
  [project]
2
2
  name = "pfc-geometry"
3
- version="0.2.20"
3
+ version="0.2.21"
4
4
  description = "A library for working with 3D geometry."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
7
7
  dependencies = [
8
- "numpy-quaternion>=2024.0.7",
9
8
  "numpy>=2.1.3",
10
9
  "pandas>=2.2.3",
11
10
  "rowan>=1.3.2",
@@ -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))
@@ -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))
@@ -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
@@ -272,7 +272,7 @@ def angle_between(a: Point, b: Point) -> np.ndarray:
272
272
 
273
273
  @ppmeth
274
274
  def scalar_projection(a: Point, b: Point) -> Point:
275
- return a.cos_angle_between(b) * abs(a)
275
+ return cos_angle_between(a, b) * abs(a)
276
276
 
277
277
 
278
278
  @ppmeth
@@ -284,21 +284,28 @@ def vector_projection(a: Point, b: Point) -> Point:
284
284
  def vector_rejection(a: Point, b: Point) -> Point:
285
285
  return a - ((Point.dot(a, b)) / Point.dot(b, b)) * b
286
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)
287
291
 
288
292
  @ppmeth
289
293
  def is_parallel(a: Point, b: Point, tolerance=1e-6):
290
294
  return abs(a.cos_angle_between(b) - 1) < tolerance
291
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
+
292
300
 
293
301
  @ppmeth
294
- def is_perpendicular(a: Point, b: Point, tolerance=1e-6):
295
- 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
296
304
 
297
305
 
298
306
  @ppmeth
299
- def min_angle_between(p1: Point, p2: Point):
300
- angle = angle_between(p1, p2) % np.pi
301
- 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
302
309
 
303
310
 
304
311
  def vector_norm(point: Point):
@@ -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,
@@ -6,8 +6,6 @@ from geometry.checks import assert_almost_equal
6
6
  import pandas as pd
7
7
  import numpy as np
8
8
 
9
- import quaternion
10
-
11
9
  def test_init():
12
10
  data = np.random.random((500,4))
13
11
  qs = Quaternion(data)
File without changes
File without changes
File without changes
File without changes