hi i’m using try_from_points to generate a convex hull,
how can i get the number of faces generated?
currently i’m using the number of generated points but sometimes it doesn’t match, here’s my code snippet:
let convex = ConvexHull::try_from_points(&points[..]).expect("***** Invalid convex shape. *****");
convex.check_geometry();
// println!("N. points: {}\N{:?}", convex.points().len(), convex.points());
let pnts = convex.points();
let n_pnts = pnts.len();
let face = ConvexPolygonalFeature::<f32>::new(); // get face
// let fff = convex.get_faces();
println!("faces in {} generated points: {}", N, n_pnts);
for i in 0..n_pnts {
let mut face = face.clone();
convex.face(FeatureId::Face(i), &mut face);
let faces = face.vertices_id;
print!("face {:5}/{} ({} pts): ", i, n_pnts, faces.len());
for f in faces {
let vix = f.unwrap_vertex(); // index to vertex
let vertex = pnts[vix].coords.data; // the vertex as [x, y, z]
print!("{} ({:?}) ", vix, vertex);
}
println!("");
}
i’m also getting this error for waterman(52) s/c below:
thread 'main' panicked at 'assertion failed: (v - p0).dot(face.normal.as_ref()) <= N::default_epsilon()', /Users/asd/.cargo/registry/src/github.com-1ecc6299db9ec823/ncollide3d-0.26.1/src/shape/convex.rs:344:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
also
let convex = ConvexHull::try_from_points(&points[..]).expect("***** Invalid convex shape. *****");
fails over a valid waterman(54) set
and finally for waterman(56):
thread 'main' panicked at 'assertion failed: triangles[curr_triangle].vertices[curr_edge_id] == curr_vertex', /Users/asd/.cargo/registry/src/github.com-1ecc6299db9ec823/ncollide3d-0.26.1/src/shape/convex.rs:231:33```
i’m running a waterman poly generator on ConvexHull and in the case of rad=372 it enter in a endless loop consuming large amount of memory, i’ve been running a c++version with my ported java->c++ convex hull for years and it works in all waterman cases (https://github.com/rforcen/WatermanPython/tree/master/Waterman/cpp)
code for rust generator:
/*
Waterman poly
*/
extern crate nalgebra as na;
use na::Point3;
pub fn gen_waterman_poly(radius : f64) -> Vec<Point3<f64>> {
let mut coords = vec![];
let (mut minc, mut maxc) = (std::f64::MAX, -std::f64::MAX);
let (a, b, c) = (0.0f64, 0.0f64, 0.0f64);
let mut s = radius.sqrt();
let radius2 = s * s;
let (xra, xrb) = ( (a - s).ceil(), (a + s).floor() );
let mut x = xra;
while x <= xrb {
let r = radius2 - (x - a) * (x - a);
if r < 0. { x += 1.; continue }
s = r.sqrt();
let yra = (b - s).ceil();
let yrb = (b + s).floor();
let mut y = yra;
let (mut zra, mut zrb) : (f64, f64);
while y <= yrb {
let ry = r - (y - b) * (y - b);
if ry < 0. { y += 1.; continue } //case ry < 0
if ry == 0. && c == c.floor() { //case ry=0
if ((x + y + c) % 2.) != 0. { y += 1.; continue }
else {
zra = c;
zrb = c;
}
} else { // case ry > 0
s = ry.sqrt();
zra = (c - s).ceil();
zrb = (c + s).floor();
if ((x + y) % 2.) == 0. {
if (zra % 2.) != 0. {
if zra <= c { zra = zra + 1. }
else { zra = zra - 1. }
}
} else {
if zra % 2. == 0. {
if zra <= c { zra = zra + 1. }
else { zra = zra - 1. }
}
}
}
let mut z = zra;
while z <= zrb { // save vertex x,y,z
minc = minc.min(x.min(y.min(z)));
maxc = maxc.max(x.max(y.max(z)));
coords.push(Point3::<f64>::new(x, y, z));
z += 2.
}
y += 1.;
}
x += 1.;
}
// scale
let diff = (maxc-minc).abs();
if diff != 0. {
for i in 0..coords.len() {
let ci = coords[i];
coords[i] = Point3::<f64>::new(ci[0]/diff, ci[1]/diff, ci[2]/diff)
}
}
coords
}
just tested waterman generator with chull:
use chull::{ConvexHull,ConvexHullWrapper};
and works perfectly in both cases:
let points = gen_waterman_poly(372.);
// slow but robust
let convexh01 = ConvexHullWrapper::try_new(&points[..], None).unwrap();
// fast but non-robust
let convexh02 = ConvexHull::try_new(&points[..], std::f64::EPSILON*200.0, None).unwrap();