Skip to content

Commit

Permalink
Use T in favor of R as does nalgebra.
Browse files Browse the repository at this point in the history
  • Loading branch information
n3vu0r committed Mar 24, 2024
1 parent c89b6d4 commit 22db1d0
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 38 deletions.
42 changes: 21 additions & 21 deletions src/ball.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<R: RealField, D: DimName>
pub struct Ball<T: RealField, D: DimName>
where
DefaultAllocator: Allocator<R, D>,
DefaultAllocator: Allocator<T, D>,
{
/// Ball's center.
pub center: OPoint<R, D>,
pub center: OPoint<T, D>,
/// Ball's radius squared.
pub radius_squared: R,
pub radius_squared: T,
}

impl<R: RealField + Copy, D: DimName> Copy for Ball<R, D>
impl<T: RealField + Copy, D: DimName> Copy for Ball<T, D>
where
OPoint<R, D>: Copy,
DefaultAllocator: Allocator<R, D>,
OPoint<T, D>: Copy,
DefaultAllocator: Allocator<T, D>,
{
}

impl<R: RealField, D: DimName> Enclosing<R, D> for Ball<R, D>
impl<T: RealField, D: DimName> Enclosing<T, D> for Ball<T, D>
where
DefaultAllocator: Allocator<R, D>,
DefaultAllocator: Allocator<T, D>,
{
#[inline]
fn contains(&self, point: &OPoint<R, D>) -> bool {
fn contains(&self, point: &OPoint<T, D>) -> bool {
(point - &self.center).norm_squared() <= self.radius_squared
}
fn with_bounds(bounds: &[OPoint<R, D>]) -> Option<Self>
fn with_bounds(bounds: &[OPoint<T, D>]) -> Option<Self>
where
DefaultAllocator: Allocator<R, D, D>,
DefaultAllocator: Allocator<T, D, D>,
{
let length = bounds.len().checked_sub(1).filter(|&len| len <= D::USIZE)?;
let points = OMatrix::<R, D, D>::from_fn(|row, column| {
let points = OMatrix::<T, D, D>::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::<R, D, D>::from_fn(|row, column| {
let matrix = OMatrix::<T, D, D>::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::<R, D>::from_fn(|row, _column| {
let vector = OVector::<T, D>::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::<R, D>::zeros();
let mut center = OVector::<T, D>::zeros();
for point in 0..length {
center += points.column(point) * vector[point].clone();
}
Expand Down
34 changes: 17 additions & 17 deletions src/enclosing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,22 @@ use stacker::maybe_grow;
use std::mem::size_of;

/// Minimum enclosing ball.
pub trait Enclosing<R: RealField, D: DimName>
pub trait Enclosing<T: RealField, D: DimName>
where
Self: Clone,
DefaultAllocator: Allocator<R, D>,
DefaultAllocator: Allocator<T, D>,
{
#[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::<OPoint<R, D>>();
32 * 1_024 + (8 * D::USIZE + 2 * D::USIZE.pow(2)) * size_of::<OPoint<T, D>>();
#[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<R, D>) -> bool;
fn contains(&self, point: &OPoint<T, D>) -> bool;
/// Returns circumscribed ball with all `bounds` on surface or `None` if it does not exist.
///
/// # Example
Expand Down Expand Up @@ -59,9 +59,9 @@ where
/// assert_eq!(radius_squared, 3.0);
/// ```
#[must_use]
fn with_bounds(bounds: &[OPoint<R, D>]) -> Option<Self>
fn with_bounds(bounds: &[OPoint<T, D>]) -> Option<Self>
where
DefaultAllocator: Allocator<R, D, D>;
DefaultAllocator: Allocator<T, D, D>;

/// Returns minimum ball enclosing `points`.
///
Expand All @@ -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
///
Expand Down Expand Up @@ -132,16 +132,16 @@ where
/// ```
#[must_use]
#[inline]
fn enclosing_points(points: &mut impl Deque<OPoint<R, D>>) -> Self
fn enclosing_points(points: &mut impl Deque<OPoint<T, D>>) -> Self
where
D: DimNameAdd<U1>,
DefaultAllocator: Allocator<R, D, D> + Allocator<OPoint<R, D>, DimNameSum<D, U1>>,
<DefaultAllocator as Allocator<OPoint<R, D>, DimNameSum<D, U1>>>::Buffer: Default,
DefaultAllocator: Allocator<T, D, D> + Allocator<OPoint<T, D>, DimNameSum<D, U1>>,
<DefaultAllocator as Allocator<OPoint<T, D>, DimNameSum<D, U1>>>::Buffer: Default,
{
maybe_grow(Self::RED_ZONE, Self::STACK_SIZE, || {
Self::enclosing_points_with_bounds(
points,
&mut OVec::<OPoint<R, D>, DimNameSum<D, U1>>::new(),
&mut OVec::<OPoint<T, D>, DimNameSum<D, U1>>::new(),
)
.expect("Empty point set")
})
Expand All @@ -152,13 +152,13 @@ where
#[doc(hidden)]
#[must_use]
fn enclosing_points_with_bounds(
points: &mut impl Deque<OPoint<R, D>>,
bounds: &mut OVec<OPoint<R, D>, DimNameSum<D, U1>>,
points: &mut impl Deque<OPoint<T, D>>,
bounds: &mut OVec<OPoint<T, D>, DimNameSum<D, U1>>,
) -> Option<Self>
where
D: DimNameAdd<U1>,
DefaultAllocator: Allocator<R, D, D> + Allocator<OPoint<R, D>, DimNameSum<D, U1>>,
<DefaultAllocator as Allocator<OPoint<R, D>, DimNameSum<D, U1>>>::Buffer: Default,
DefaultAllocator: Allocator<T, D, D> + Allocator<OPoint<T, D>, DimNameSum<D, U1>>,
<DefaultAllocator as Allocator<OPoint<T, D>, DimNameSum<D, U1>>>::Buffer: Default,
{
// Take point from back.
if let Some(point) = points.pop_back().filter(|_| !bounds.is_full()) {
Expand Down

0 comments on commit 22db1d0

Please sign in to comment.