diff --git a/src/ball.rs b/src/ball.rs index c729d6d..72ebe19 100644 --- a/src/ball.rs +++ b/src/ball.rs @@ -9,65 +9,65 @@ use nalgebra::{ base::allocator::Allocator, DefaultAllocator, DimName, OMatrix, OPoint, OVector, RealField, }; -/// Ball over real field `R` of dimension `D` with center and radius squared. +/// Ball over real field `T` of dimension `D` with center and radius squared. #[derive(Debug, Clone, PartialEq)] -pub struct Ball +pub struct Ball where - DefaultAllocator: Allocator, + DefaultAllocator: Allocator, { /// Ball's center. - pub center: OPoint, + pub center: OPoint, /// Ball's radius squared. - pub radius_squared: R, + pub radius_squared: T, } -impl Copy for Ball +impl Copy for Ball where - OPoint: Copy, - DefaultAllocator: Allocator, + OPoint: Copy, + DefaultAllocator: Allocator, { } -impl Enclosing for Ball +impl Enclosing for Ball where - DefaultAllocator: Allocator, + DefaultAllocator: Allocator, { #[inline] - fn contains(&self, point: &OPoint) -> bool { + fn contains(&self, point: &OPoint) -> bool { (point - &self.center).norm_squared() <= self.radius_squared } - fn with_bounds(bounds: &[OPoint]) -> Option + fn with_bounds(bounds: &[OPoint]) -> Option where - DefaultAllocator: Allocator, + DefaultAllocator: Allocator, { let length = bounds.len().checked_sub(1).filter(|&len| len <= D::USIZE)?; - let points = OMatrix::::from_fn(|row, column| { + let points = OMatrix::::from_fn(|row, column| { if column < length { bounds[column + 1].coords[row].clone() - bounds[0].coords[row].clone() } else { - R::zero() + T::zero() } }); let points = points.view((0, 0), (D::USIZE, length)); - let matrix = OMatrix::::from_fn(|row, column| { + let matrix = OMatrix::::from_fn(|row, column| { if row < length && column < length { - points.column(row).dot(&points.column(column)) * (R::one() + R::one()) + points.column(row).dot(&points.column(column)) * (T::one() + T::one()) } else { - R::zero() + T::zero() } }); let matrix = matrix.view((0, 0), (length, length)); - let vector = OVector::::from_fn(|row, _column| { + let vector = OVector::::from_fn(|row, _column| { if row < length { points.column(row).norm_squared() } else { - R::zero() + T::zero() } }); let vector = vector.view((0, 0), (length, 1)); matrix.try_inverse().map(|matrix| { let vector = matrix * vector; - let mut center = OVector::::zeros(); + let mut center = OVector::::zeros(); for point in 0..length { center += points.column(point) * vector[point].clone(); } diff --git a/src/enclosing.rs b/src/enclosing.rs index 56f515e..f2b4d8b 100644 --- a/src/enclosing.rs +++ b/src/enclosing.rs @@ -13,22 +13,22 @@ use stacker::maybe_grow; use std::mem::size_of; /// Minimum enclosing ball. -pub trait Enclosing +pub trait Enclosing where Self: Clone, - DefaultAllocator: Allocator, + DefaultAllocator: Allocator, { #[doc(hidden)] /// Guaranteed stack size per recursion step. const RED_ZONE: usize = - 32 * 1_024 + (8 * D::USIZE + 2 * D::USIZE.pow(2)) * size_of::>(); + 32 * 1_024 + (8 * D::USIZE + 2 * D::USIZE.pow(2)) * size_of::>(); #[doc(hidden)] /// New stack space to allocate if within [`Self::RED_ZONE`]. const STACK_SIZE: usize = Self::RED_ZONE * 1_024; /// Whether ball contains `point`. #[must_use] - fn contains(&self, point: &OPoint) -> bool; + fn contains(&self, point: &OPoint) -> bool; /// Returns circumscribed ball with all `bounds` on surface or `None` if it does not exist. /// /// # Example @@ -59,9 +59,9 @@ where /// assert_eq!(radius_squared, 3.0); /// ``` #[must_use] - fn with_bounds(bounds: &[OPoint]) -> Option + fn with_bounds(bounds: &[OPoint]) -> Option where - DefaultAllocator: Allocator; + DefaultAllocator: Allocator; /// Returns minimum ball enclosing `points`. /// @@ -72,15 +72,15 @@ where /// to the front and enclosed ones to the back. /// /// Implements [Welzl's recursive algorithm] with move-to-front heuristic. No allocations happen - /// unless real field `R` is not [`Copy`] or stack size enters dimension-dependant red zone in + /// unless real field `T` is not [`Copy`] or stack size enters dimension-dependant red zone in /// which case temporary stack space will be allocated. /// /// [Welzl's recursive algorithm]: https://api.semanticscholar.org/CorpusID:17569809 /// /// # Complexity /// - /// Expected time complexity is *O(cn)* for *n* randomly permuted points. Complexity constant - /// *c* is significantly reduced by reusing permuted points of previous invocations. + /// Expected time complexity is *O*(*n*) for *n* randomly permuted points. Complexity constant + /// *c* as in *cn* is significantly reduced by reusing permuted points of previous invocations. /// /// # Example /// @@ -132,16 +132,16 @@ where /// ``` #[must_use] #[inline] - fn enclosing_points(points: &mut impl Deque>) -> Self + fn enclosing_points(points: &mut impl Deque>) -> Self where D: DimNameAdd, - DefaultAllocator: Allocator + Allocator, DimNameSum>, - , DimNameSum>>::Buffer: Default, + DefaultAllocator: Allocator + Allocator, DimNameSum>, + , DimNameSum>>::Buffer: Default, { maybe_grow(Self::RED_ZONE, Self::STACK_SIZE, || { Self::enclosing_points_with_bounds( points, - &mut OVec::, DimNameSum>::new(), + &mut OVec::, DimNameSum>::new(), ) .expect("Empty point set") }) @@ -152,13 +152,13 @@ where #[doc(hidden)] #[must_use] fn enclosing_points_with_bounds( - points: &mut impl Deque>, - bounds: &mut OVec, DimNameSum>, + points: &mut impl Deque>, + bounds: &mut OVec, DimNameSum>, ) -> Option where D: DimNameAdd, - DefaultAllocator: Allocator + Allocator, DimNameSum>, - , DimNameSum>>::Buffer: Default, + DefaultAllocator: Allocator + Allocator, DimNameSum>, + , DimNameSum>>::Buffer: Default, { // Take point from back. if let Some(point) = points.pop_back().filter(|_| !bounds.is_full()) {