engeom 0.2.10__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.10 → engeom-0.2.12}/Cargo.lock +1 -1
- {engeom-0.2.10 → engeom-0.2.12}/Cargo.toml +1 -1
- {engeom-0.2.10 → engeom-0.2.12}/PKG-INFO +1 -1
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom3/mesh.rs +68 -21
- engeom-0.2.12/engeom/src/geom3/xyzwpr.rs +141 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom3.rs +2 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/lib.rs +4 -0
- {engeom-0.2.10 → engeom-0.2.12}/python/engeom/geom2.pyi +77 -0
- {engeom-0.2.10 → engeom-0.2.12}/python/engeom/geom3.pyi +187 -14
- {engeom-0.2.10 → engeom-0.2.12}/src/bounding.rs +12 -0
- {engeom-0.2.10 → engeom-0.2.12}/src/conversions.rs +14 -1
- {engeom-0.2.10 → engeom-0.2.12}/src/geom2.rs +76 -3
- {engeom-0.2.10 → engeom-0.2.12}/src/geom3.rs +75 -2
- {engeom-0.2.10 → engeom-0.2.12}/src/mesh.rs +72 -12
- {engeom-0.2.10 → engeom-0.2.12}/.github/workflows/CI.yml +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/.gitignore +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/.gitmodules +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/README.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/docs/airfoils/intro.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/docs/api/airfoil.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/docs/api/engeom.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/docs/api/geom2.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/docs/api/geom3.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/docs/api/metrology.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/docs/api/plot.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/docs/bounding_volumes.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/docs/curves.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/docs/images/surface_point_meas.svg +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/docs/index.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/docs/isometries.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/docs/meshes.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/docs/metrology.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/docs/numpy.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/docs/planes_circles_lines.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/docs/points_vectors.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/docs/surf_points.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/docs/svd_basis.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/.gitignore +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/Cargo.lock +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/Cargo.toml +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/README.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/docs/airfoils/camber.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/docs/airfoils/overview.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/docs/common/angles.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/docs/common/core_space.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/docs/common/discrete_domain.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/docs/common/images/surface_point_meas.svg +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/docs/common/svd_basis.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/docs/geom2/alignment.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/docs/geom2/curve.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/docs/geom2/point_collections.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/docs/geom2/shapes.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/docs/index.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/docs/javascripts/mathjax.js +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/docs/python_rust.md +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/mkdocs.yml +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/airfoil/camber.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/airfoil/edges.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/airfoil/helpers.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/airfoil/inscribed_circle.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/airfoil/orientation.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/airfoil.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/common/align.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/common/angles.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/common/convert_2d_3d.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/common/discrete_domain.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/common/indices.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/common/interval.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/common/kd_tree.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/common/points.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/common/poisson_disk.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/common/surface_point.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/common/svd_basis.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/common/vec_f64.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/common.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/errors.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/func1/common_functions.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/func1/polynomial.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/func1/series1.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/func1.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom2/aabb2.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom2/align2/jacobian.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom2/align2/points_to_curve.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom2/align2/rc_params2.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom2/align2.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom2/angles2.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom2/circle2.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom2/curve2.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom2/hull.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom2/line2.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom2/polyline2.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom2.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom3/align3/jacobian.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom3/align3/multi_param.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom3/align3/points_to_mesh.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom3/align3/rotations.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom3/align3.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom3/curve3.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom3/iso3.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom3/mesh/collisions.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom3/mesh/conformal.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom3/mesh/edges.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom3/mesh/faces.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom3/mesh/filtering.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom3/mesh/measurement.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom3/mesh/outline.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom3/mesh/patches.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom3/mesh/queries.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom3/mesh/sampling.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom3/mesh/uv_mapping.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom3/plane3.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/geom3/point_cloud.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/io.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/metrology/dimension.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/metrology/line_profiles.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/metrology/surface_deviation.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/metrology/tolerance.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/metrology/tolerance_map.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/metrology.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/raster3.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/sensor.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/stats.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/engeom/src/utility.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/mkdocs.yml +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/pyproject.toml +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/python/engeom/__init__.py +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/python/engeom/_plot/__init__.py +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/python/engeom/_plot/common.py +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/python/engeom/_plot/matplotlib.py +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/python/engeom/_plot/pyvista.py +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/python/engeom/airfoil/__init__.py +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/python/engeom/airfoil.pyi +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/python/engeom/align/__init__.py +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/python/engeom/align.pyi +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/python/engeom/engeom.pyi +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/python/engeom/geom2/__init__.py +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/python/engeom/geom3/__init__.py +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/python/engeom/metrology/__init__.py +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/python/engeom/metrology.pyi +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/python/engeom/plot.py +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/python/engeom/raster3/__init__.py +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/python/engeom/raster3.pyi +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/python/engeom/sensor/__init__.py +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/python/engeom/sensor.pyi +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/python/tests/test_all.py +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/python/tests/test_geom2_simple.py +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/python/tests/test_geom3_simple.py +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/src/airfoil.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/src/alignments.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/src/common.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/src/lib.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/src/metrology.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/src/raster.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/src/ray_casting.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/src/sensor.rs +0 -0
- {engeom-0.2.10 → engeom-0.2.12}/src/svd_basis.rs +0 -0
@@ -2,6 +2,7 @@
|
|
2
2
|
//! indices into the vertex list. This abstraction is built around the `TriMesh` type from the
|
3
3
|
//! `parry3d` crate.
|
4
4
|
|
5
|
+
mod collisions;
|
5
6
|
mod conformal;
|
6
7
|
mod edges;
|
7
8
|
mod faces;
|
@@ -12,15 +13,14 @@ mod patches;
|
|
12
13
|
mod queries;
|
13
14
|
mod sampling;
|
14
15
|
mod uv_mapping;
|
15
|
-
mod collisions;
|
16
16
|
|
17
|
-
pub use self::uv_mapping::UvMapping;
|
18
17
|
pub use self::collisions::MeshCollisionSet;
|
19
|
-
use
|
18
|
+
pub use self::uv_mapping::UvMapping;
|
19
|
+
use crate::geom3::{Aabb3, IsoExtensions3};
|
20
20
|
use crate::{Iso3, Point2, Point3, Result, SurfacePoint3, UnitVec3, Vector3};
|
21
21
|
pub use edges::MeshEdges;
|
22
22
|
use parry3d_f64::shape::{TriMesh, TriMeshFlags};
|
23
|
-
use parry3d_f64::transformation;
|
23
|
+
use parry3d_f64::{shape, transformation};
|
24
24
|
|
25
25
|
#[derive(Clone)]
|
26
26
|
pub struct Mesh {
|
@@ -204,32 +204,79 @@ impl Mesh {
|
|
204
204
|
}
|
205
205
|
}
|
206
206
|
|
207
|
-
pub fn
|
208
|
-
let
|
207
|
+
pub fn create_cone(half_height: f64, radius: f64, steps: usize) -> Self {
|
208
|
+
let cone = shape::Cone::new(half_height, radius);
|
209
|
+
let (vertices, faces) = cone.to_trimesh(steps as u32);
|
210
|
+
|
211
|
+
Self::new(vertices, faces, true)
|
212
|
+
}
|
213
|
+
|
214
|
+
pub fn create_capsule(
|
215
|
+
p0: &Point3,
|
216
|
+
p1: &Point3,
|
217
|
+
radius: f64,
|
218
|
+
n_theta: usize,
|
219
|
+
n_phi: usize,
|
220
|
+
) -> Self {
|
221
|
+
let capsule = shape::Capsule::new(*p0, *p1, radius);
|
222
|
+
let (vertices, faces) = capsule.to_trimesh(n_theta as u32, n_phi as u32);
|
223
|
+
|
224
|
+
Self::new(vertices, faces, true)
|
225
|
+
}
|
226
|
+
|
227
|
+
pub fn create_sphere(radius: f64, n_theta: usize, n_phi: usize) -> Self {
|
228
|
+
let sphere = shape::Ball::new(radius);
|
229
|
+
let (vertices, faces) = sphere.to_trimesh(n_theta as u32, n_phi as u32);
|
230
|
+
|
231
|
+
Self::new(vertices, faces, true)
|
232
|
+
}
|
233
|
+
|
234
|
+
pub fn create_box(length: f64, width: f64, height: f64, is_solid: bool) -> Self {
|
235
|
+
let bx = shape::Cuboid::new(Vector3::new(length / 2.0, width / 2.0, height / 2.0));
|
236
|
+
let (vertices, triangles) = bx.to_trimesh();
|
209
237
|
Self::new(vertices, triangles, is_solid)
|
210
238
|
}
|
211
239
|
|
212
240
|
pub fn create_cylinder(radius: f64, height: f64, steps: usize) -> Self {
|
213
|
-
let
|
214
|
-
let
|
241
|
+
let cyl = shape::Cylinder::new(height / 2.0, radius);
|
242
|
+
let (vertices, faces) = cyl.to_trimesh(steps as u32);
|
243
|
+
|
244
|
+
Self::new(vertices, faces, true)
|
245
|
+
}
|
246
|
+
|
247
|
+
pub fn create_rect_beam_between(
|
248
|
+
p0: &Point3,
|
249
|
+
p1: &Point3,
|
250
|
+
width: f64,
|
251
|
+
height: f64,
|
252
|
+
up: &Vector3,
|
253
|
+
) -> Result<Self> {
|
254
|
+
let v = *p1 - *p0;
|
255
|
+
let pc = *p0 + v / 2.0;
|
256
|
+
let box_geom = shape::Cuboid::new(Vector3::new(width / 2.0, height / 2.0, v.norm() / 2.0));
|
215
257
|
|
216
|
-
|
217
|
-
|
218
|
-
let x = radius * angle.cos();
|
219
|
-
let y = radius * angle.sin();
|
258
|
+
// I think this is OK?
|
259
|
+
let transform = Iso3::try_from_basis_zy(&v, up, Some(pc))?;
|
220
260
|
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
261
|
+
let (vertices, faces) = box_geom.to_trimesh();
|
262
|
+
let mut mesh = Self::new(vertices, faces, true);
|
263
|
+
mesh.transform(&transform);
|
264
|
+
Ok(mesh)
|
265
|
+
}
|
225
266
|
|
226
|
-
|
267
|
+
pub fn create_cylinder_between(p0: &Point3, p1: &Point3, radius: f64, steps: usize) -> Self {
|
268
|
+
let v = *p1 - *p0;
|
269
|
+
let pc = *p0 + v / 2.0;
|
270
|
+
let cyl = shape::Cylinder::new(v.norm() / 2.0, radius);
|
227
271
|
|
228
|
-
|
229
|
-
|
230
|
-
|
272
|
+
// I think this is OK?
|
273
|
+
let transform = Iso3::try_from_basis_yz(&v, &Vector3::z(), Some(pc))
|
274
|
+
.unwrap_or(Iso3::try_from_basis_yx(&v, &Vector3::x(), Some(pc)).unwrap());
|
231
275
|
|
232
|
-
|
276
|
+
let (vertices, faces) = cyl.to_trimesh(steps as u32);
|
277
|
+
let mut mesh = Self::new(vertices, faces, true);
|
278
|
+
mesh.transform(&transform);
|
279
|
+
mesh
|
233
280
|
}
|
234
281
|
|
235
282
|
pub fn get_patches(&self) -> Vec<Vec<usize>> {
|
@@ -0,0 +1,141 @@
|
|
1
|
+
use serde::{Deserialize, Serialize};
|
2
|
+
use crate::{Iso3, Vector3};
|
3
|
+
use crate::na::{Translation3, UnitQuaternion};
|
4
|
+
|
5
|
+
/// A struct representing a 6D pose in XYZ and WPR (Yaw, Pitch, Roll) format, commonly used by
|
6
|
+
/// FANUC robots. Angles are represented in degrees.
|
7
|
+
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
8
|
+
pub struct XyzWpr {
|
9
|
+
pub x: f64,
|
10
|
+
pub y: f64,
|
11
|
+
pub z: f64,
|
12
|
+
pub w: f64,
|
13
|
+
pub p: f64,
|
14
|
+
pub r: f64,
|
15
|
+
}
|
16
|
+
|
17
|
+
impl XyzWpr {
|
18
|
+
pub fn new(x: f64, y: f64, z: f64, w: f64, p: f64, r: f64) -> Self {
|
19
|
+
XyzWpr { x, y, z, w, p, r }
|
20
|
+
}
|
21
|
+
|
22
|
+
pub fn from_isometry(isometry: &Iso3) -> Self {
|
23
|
+
let translation = isometry.translation.vector;
|
24
|
+
let rotation = isometry.rotation;
|
25
|
+
let (r, p, w) = rotation.euler_angles();
|
26
|
+
XyzWpr::new(
|
27
|
+
translation.x,
|
28
|
+
translation.y,
|
29
|
+
translation.z,
|
30
|
+
w.to_degrees(),
|
31
|
+
p.to_degrees(),
|
32
|
+
r.to_degrees(),
|
33
|
+
)
|
34
|
+
}
|
35
|
+
|
36
|
+
pub fn to_isometry(&self) -> Iso3 {
|
37
|
+
let translation = Vector3::new(self.x, self.y, self.z);
|
38
|
+
let rotation = UnitQuaternion::from_euler_angles(
|
39
|
+
self.r.to_radians(),
|
40
|
+
self.p.to_radians(),
|
41
|
+
self.w.to_radians(),
|
42
|
+
);
|
43
|
+
Iso3::from_parts(Translation3::from(translation), rotation)
|
44
|
+
}
|
45
|
+
|
46
|
+
pub fn approx_eq(&self, other: &XyzWpr, epsilon: f64) -> bool {
|
47
|
+
let m0 = self.to_isometry().to_matrix();
|
48
|
+
let m1 = other.to_isometry().to_matrix();
|
49
|
+
let diff = m0 - m1;
|
50
|
+
diff.amax() < epsilon
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
impl std::fmt::Display for XyzWpr {
|
55
|
+
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
56
|
+
write!(
|
57
|
+
f,
|
58
|
+
"XyzWpr {{ x: {}, y: {}, z: {}, w: {}, p: {}, r: {} }}",
|
59
|
+
self.x, self.y, self.z, self.w, self.p, self.r
|
60
|
+
)
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
#[cfg(test)]
|
65
|
+
mod tests {
|
66
|
+
use super::*;
|
67
|
+
use crate::na::{try_convert, Matrix4};
|
68
|
+
use approx::assert_relative_eq;
|
69
|
+
use test_case::test_case;
|
70
|
+
|
71
|
+
#[test_case((-0.8156824504, -0.5743236360, -0.0693866068, -413.8635232282, 0.0004524620, 0.1193088953, -0.9928570807, 263.1863811434, 0.5784997281, -0.8098874913, -0.0970583124, 291.9820746748, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (-413.8635232282, 263.1863811434, 291.9820746748, -96.8338333769, -35.3450905433, 179.9682178248))]
|
72
|
+
#[test_case((-0.1500516217, 0.5455385155, -0.8245436550, -149.1668440821, 0.9459952737, -0.1631791693, -0.2801169415, 59.3543506644, -0.2873629291, -0.8220464019, -0.4915915582, 543.2838251943, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (-149.1668440821, 59.3543506644, 543.2838251943, -120.8798246395, 16.7001441168, 99.0130388728))]
|
73
|
+
#[test_case((0.5009445358, 0.6825401810, 0.5321592557, 31.0642288750, -0.8639774486, 0.3581642754, 0.3539227601, -26.7743169615, 0.0509660705, -0.6370692687, 0.7691197609, 37.9006405971, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (31.0642288750, -26.7743169615, 37.9006405971, -39.6352782596, -2.9214064154, -59.8943255222))]
|
74
|
+
#[test_case((0.9089103503, -0.4069146210, 0.0911178708, 33.5138781088, -0.0854907806, 0.0320310501, 0.9958239494, 96.1164814542, -0.4081339260, -0.9129044326, -0.0056740956, -300.9032245106, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (33.5138781088, 96.1164814542, -300.9032245106, -90.3561134473, 24.0876647389, -5.3733485621))]
|
75
|
+
#[test_case((-0.1653518888, 0.9687851465, -0.1847000075, 77.8658952620, 0.9532759246, 0.2050088803, 0.2218927005, 100.2923343848, 0.2528314941, -0.1393796933, -0.9574181619, -127.6541936118, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (77.8658952620, 100.2923343848, -127.6541936118, -171.7171410357, -14.6451288996, 99.8404139441))]
|
76
|
+
#[test_case((-0.4118951499, 0.3279601759, -0.8501673415, -70.6389144769, -0.3403719856, -0.9208299694, -0.1903131075, 22.3217390074, -0.8452746873, 0.2109841002, 0.4909138545, 18.1798498130, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (-70.6389144769, 22.3217390074, 18.1798498130, 23.2569815201, 57.7013782986, -140.4311743532))]
|
77
|
+
#[test_case((-0.7479917678, -0.6191725989, -0.2390263753, 604.2872268462, -0.4057545090, 0.1415967662, 0.9029471935, -20.9333741686, -0.5252347986, 0.7723830970, -0.3571452893, 30.4479677368, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (604.2872268462, -20.9333741686, 30.4479677368, 114.8155367373, 31.6840511268, -151.5220050073))]
|
78
|
+
#[test_case((0.4873440333, 0.6172398073, 0.6176656163, 77.4016768659, 0.3323406191, 0.5230063131, -0.7848656633, -28.4720503689, -0.8074933474, 0.5877749712, 0.0497501464, -19.7908480100, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (77.4016768659, -28.4720503689, -19.7908480100, 85.1619317507, 53.8517426985, 34.2917400153))]
|
79
|
+
#[test_case((0.0833272687, 0.6836449300, 0.7250421891, 471.9320306822, -0.8519144952, -0.3286045615, 0.4077508246, -102.6726730677, 0.5170089546, -0.6516507130, 0.5550253049, 588.5120154719, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (471.9320306822, -102.6726730677, 588.5120154719, -49.5782300627, -31.1318310910, -84.4135682965))]
|
80
|
+
#[test_case((-0.2510504585, 0.9157805028, -0.3135597837, -577.6445766741, -0.0345374583, -0.3322023607, -0.9425755967, -216.2517731052, -0.9673576543, -0.2258044778, 0.1150282859, 240.9460890915, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (-577.6445766741, -216.2517731052, 240.9460890915, -63.0050045001, 75.3203125033, -172.1668871906))]
|
81
|
+
#[test_case((0.1791056335, -0.5890186234, -0.7880217213, 411.6803610302, 0.6839325663, -0.5012295385, 0.5300992308, 331.0434986878, -0.7072180829, -0.6338974767, 0.3130759848, -361.9951518329, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (411.6803610302, 331.0434986878, -361.9951518329, -63.7156683382, 45.0090193165, 75.3251405039))]
|
82
|
+
#[test_case((-0.7389487926, -0.6540675080, 0.1617107816, 5.4890201453, -0.6393453686, 0.7564348576, 0.1379992968, -26.5744088848, -0.2125845282, -0.0014146255, -0.9771416567, -99.6628429743, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (5.4890201453, -26.5744088848, -99.6628429743, -179.9170519309, 12.2738553488, -139.1333357015))]
|
83
|
+
#[test_case((-0.2037395422, 0.6790363200, -0.7052658187, -1.7434467919, -0.8508250650, -0.4791894336, -0.2155787453, -14.7633944063, -0.4843417261, 0.5561359212, 0.6753709570, -79.9344894886, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (-1.7434467919, -14.7633944063, -79.9344894886, 39.4698348110, 28.9693530939, -103.4665369616))]
|
84
|
+
#[test_case((0.7230637290, 0.1432361537, -0.6757678952, -49.7118498703, 0.5101470443, 0.5488670300, 0.6621895322, 20.3765636776, 0.4657561992, -0.8235462268, 0.3237943410, 8.4422995188, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (-49.7118498703, 20.3765636776, 8.4422995188, -68.5366961539, -27.7591729450, 35.2043221840))]
|
85
|
+
#[test_case((0.9572590453, -0.2498925755, 0.1456324858, 59.5794643289, -0.2886479285, -0.7934076632, 0.5358979878, 6.7548483372, -0.0183709982, -0.5550297115, -0.8316276365, -88.8341095469, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000), (59.5794643289, 6.7548483372, -88.8341095469, -146.2807856754, 1.0526398756, -16.7799423973))]
|
86
|
+
fn xyzwpr_to_isometry(
|
87
|
+
mf: (
|
88
|
+
f64,
|
89
|
+
f64,
|
90
|
+
f64,
|
91
|
+
f64,
|
92
|
+
f64,
|
93
|
+
f64,
|
94
|
+
f64,
|
95
|
+
f64,
|
96
|
+
f64,
|
97
|
+
f64,
|
98
|
+
f64,
|
99
|
+
f64,
|
100
|
+
f64,
|
101
|
+
f64,
|
102
|
+
f64,
|
103
|
+
f64,
|
104
|
+
),
|
105
|
+
pf: (f64, f64, f64, f64, f64, f64),
|
106
|
+
) {
|
107
|
+
let m = Matrix4::new(
|
108
|
+
mf.0, mf.1, mf.2, mf.3, mf.4, mf.5, mf.6, mf.7, mf.8, mf.9, mf.10, mf.11, mf.12, mf.13,
|
109
|
+
mf.14, mf.15,
|
110
|
+
);
|
111
|
+
let p = XyzWpr::new(pf.0, pf.1, pf.2, pf.5, pf.4, pf.3);
|
112
|
+
let t = p.to_isometry();
|
113
|
+
let m_ = t.to_matrix();
|
114
|
+
assert_relative_eq!(m, m_, epsilon = 1e-5);
|
115
|
+
}
|
116
|
+
|
117
|
+
#[test_case((213.3455874397, -541.8828362001, -95.1324602951, -164.2348619634, 24.0489557219, -170.7519141710))]
|
118
|
+
#[test_case((70.6318465112, 113.6560228546, 346.7855689786, -26.3445451403, -30.6825741682, -92.3381779921))]
|
119
|
+
#[test_case((-18.5208462508, 554.3972482202, 531.8505273397, 24.9359848528, -20.6580074641, -118.2163130322))]
|
120
|
+
#[test_case((-279.4908707038, 107.0379921066, 347.6153730196, 141.6846980303, 42.9511504078, 21.8352677126))]
|
121
|
+
#[test_case((61.7823486174, 39.0960520469, 7.1731831514, 63.6707920489, 28.5547935126, 65.2651276746))]
|
122
|
+
#[test_case((17.8583707934, -103.5277608846, -41.9211021563, -129.0763419754, -64.3075695674, -119.6216242866))]
|
123
|
+
#[test_case((381.5649351646, -118.4073378481, 86.8318954547, -69.6420826640, 50.3520931676, -113.9445091815))]
|
124
|
+
#[test_case((-46.1766927642, -55.8019771470, -84.1930750980, -148.4720043329, 11.1136514360, 139.1677460882))]
|
125
|
+
#[test_case((222.2302724845, -372.5432843996, 266.9542861389, 88.4476440066, 35.3943355124, -166.3788546777))]
|
126
|
+
#[test_case((459.8055541953, 401.5061123248, 180.9052529976, 121.5295678361, -30.3457576176, 66.0945383908))]
|
127
|
+
#[test_case((-68.9503102461, -79.4547936268, -62.0503091459, 121.1860503955, 5.5438249089, -33.3572843285))]
|
128
|
+
fn xyzwpr_from_isometry(pf: (f64, f64, f64, f64, f64, f64)) {
|
129
|
+
let p = XyzWpr::new(pf.0, pf.1, pf.2, pf.5, pf.4, pf.3);
|
130
|
+
let i = p.to_isometry();
|
131
|
+
|
132
|
+
let p_ = XyzWpr::from_isometry(&i);
|
133
|
+
|
134
|
+
assert_relative_eq!(p.x, p_.x, epsilon = 1e-5);
|
135
|
+
assert_relative_eq!(p.y, p_.y, epsilon = 1e-5);
|
136
|
+
assert_relative_eq!(p.z, p_.z, epsilon = 1e-5);
|
137
|
+
assert_relative_eq!(p.w, p_.w, epsilon = 1e-5);
|
138
|
+
assert_relative_eq!(p.p, p_.p, epsilon = 1e-5);
|
139
|
+
assert_relative_eq!(p.r, p_.r, epsilon = 1e-5);
|
140
|
+
}
|
141
|
+
}
|
@@ -4,6 +4,7 @@ pub mod mesh;
|
|
4
4
|
mod plane3;
|
5
5
|
mod point_cloud;
|
6
6
|
mod iso3;
|
7
|
+
mod xyzwpr;
|
7
8
|
|
8
9
|
use parry3d_f64::na::UnitQuaternion;
|
9
10
|
|
@@ -17,6 +18,7 @@ pub use mesh::{Mesh, UvMapping, MeshCollisionSet};
|
|
17
18
|
pub use plane3::Plane3;
|
18
19
|
pub use point_cloud::{PointCloud, PointCloudFeatures, PointCloudKdTree};
|
19
20
|
pub use iso3::IsoExtensions3;
|
21
|
+
pub use xyzwpr::XyzWpr;
|
20
22
|
|
21
23
|
pub type Point3 = parry3d_f64::na::Point3<f64>;
|
22
24
|
pub type Vector3 = parry3d_f64::na::Vector3<f64>;
|
@@ -15,6 +15,10 @@ pub mod sensor;
|
|
15
15
|
|
16
16
|
pub type Result<T> = std::result::Result<T, Box<dyn Error>>;
|
17
17
|
|
18
|
+
// Re-export parry and nalgebra
|
19
|
+
pub use parry3d_f64::na as na;
|
20
|
+
pub use parry3d_f64 as parry3d;
|
21
|
+
|
18
22
|
// Common one dimensional functions
|
19
23
|
pub use func1::{Func1, Gaussian1, Line1, Polynomial, Series1};
|
20
24
|
|
@@ -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
|
+
...
|