@@ -390,6 +390,7 @@ where
390390 starts : Box < [ I ] > ,
391391 /// The sets of afforded points for each cell.
392392 afforded : [ Box < [ MySimd < A , L > ] > ; K ] ,
393+ r_point : A ,
393394}
394395
395396#[ repr( C ) ]
@@ -456,11 +457,46 @@ where
456457 . expect ( "index type I must be able to support all points in CAPT during construction" )
457458 }
458459
460+ /// Construct a new CAPT containing all the points in `points` with a point radius `r_point`.
461+ ///
462+ /// `r_range` is a `(minimum, maximum)` pair containing the lower and upper bound on the
463+ /// radius of the balls which will be queried against the tree.
464+ ///
465+ /// # Panics
466+ ///
467+ /// This function will panic if there are too many points in the tree to be addressed by `I`, or
468+ /// if any points contain non-finite non-real value. This can even be the case if there are
469+ /// fewer points in `points` than can be addressed by `I` as the CAPT may duplicate points
470+ /// for efficiency.
471+ ///
472+ /// # Examples
473+ ///
474+ /// ```
475+ /// let points = [[0.0]];
476+ ///
477+ /// let capt = capt::Capt::<1>::with_point_radius(&points, (0.0, f32::INFINITY), 0.2);
478+ ///
479+ /// assert!(capt.collides(&[1.0], 1.5));
480+ /// assert!(!capt.collides(&[1.0], 0.5));
481+ /// ```
482+ ///
483+ /// If there are too many points in `points`, this could cause a panic!
484+ ///
485+ /// ```rust,should_panic
486+ /// let points = [[0.0]; 256];
487+ ///
488+ /// // note that we are using `u8` as our index type
489+ /// let capt = capt::Capt::<1, 8, f32, u8>::with_point_radius(&points, (0.0, f32::INFINITY), 0.2);
490+ /// ```
491+ pub fn with_point_radius ( points : & [ [ A ; K ] ] , r_range : ( A , A ) , r_point : A ) -> Self {
492+ Self :: try_with_point_radius ( points, r_range, r_point)
493+ . expect ( "index type I must be able to support all points in CAPT during construction" )
494+ }
495+
459496 /// Construct a new CAPT containing all the points in `points`, checking for index overflow.
460497 ///
461498 /// `r_range` is a `(minimum, maximum)` pair containing the lower and upper bound on the
462499 /// radius of the balls which will be queried against the tree.
463- /// `rng` is a random number generator.
464500 ///
465501 /// # Errors
466502 ///
@@ -489,6 +525,48 @@ where
489525 /// assert!(opt.is_err());
490526 /// ```
491527 pub fn try_new ( points : & [ [ A ; K ] ] , r_range : ( A , A ) ) -> Result < Self , NewCaptError > {
528+ Self :: try_with_point_radius ( points, r_range, A :: ZERO )
529+ }
530+
531+ /// Construct a new CAPT containing all the points in `points` with a point radius `r_point`,
532+ /// checking for index overflow.
533+ ///
534+ /// `r_range` is a `(minimum, maximum)` pair containing the lower and upper bound on the
535+ /// radius of the balls which will be queried against the tree.
536+ ///
537+ /// # Errors
538+ ///
539+ /// This function will return `Err(NewCaptError::TooManyPoints)` if there are too many points to
540+ /// be indexed by `I`. It will return `Err(NewCaptError::NonFinite)` if any element of
541+ /// `points` is non-finite.
542+ ///
543+ /// # Examples
544+ ///
545+ /// Unwrapping the output from this function is equivalent to calling
546+ /// [`Capt::with_point_radius`].
547+ ///
548+ /// ```
549+ /// let points = [[0.0]];
550+ ///
551+ /// let capt = capt::Capt::<1>::try_with_point_radius(&points, (0.0, f32::INFINITY), 0.01).unwrap();
552+ /// ```
553+ ///
554+ /// In failure, we get an `Err`.
555+ ///
556+ /// ```
557+ /// let points = [[0.0]; 256];
558+ ///
559+ /// // note that we are using `u8` as our index type
560+ /// let opt =
561+ /// capt::Capt::<1, 8, f32, u8>::try_with_point_radius(&points, (0.0, f32::INFINITY), 0.01);
562+ ///
563+ /// assert!(opt.is_err());
564+ /// ```
565+ pub fn try_with_point_radius (
566+ points : & [ [ A ; K ] ] ,
567+ r_range : ( A , A ) ,
568+ r_point : A ,
569+ ) -> Result < Self , NewCaptError > {
492570 let n2 = points. len ( ) . next_power_of_two ( ) ;
493571
494572 if points. iter ( ) . any ( |p| p. iter ( ) . any ( |x| !x. is_finite ( ) ) ) {
@@ -534,6 +612,7 @@ where
534612 starts,
535613 afforded : afforded. map ( Vec :: into_boxed_slice) ,
536614 aabbs,
615+ r_point,
537616 } )
538617 }
539618
@@ -708,7 +787,8 @@ where
708787 /// capt.collides(&[100.0; 3], 100.0)
709788 /// );
710789 /// ```
711- pub fn collides ( & self , center : & [ A ; K ] , radius : A ) -> bool {
790+ pub fn collides ( & self , center : & [ A ; K ] , mut radius : A ) -> bool {
791+ radius = radius + self . r_point ;
712792 // forward pass through the tree
713793 let mut test_idx = 0 ;
714794 let mut k = 0 ;
@@ -799,14 +879,15 @@ where
799879 ///
800880 /// assert!(tree.collides_simd(¢ers, radii));
801881 /// ```
802- pub fn collides_simd ( & self , centers : & [ Simd < A , L > ; K ] , radii : Simd < A , L > ) -> bool
882+ pub fn collides_simd ( & self , centers : & [ Simd < A , L > ; K ] , mut radii : Simd < A , L > ) -> bool
803883 where
804884 LaneCount < L > : SupportedLaneCount ,
805885 Simd < A , L > :
806886 SimdPartialOrd + Sub < Output = Simd < A , L > > + Mul < Output = Simd < A , L > > + AddAssign ,
807887 Mask < isize , L > : From < <Simd < A , L > as SimdPartialEq >:: Mask > ,
808888 A : Axis + AxisSimd < <Simd < A , L > as SimdPartialEq >:: Mask > ,
809889 {
890+ radii += Simd :: splat ( self . r_point ) ;
810891 let zs = forward_pass_simd ( & self . tests , centers) ;
811892
812893 let mut inbounds = Mask :: splat ( true ) ;
@@ -1068,4 +1149,14 @@ mod tests {
10681149 assert ! ( p0[ 0 ] >= median) ;
10691150 }
10701151 }
1152+
1153+ #[ test]
1154+ fn point_radius ( ) {
1155+ let points = [ [ 0.0 , 0.0 ] , [ 0.0 , 1.0 ] ] ;
1156+ let r_range = ( 0.0 , 1.0 ) ;
1157+
1158+ let capt: Capt < _ , 8 , _ , u32 > = Capt :: with_point_radius ( & points, r_range, 0.5 ) ;
1159+ assert ! ( capt. collides( & [ 0.6 , 0.0 ] , 0.2 ) ) ;
1160+ assert ! ( !capt. collides( & [ 0.6 , 0.0 ] , 0.05 ) ) ;
1161+ }
10711162}
0 commit comments