pfc-geometry 0.2.19__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.19 → pfc_geometry-0.2.21}/PKG-INFO +1 -2
  2. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/pyproject.toml +1 -2
  3. {pfc_geometry-0.2.19 → 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.19 → pfc_geometry-0.2.21}/src/geometry/angles.py +6 -1
  6. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/src/geometry/coordinate_frame.py +4 -2
  7. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/src/geometry/point.py +13 -8
  8. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/src/geometry/time.py +2 -2
  9. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/src/geometry/transformation.py +2 -1
  10. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/tests/test_quaternion.py +0 -2
  11. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/.dockerignore +0 -0
  12. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/.github/workflows/publish_pypi.yml +0 -0
  13. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/.gitignore +0 -0
  14. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/LICENSE +0 -0
  15. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/README.md +0 -0
  16. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/src/geometry/base.py +0 -0
  17. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/src/geometry/checks.py +0 -0
  18. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/src/geometry/gps.py +0 -0
  19. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/src/geometry/mass.py +0 -0
  20. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/src/geometry/py.typed +0 -0
  21. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/src/geometry/quaternion.py +0 -0
  22. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/src/geometry/utils.py +0 -0
  23. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/tests/__init__.py +0 -0
  24. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/tests/test_angles.py +0 -0
  25. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/tests/test_base.py +0 -0
  26. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/tests/test_coord.py +0 -0
  27. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/tests/test_gps.py +0 -0
  28. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/tests/test_mass.py +0 -0
  29. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/tests/test_point.py +0 -0
  30. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/tests/test_remove_outliers.csv +0 -0
  31. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/tests/test_time.py +0 -0
  32. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/tests/test_transform.py +0 -0
  33. {pfc_geometry-0.2.19 → pfc_geometry-0.2.21}/tests/test_utils.py +0 -0
  34. {pfc_geometry-0.2.19 → 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.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
@@ -1,11 +1,10 @@
1
1
  [project]
2
2
  name = "pfc-geometry"
3
- version="0.2.19"
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
@@ -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):
@@ -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