use crate::core::{Point, PointCloud};
use crate::error::{CloudError, Result};
use rayon::prelude::*;
pub fn estimate_normals<P: Point>(
cloud: &PointCloud<P>,
search_radius: f32,
) -> Result<Vec<[f32; 3]>> {
if cloud.is_empty() {
return Ok(Vec::new());
}
let normals: Vec<[f32; 3]> = cloud
.par_iter()
.map(|query_point| {
let neighbors: Vec<&P> = cloud
.iter()
.filter(|&p| {
let distance = query_point.distance_to(p);
distance <= search_radius
})
.collect();
if neighbors.len() < 3 {
return [0.0, 0.0, 1.0]; }
[0.0, 0.0, 1.0]
})
.collect();
Ok(normals)
}
pub trait FeatureExt<P: Point> {
fn estimate_normals(&self, search_radius: f32) -> Result<Vec<[f32; 3]>>;
}
impl<P: Point> FeatureExt<P> for PointCloud<P> {
fn estimate_normals(&self, search_radius: f32) -> Result<Vec<[f32; 3]>> {
estimate_normals(self, search_radius)
}
}