engeom 0.2.11__tar.gz → 0.2.12__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.
- {engeom-0.2.11 → engeom-0.2.12}/Cargo.lock +1 -1
- {engeom-0.2.11 → engeom-0.2.12}/Cargo.toml +1 -1
- {engeom-0.2.11 → engeom-0.2.12}/PKG-INFO +1 -1
- {engeom-0.2.11 → engeom-0.2.12}/python/engeom/geom2.pyi +77 -0
- {engeom-0.2.11 → engeom-0.2.12}/python/engeom/geom3.pyi +65 -1
- {engeom-0.2.11 → engeom-0.2.12}/src/bounding.rs +12 -0
- {engeom-0.2.11 → engeom-0.2.12}/src/conversions.rs +14 -1
- {engeom-0.2.11 → engeom-0.2.12}/src/geom2.rs +76 -3
- {engeom-0.2.11 → engeom-0.2.12}/src/geom3.rs +36 -52
- {engeom-0.2.11 → engeom-0.2.12}/.github/workflows/CI.yml +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/.gitignore +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/.gitmodules +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/README.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/docs/airfoils/intro.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/docs/api/airfoil.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/docs/api/engeom.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/docs/api/geom2.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/docs/api/geom3.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/docs/api/metrology.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/docs/api/plot.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/docs/bounding_volumes.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/docs/curves.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/docs/images/surface_point_meas.svg +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/docs/index.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/docs/isometries.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/docs/meshes.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/docs/metrology.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/docs/numpy.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/docs/planes_circles_lines.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/docs/points_vectors.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/docs/surf_points.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/docs/svd_basis.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/.gitignore +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/Cargo.lock +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/Cargo.toml +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/README.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/docs/airfoils/camber.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/docs/airfoils/overview.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/docs/common/angles.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/docs/common/core_space.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/docs/common/discrete_domain.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/docs/common/images/surface_point_meas.svg +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/docs/common/svd_basis.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/docs/geom2/alignment.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/docs/geom2/curve.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/docs/geom2/point_collections.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/docs/geom2/shapes.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/docs/index.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/docs/javascripts/mathjax.js +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/docs/python_rust.md +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/mkdocs.yml +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/airfoil/camber.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/airfoil/edges.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/airfoil/helpers.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/airfoil/inscribed_circle.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/airfoil/orientation.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/airfoil.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/common/align.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/common/angles.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/common/convert_2d_3d.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/common/discrete_domain.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/common/indices.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/common/interval.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/common/kd_tree.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/common/points.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/common/poisson_disk.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/common/surface_point.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/common/svd_basis.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/common/vec_f64.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/common.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/errors.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/func1/common_functions.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/func1/polynomial.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/func1/series1.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/func1.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom2/aabb2.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom2/align2/jacobian.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom2/align2/points_to_curve.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom2/align2/rc_params2.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom2/align2.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom2/angles2.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom2/circle2.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom2/curve2.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom2/hull.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom2/line2.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom2/polyline2.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom2.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom3/align3/jacobian.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom3/align3/multi_param.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom3/align3/points_to_mesh.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom3/align3/rotations.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom3/align3.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom3/curve3.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom3/iso3.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom3/mesh/collisions.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom3/mesh/conformal.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom3/mesh/edges.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom3/mesh/faces.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom3/mesh/filtering.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom3/mesh/measurement.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom3/mesh/outline.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom3/mesh/patches.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom3/mesh/queries.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom3/mesh/sampling.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom3/mesh/uv_mapping.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom3/mesh.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom3/plane3.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom3/point_cloud.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom3/xyzwpr.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/geom3.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/io.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/lib.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/metrology/dimension.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/metrology/line_profiles.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/metrology/surface_deviation.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/metrology/tolerance.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/metrology/tolerance_map.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/metrology.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/raster3.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/sensor.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/stats.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/engeom/src/utility.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/mkdocs.yml +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/pyproject.toml +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/python/engeom/__init__.py +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/python/engeom/_plot/__init__.py +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/python/engeom/_plot/common.py +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/python/engeom/_plot/matplotlib.py +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/python/engeom/_plot/pyvista.py +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/python/engeom/airfoil/__init__.py +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/python/engeom/airfoil.pyi +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/python/engeom/align/__init__.py +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/python/engeom/align.pyi +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/python/engeom/engeom.pyi +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/python/engeom/geom2/__init__.py +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/python/engeom/geom3/__init__.py +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/python/engeom/metrology/__init__.py +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/python/engeom/metrology.pyi +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/python/engeom/plot.py +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/python/engeom/raster3/__init__.py +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/python/engeom/raster3.pyi +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/python/engeom/sensor/__init__.py +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/python/engeom/sensor.pyi +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/python/tests/test_all.py +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/python/tests/test_geom2_simple.py +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/python/tests/test_geom3_simple.py +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/src/airfoil.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/src/alignments.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/src/common.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/src/lib.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/src/mesh.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/src/metrology.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/src/raster.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/src/ray_casting.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/src/sensor.rs +0 -0
- {engeom-0.2.11 → engeom-0.2.12}/src/svd_basis.rs +0 -0
@@ -138,6 +138,22 @@ class Vector2(Iterable[float]):
|
|
138
138
|
"""
|
139
139
|
...
|
140
140
|
|
141
|
+
def with_x(self, x: float) -> Vector2:
|
142
|
+
"""
|
143
|
+
Return a new vector with the same y component as this vector, but with the x component set to the given value.
|
144
|
+
:param x: the new x component of the vector.
|
145
|
+
:return: a new vector with the same y component as this vector, but with the x component set to the given value.
|
146
|
+
"""
|
147
|
+
...
|
148
|
+
|
149
|
+
def with_y(self, y: float) -> Vector2:
|
150
|
+
"""
|
151
|
+
Return a new vector with the same x component as this vector, but with the y component set to the given value.
|
152
|
+
:param y: the new y component of the vector.
|
153
|
+
:return: a new vector with the same x component as this vector, but with the y component set to the given value.
|
154
|
+
"""
|
155
|
+
...
|
156
|
+
|
141
157
|
|
142
158
|
class Point2(Iterable[float]):
|
143
159
|
"""
|
@@ -243,6 +259,22 @@ class Point2(Iterable[float]):
|
|
243
259
|
"""
|
244
260
|
...
|
245
261
|
|
262
|
+
def with_x(self, x: float) -> Point2:
|
263
|
+
"""
|
264
|
+
Return a new point with the same y component as this point, but with the x component set to the given value.
|
265
|
+
:param x: the new x component of the point.
|
266
|
+
:return: a new point with the same y component as this point, but with the x component set to the given value.
|
267
|
+
"""
|
268
|
+
...
|
269
|
+
|
270
|
+
def with_y(self, y: float) -> Point2:
|
271
|
+
"""
|
272
|
+
Return a new point with the same x component as this point, but with the y component set to the given value.
|
273
|
+
:param y: the new y component of the point.
|
274
|
+
:return: a new point with the same x component as this point, but with the y component set to the given value.
|
275
|
+
"""
|
276
|
+
...
|
277
|
+
|
246
278
|
|
247
279
|
class SurfacePoint2:
|
248
280
|
"""
|
@@ -950,6 +982,43 @@ class Circle2:
|
|
950
982
|
"""
|
951
983
|
...
|
952
984
|
|
985
|
+
@staticmethod
|
986
|
+
def fitting(points: NDArray[float], guess: Circle2 | None = None, sigma: float | None = None) -> Circle2:
|
987
|
+
"""
|
988
|
+
Fit a circle to a set of points using an unconstrained Levenberg-Marquardt minimization of the sum of
|
989
|
+
squared errors between the points and the boundary of the circle.
|
990
|
+
|
991
|
+
The initial guess is used to provide a starting point for the optimization. If no guess is provided, the
|
992
|
+
unit circle will be used.
|
993
|
+
|
994
|
+
The sigma parameter is used to weight the points in the optimization. If no sigma is provided, all points
|
995
|
+
will be weighted equally, otherwise points beyond `sigma` standard deviations from the mean will be
|
996
|
+
assigned a weight of 0.0.
|
997
|
+
:param points: the points to fit the circle to.
|
998
|
+
:param guess: an optional initial guess for the circle. If None, the unit circle will be used.
|
999
|
+
:param sigma: an optional standard deviation to use for weighting the points. If None, all points will be
|
1000
|
+
weighted equally.
|
1001
|
+
:return: a new `Circle2` object representing the fitted circle.
|
1002
|
+
"""
|
1003
|
+
...
|
1004
|
+
|
1005
|
+
@staticmethod
|
1006
|
+
def ransac(points: NDArray[float], tol: float, iterations: int | None = None, min_r: float | None = None,
|
1007
|
+
max_r: float | None = None) -> Circle2:
|
1008
|
+
"""
|
1009
|
+
Fit a circle to a set of points using the RANSAC algorithm. The algorithm will randomly sample points from the
|
1010
|
+
input set and fit a circle to them, then check how many points are within the given tolerance of the fitted
|
1011
|
+
circle. The best fitting circle will be returned.
|
1012
|
+
|
1013
|
+
:param points: the points to fit the circle to.
|
1014
|
+
:param tol: the tolerance for the RANSAC algorithm.
|
1015
|
+
:param iterations: the number of iterations to run. If None, a default value of 500 will be used.
|
1016
|
+
:param min_r: the minimum radius of the circle. If None, no minimum will be enforced.
|
1017
|
+
:param max_r: the maximum radius of the circle. If None, no maximum will be enforced.
|
1018
|
+
:return: a new `Circle2` object representing the fitted circle.
|
1019
|
+
"""
|
1020
|
+
...
|
1021
|
+
|
953
1022
|
|
954
1023
|
class Arc2:
|
955
1024
|
"""
|
@@ -1148,3 +1217,11 @@ class Aabb2:
|
|
1148
1217
|
:return: a new AABB object with the shrunk bounds.
|
1149
1218
|
"""
|
1150
1219
|
...
|
1220
|
+
|
1221
|
+
def merged(self, other: Aabb2) -> Aabb2:
|
1222
|
+
"""
|
1223
|
+
Merge this AABB with another AABB and return a new AABB.
|
1224
|
+
:param other: the other AABB to merge with.
|
1225
|
+
:return: a new AABB object that is the result of merging this AABB with the other AABB.
|
1226
|
+
"""
|
1227
|
+
...
|
@@ -150,6 +150,33 @@ class Vector3(Iterable[float]):
|
|
150
150
|
"""
|
151
151
|
...
|
152
152
|
|
153
|
+
def with_x(self, x: float) -> Vector3:
|
154
|
+
"""
|
155
|
+
Return a new vector with the same y and z components as this vector, but with the x component set to the
|
156
|
+
specified value.
|
157
|
+
:param x: the new x component of the vector.
|
158
|
+
:return: a new vector with the specified x component.
|
159
|
+
"""
|
160
|
+
...
|
161
|
+
|
162
|
+
def with_y(self, y: float) -> Vector3:
|
163
|
+
"""
|
164
|
+
Return a new vector with the same x and z components as this vector, but with the y component set to the
|
165
|
+
specified value.
|
166
|
+
:param y: the new y component of the vector.
|
167
|
+
:return: a new vector with the specified y component.
|
168
|
+
"""
|
169
|
+
...
|
170
|
+
|
171
|
+
def with_z(self, z: float) -> Vector3:
|
172
|
+
"""
|
173
|
+
Return a new vector with the same x and y components as this vector, but with the z component set to the
|
174
|
+
specified value.
|
175
|
+
:param z: the new z component of the vector.
|
176
|
+
:return: a new vector with the specified z component.
|
177
|
+
"""
|
178
|
+
...
|
179
|
+
|
153
180
|
|
154
181
|
class Point3(Iterable[float]):
|
155
182
|
"""
|
@@ -267,6 +294,33 @@ class Point3(Iterable[float]):
|
|
267
294
|
"""
|
268
295
|
...
|
269
296
|
|
297
|
+
def with_x(self, x: float) -> Point3:
|
298
|
+
"""
|
299
|
+
Return a new point with the same y and z coordinates as this point, but with the x coordinate set to the
|
300
|
+
specified value.
|
301
|
+
:param x: the new x coordinate of the point.
|
302
|
+
:return: a new point with the specified x coordinate.
|
303
|
+
"""
|
304
|
+
...
|
305
|
+
|
306
|
+
def with_y(self, y: float) -> Point3:
|
307
|
+
"""
|
308
|
+
Return a new point with the same x and z coordinates as this point, but with the y coordinate set to the
|
309
|
+
specified value.
|
310
|
+
:param y: the new y coordinate of the point.
|
311
|
+
:return: a new point with the specified y coordinate.
|
312
|
+
"""
|
313
|
+
...
|
314
|
+
|
315
|
+
def with_z(self, z: float) -> Point3:
|
316
|
+
"""
|
317
|
+
Return a new point with the same x and y coordinates as this point, but with the z coordinate set to the
|
318
|
+
specified value.
|
319
|
+
:param z: the new z coordinate of the point.
|
320
|
+
:return: a new point with the specified z coordinate.
|
321
|
+
"""
|
322
|
+
...
|
323
|
+
|
270
324
|
|
271
325
|
class SurfacePoint3:
|
272
326
|
"""
|
@@ -1273,7 +1327,8 @@ class Mesh:
|
|
1273
1327
|
...
|
1274
1328
|
|
1275
1329
|
@staticmethod
|
1276
|
-
def create_rect_beam_between(p0: Point3, p1: Point3, width: float, height: float,
|
1330
|
+
def create_rect_beam_between(p0: Point3, p1: Point3, width: float, height: float,
|
1331
|
+
up: Vector3 | None = None) -> Mesh:
|
1277
1332
|
"""
|
1278
1333
|
Create a rectangular cross-sectioned prism between two points with a specified width and height. The prism will
|
1279
1334
|
be centered between the two points and oriented along the line connecting them. The up vector's projection onto
|
@@ -1687,6 +1742,15 @@ class Aabb3:
|
|
1687
1742
|
"""
|
1688
1743
|
...
|
1689
1744
|
|
1745
|
+
def merged(self, other: Aabb3) -> Aabb3:
|
1746
|
+
"""
|
1747
|
+
Merge this AABB with another AABB. The resulting AABB will be the smallest AABB that contains both AABBs.
|
1748
|
+
|
1749
|
+
:param other: the other AABB to merge with.
|
1750
|
+
:return: a new AABB object representing the merged bounds.
|
1751
|
+
"""
|
1752
|
+
...
|
1753
|
+
|
1690
1754
|
|
1691
1755
|
class RayBundle3:
|
1692
1756
|
"""
|
@@ -114,6 +114,12 @@ impl Aabb2 {
|
|
114
114
|
use parry2d_f64::bounding_volume::BoundingVolume;
|
115
115
|
Aabb2::from_inner(self.inner.tightened(d))
|
116
116
|
}
|
117
|
+
|
118
|
+
fn merged(&self, other: &Self) -> Self {
|
119
|
+
use parry2d_f64::bounding_volume::BoundingVolume;
|
120
|
+
let merged = self.get_inner().merged(other.get_inner());
|
121
|
+
Aabb2::from_inner(merged)
|
122
|
+
}
|
117
123
|
}
|
118
124
|
|
119
125
|
// ================================================================================================
|
@@ -238,4 +244,10 @@ impl Aabb3 {
|
|
238
244
|
use parry3d_f64::bounding_volume::BoundingVolume;
|
239
245
|
Aabb3::from_inner(self.inner.tightened(d))
|
240
246
|
}
|
247
|
+
|
248
|
+
fn merged(&self, other: &Self) -> Self {
|
249
|
+
use parry3d_f64::bounding_volume::BoundingVolume;
|
250
|
+
let merged = self.get_inner().merged(other.get_inner());
|
251
|
+
Aabb3::from_inner(merged)
|
252
|
+
}
|
241
253
|
}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
//! This module has conversion helpers for numpy arrays and other engeom types
|
2
2
|
|
3
3
|
use engeom::{Point2, Point3, Vector2, Vector3};
|
4
|
-
use numpy::ndarray::{ArrayD, ArrayViewD};
|
4
|
+
use numpy::ndarray::{ArrayD, ArrayView2, ArrayViewD};
|
5
5
|
use pyo3::exceptions::PyValueError;
|
6
6
|
use pyo3::PyResult;
|
7
7
|
|
@@ -83,6 +83,19 @@ pub fn array_to_vectors3(array: &ArrayViewD<'_, f64>) -> PyResult<Vec<Vector3>>
|
|
83
83
|
.collect())
|
84
84
|
}
|
85
85
|
|
86
|
+
pub fn array2_to_points2(array: &ArrayView2<'_, f64>) -> PyResult<Vec<Point2>> {
|
87
|
+
let shape = array.shape();
|
88
|
+
if shape.len() != 2 || shape[1] != 2 {
|
89
|
+
return Err(PyValueError::new_err("Expected Nx2 array of points"));
|
90
|
+
}
|
91
|
+
|
92
|
+
Ok(array
|
93
|
+
.rows()
|
94
|
+
.into_iter()
|
95
|
+
.map(|row| Point2::new(row[0], row[1]))
|
96
|
+
.collect())
|
97
|
+
}
|
98
|
+
|
86
99
|
pub fn array_to_points2(array: &ArrayViewD<'_, f64>) -> PyResult<Vec<Point2>> {
|
87
100
|
let shape = array.shape();
|
88
101
|
if shape.len() != 2 || shape[1] != 2 {
|
@@ -1,11 +1,14 @@
|
|
1
1
|
use crate::bounding::Aabb2;
|
2
2
|
use crate::common::Resample;
|
3
|
-
use crate::conversions::{
|
3
|
+
use crate::conversions::{
|
4
|
+
array2_to_points2, array_to_points2, array_to_vectors2, points_to_array2,
|
5
|
+
};
|
4
6
|
use crate::geom3::Point3;
|
5
7
|
use engeom::geom2::{HasBounds2, Line2};
|
6
|
-
use engeom::To3D;
|
8
|
+
use engeom::{BestFit, To3D};
|
9
|
+
use engeom::airfoil::OpenEdge;
|
7
10
|
use numpy::ndarray::{Array1, ArrayD};
|
8
|
-
use numpy::{IntoPyArray, PyArray1, PyArrayDyn, PyReadonlyArrayDyn};
|
11
|
+
use numpy::{IntoPyArray, PyArray1, PyArrayDyn, PyReadonlyArray2, PyReadonlyArrayDyn};
|
9
12
|
use pyo3::exceptions::PyValueError;
|
10
13
|
use pyo3::types::PyIterator;
|
11
14
|
use pyo3::{
|
@@ -136,6 +139,18 @@ impl Vector2 {
|
|
136
139
|
fn angle_to(&self, other: Vector2) -> f64 {
|
137
140
|
self.inner.angle(&other.inner)
|
138
141
|
}
|
142
|
+
|
143
|
+
fn with_x(&self, x: f64) -> Self {
|
144
|
+
Self {
|
145
|
+
inner: engeom::Vector2::new(x, self.inner.y),
|
146
|
+
}
|
147
|
+
}
|
148
|
+
|
149
|
+
fn with_y(&self, y: f64) -> Self {
|
150
|
+
Self {
|
151
|
+
inner: engeom::Vector2::new(self.inner.x, y),
|
152
|
+
}
|
153
|
+
}
|
139
154
|
}
|
140
155
|
|
141
156
|
// ================================================================================================
|
@@ -246,6 +261,18 @@ impl Point2 {
|
|
246
261
|
b.get_inner(),
|
247
262
|
))
|
248
263
|
}
|
264
|
+
|
265
|
+
fn with_x(&self, x: f64) -> Self {
|
266
|
+
Self {
|
267
|
+
inner: engeom::Point2::new(x, self.inner.y),
|
268
|
+
}
|
269
|
+
}
|
270
|
+
|
271
|
+
fn with_y(&self, y: f64) -> Self {
|
272
|
+
Self {
|
273
|
+
inner: engeom::Point2::new(self.inner.x, y),
|
274
|
+
}
|
275
|
+
}
|
249
276
|
}
|
250
277
|
|
251
278
|
// ================================================================================================
|
@@ -426,6 +453,52 @@ impl Circle2 {
|
|
426
453
|
fn point_at_angle(&self, angle: f64) -> Point2 {
|
427
454
|
Point2::from_inner(self.inner.point_at_angle(angle))
|
428
455
|
}
|
456
|
+
|
457
|
+
#[staticmethod]
|
458
|
+
#[pyo3(signature=(points, guess=None, sigma=None))]
|
459
|
+
fn fitting<'py>(
|
460
|
+
points: PyReadonlyArray2<'py, f64>,
|
461
|
+
guess: Option<Circle2>,
|
462
|
+
sigma: Option<f64>,
|
463
|
+
) -> PyResult<Self> {
|
464
|
+
let points = array2_to_points2(&points.as_array())?;
|
465
|
+
let guess = if let Some(c) = guess {
|
466
|
+
c.get_inner().clone()
|
467
|
+
} else {
|
468
|
+
engeom::Circle2::new(0.0, 0.0, 1.0)
|
469
|
+
};
|
470
|
+
|
471
|
+
let mode = if let Some(s) = sigma {
|
472
|
+
BestFit::Gaussian(s)
|
473
|
+
} else {
|
474
|
+
BestFit::All
|
475
|
+
};
|
476
|
+
|
477
|
+
let circle = engeom::Circle2::fitting_circle(&points, &guess, mode)
|
478
|
+
.map_err(|e| PyValueError::new_err(e.to_string()))?;
|
479
|
+
Ok(Self::from_inner(circle))
|
480
|
+
}
|
481
|
+
|
482
|
+
#[staticmethod]
|
483
|
+
#[pyo3(signature=(points, tol, iterations=None, min_r=None, max_r=None))]
|
484
|
+
fn ransac<'py>(
|
485
|
+
points: PyReadonlyArray2<'py, f64>,
|
486
|
+
tol: f64,
|
487
|
+
iterations: Option<usize>,
|
488
|
+
min_r: Option<f64>,
|
489
|
+
max_r: Option<f64>,
|
490
|
+
) -> PyResult<Self> {
|
491
|
+
let points = array2_to_points2(&points.as_array())?;
|
492
|
+
let result = engeom::Circle2::ransac(
|
493
|
+
&points,
|
494
|
+
tol,
|
495
|
+
iterations,
|
496
|
+
min_r,
|
497
|
+
max_r,
|
498
|
+
)
|
499
|
+
.map_err(|e| PyValueError::new_err(e.to_string()))?;
|
500
|
+
Ok(Self::from_inner(result))
|
501
|
+
}
|
429
502
|
}
|
430
503
|
|
431
504
|
// ================================================================================================
|
@@ -139,6 +139,24 @@ impl Vector3 {
|
|
139
139
|
fn angle_to(&self, other: Vector3) -> f64 {
|
140
140
|
self.inner.angle(&other.inner)
|
141
141
|
}
|
142
|
+
|
143
|
+
fn with_z(&self, z: f64) -> Self {
|
144
|
+
Self {
|
145
|
+
inner: engeom::Vector3::new(self.inner.x, self.inner.y, z),
|
146
|
+
}
|
147
|
+
}
|
148
|
+
|
149
|
+
fn with_x(&self, x: f64) -> Self {
|
150
|
+
Self {
|
151
|
+
inner: engeom::Vector3::new(x, self.inner.y, self.inner.z),
|
152
|
+
}
|
153
|
+
}
|
154
|
+
|
155
|
+
fn with_y(&self, y: f64) -> Self {
|
156
|
+
Self {
|
157
|
+
inner: engeom::Vector3::new(self.inner.x, y, self.inner.z),
|
158
|
+
}
|
159
|
+
}
|
142
160
|
}
|
143
161
|
|
144
162
|
// ================================================================================================
|
@@ -256,6 +274,24 @@ impl Point3 {
|
|
256
274
|
b.get_inner(),
|
257
275
|
))
|
258
276
|
}
|
277
|
+
|
278
|
+
fn with_x(&self, x: f64) -> Self {
|
279
|
+
Self {
|
280
|
+
inner: engeom::Point3::new(x, self.inner.y, self.inner.z),
|
281
|
+
}
|
282
|
+
}
|
283
|
+
|
284
|
+
fn with_y(&self, y: f64) -> Self {
|
285
|
+
Self {
|
286
|
+
inner: engeom::Point3::new(self.inner.x, y, self.inner.z),
|
287
|
+
}
|
288
|
+
}
|
289
|
+
|
290
|
+
fn with_z(&self, z: f64) -> Self {
|
291
|
+
Self {
|
292
|
+
inner: engeom::Point3::new(self.inner.x, self.inner.y, z),
|
293
|
+
}
|
294
|
+
}
|
259
295
|
}
|
260
296
|
|
261
297
|
// ================================================================================================
|
@@ -630,58 +666,6 @@ impl XyzWpr {
|
|
630
666
|
}
|
631
667
|
}
|
632
668
|
|
633
|
-
// #[pymethods]
|
634
|
-
// impl XyzWpr {
|
635
|
-
// #[new]
|
636
|
-
// fn new(x: f64, y: f64, z: f64, w: f64, p: f64, r: f64) -> Self {
|
637
|
-
// Self {
|
638
|
-
// inner: engeom::geom3::XyzWpr::new(x, y, z, w, p, r),
|
639
|
-
// }
|
640
|
-
// }
|
641
|
-
//
|
642
|
-
// #[getter]
|
643
|
-
// fn values(&self) -> Vec<f64> {
|
644
|
-
// vec![
|
645
|
-
// self.inner.x,
|
646
|
-
// self.inner.y,
|
647
|
-
// self.inner.z,
|
648
|
-
// self.inner.w,
|
649
|
-
// self.inner.p,
|
650
|
-
// self.inner.r,
|
651
|
-
// ]
|
652
|
-
// }
|
653
|
-
//
|
654
|
-
// #[getter]
|
655
|
-
// fn x(&self) -> f64 {
|
656
|
-
// self.inner.x
|
657
|
-
// }
|
658
|
-
//
|
659
|
-
// #[getter]
|
660
|
-
// fn y(&self) -> f64 {
|
661
|
-
// self.inner.y
|
662
|
-
// }
|
663
|
-
//
|
664
|
-
// #[getter]
|
665
|
-
// fn z(&self) -> f64 {
|
666
|
-
// self.inner.z
|
667
|
-
// }
|
668
|
-
//
|
669
|
-
// #[getter]
|
670
|
-
// fn w(&self) -> f64 {
|
671
|
-
// self.inner.w
|
672
|
-
// }
|
673
|
-
//
|
674
|
-
// #[getter]
|
675
|
-
// fn p(&self) -> f64 {
|
676
|
-
// self.inner.p
|
677
|
-
// }
|
678
|
-
//
|
679
|
-
// #[getter]
|
680
|
-
// fn r(&self) -> f64 {
|
681
|
-
// self.inner.r
|
682
|
-
// }
|
683
|
-
// }
|
684
|
-
|
685
669
|
#[derive(FromPyObject)]
|
686
670
|
enum Transformable3 {
|
687
671
|
Iso(Iso3),
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|