Skip to main content

Capt

Struct Capt 

Source
pub struct Capt<const K: usize, A = f32, I = usize> { /* private fields */ }
Expand description

A collision-affording point tree (CAPT), which allows for efficient collision-checking in a SIMD-parallel manner between spheres and point clouds.

§Generic parameters

  • K: The dimension of the space.
  • L: The lane size of this tree. Internally, this is the upper bound on the width of a SIMD lane that can be used in this data structure. The alignment of this structure must be a power of two.
  • A: The value of the axes of each point. This should typically be f32 or f64. This should implement Axis.
  • I: The index integer. This should generally be an unsigned integer, such as usize or u32. This should implement Index.

§Examples

// list of points in cloud
let points = [[0.0, 0.1], [0.4, -0.2], [-0.2, -0.1]];

// query radii must be between 0.0 and 0.2
let t = capt::Capt::<2>::new(&points, (0.0, 0.2));

assert!(!t.collides(&[0.0, 0.3], 0.1));
assert!(t.collides(&[0.0, 0.2], 0.15));

Implementations§

Source§

impl<A, I, const K: usize> Capt<K, A, I>
where A: Axis, I: Index,

Source

pub fn new(points: &[[A; K]], r_range: (A, A), n_lanes: usize) -> Self

Construct a new CAPT containing all the points in points.

r_range is a (minimum, maximum) pair containing the lower and upper bound on the radius of the balls which will be queried against the tree. n_lanes is the number of SIMD lanes to be used by this tree, and may be 1 for single-element batch requests.

§Panics

This function will panic if there are too many points in the tree to be addressed by I, or if any points contain non-finite non-real value. This can even be the case if there are fewer points in points than can be addressed by I as the CAPT may duplicate points for efficiency.

§Examples
let points = [[0.0]];

let capt = capt::Capt::<1>::new(&points, (0.0, f32::INFINITY));

assert!(capt.collides(&[1.0], 1.5));
assert!(!capt.collides(&[1.0], 0.5));

If there are too many points in points, this could cause a panic!

let points = [[0.0]; 256];

// note that we are using `u8` as our index type
let capt = capt::Capt::<1, 8, f32, u8>::new(&points, (0.0, f32::INFINITY));
Source

pub fn with_point_radius( points: &[[A; K]], r_range: (A, A), r_point: A, n_lanes: usize, ) -> Self

Construct a new CAPT containing all the points in points with a point radius r_point.

r_range is a (minimum, maximum) pair containing the lower and upper bound on the radius of the balls which will be queried against the tree. n_lanes is the number of SIMD lanes to be used by this tree, and may be 1 for single-element batch requests.

§Panics

This function will panic if there are too many points in the tree to be addressed by I, or if any points contain non-finite non-real value. This can even be the case if there are fewer points in points than can be addressed by I as the CAPT may duplicate points for efficiency.

§Examples
let points = [[0.0]];

let capt = capt::Capt::<1>::with_point_radius(&points, (0.0, f32::INFINITY), 0.2);

assert!(capt.collides(&[1.0], 1.5));
assert!(!capt.collides(&[1.0], 0.5));

If there are too many points in points, this could cause a panic!

let points = [[0.0]; 256];

// note that we are using `u8` as our index type
let capt = capt::Capt::<1, 8, f32, u8>::with_point_radius(&points, (0.0, f32::INFINITY), 0.2);
Source

pub fn try_new( points: &[[A; K]], r_range: (A, A), n_lanes: usize, ) -> Result<Self, NewCaptError>

Construct a new CAPT containing all the points in points, checking for index overflow.

r_range is a (minimum, maximum) pair containing the lower and upper bound on the radius of the balls which will be queried against the tree. n_lanes is the number of SIMD lanes to be used by this tree, and may be 1 for single-element batch requests.

§Errors

This function will return Err(NewCaptError::TooManyPoints) if there are too many points to be indexed by I. It will return Err(NewCaptError::NonFinite) if any element of points is non-finite.

§Examples

Unwrapping the output from this function is equivalent to calling Capt::new.

let points = [[0.0]];

let capt = capt::Capt::<1>::try_new(&points, (0.0, f32::INFINITY)).unwrap();

In failure, we get an Err.

let points = [[0.0]; 256];

// note that we are using `u8` as our index type
let opt = capt::Capt::<1, 8, f32, u8>::try_new(&points, (0.0, f32::INFINITY));

assert!(opt.is_err());
Source

pub fn try_with_point_radius( points: &[[A; K]], r_range: (A, A), r_point: A, n_lanes: usize, ) -> Result<Self, NewCaptError>

Construct a new CAPT containing all the points in points with a point radius r_point, checking for index overflow.

r_range is a (minimum, maximum) pair containing the lower and upper bound on the radius of the balls which will be queried against the tree. n_lanes is the number of SIMD lanes to be used by this tree, and may be 1 for single-element batch requests.

§Errors

This function will return Err(NewCaptError::TooManyPoints) if there are too many points to be indexed by I. It will return Err(NewCaptError::NonFinite) if any element of points is non-finite.

§Examples

Unwrapping the output from this function is equivalent to calling Capt::with_point_radius.

let points = [[0.0]];

let capt = capt::Capt::<1>::try_with_point_radius(&points, (0.0, f32::INFINITY), 0.01).unwrap();

In failure, we get an Err.

let points = [[0.0]; 256];

// note that we are using `u8` as our index type
let opt =
    capt::Capt::<1, 8, f32, u8>::try_with_point_radius(&points, (0.0, f32::INFINITY), 0.01);

assert!(opt.is_err());
Source

pub fn collides(&self, center: &[A; K], radius: A) -> bool

Determine whether a point in this tree is within a distance of radius to center.

Note that this function will accept query radii outside of the range r_range passed to the construction for this CAPT in Capt::new or Capt::try_new. However, if the query radius is outside this range, the tree may erroneously return false (that is, erroneously report non-collision).

§Examples
let points = [[0.0; 3], [1.0; 3], [0.1, 0.5, 1.0]];
let capt = capt::Capt::<3>::new(&points, (0.0, 1.0));

assert!(capt.collides(&[1.1; 3], 0.2));
assert!(!capt.collides(&[2.0; 3], 1.0));

// no guarantees about what this is, since the radius is greater than the construction range
println!(
    "collision check result is {:?}",
    capt.collides(&[100.0; 3], 100.0)
);

Trait Implementations§

Source§

impl<const K: usize, A: Clone, I: Clone> Clone for Capt<K, A, I>

Source§

fn clone(&self) -> Capt<K, A, I>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<const K: usize, A: Debug, I: Debug> Debug for Capt<K, A, I>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<const K: usize, A: PartialEq, I: PartialEq> PartialEq for Capt<K, A, I>

Source§

fn eq(&self, other: &Capt<K, A, I>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<const K: usize, A: Eq, I: Eq> Eq for Capt<K, A, I>

Source§

impl<const K: usize, A, I> StructuralPartialEq for Capt<K, A, I>

Auto Trait Implementations§

§

impl<const K: usize, A, I> Freeze for Capt<K, A, I>
where A: Freeze,

§

impl<const K: usize, A, I> RefUnwindSafe for Capt<K, A, I>

§

impl<const K: usize, A, I> Send for Capt<K, A, I>
where A: Send, I: Send,

§

impl<const K: usize, A, I> Sync for Capt<K, A, I>
where A: Sync, I: Sync,

§

impl<const K: usize, A, I> Unpin for Capt<K, A, I>
where A: Unpin,

§

impl<const K: usize, A, I> UnsafeUnpin for Capt<K, A, I>
where A: UnsafeUnpin,

§

impl<const K: usize, A, I> UnwindSafe for Capt<K, A, I>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.