@@ -414,6 +414,24 @@ pub enum NewCaptError {
414414 InvalidLaneCount ,
415415}
416416
417+ /// An iterator over the points in a `[Capt]`.
418+ /// This structure can only be created by `[Capt::points]`.
419+ /// This iterator also skips non-finite points.
420+ ///
421+ /// # Examples
422+ ///
423+ /// ```
424+ /// # use capt::{Capt, Points};
425+ ///
426+ /// let capt = Capt::<1>::new(&[[0.0]], (0.0, f32::INFINITY), 1);
427+ /// let _points: Points<1> = capt.points();
428+ /// ```
429+ pub struct Points < ' a , const K : usize , A = f32 , I = usize > {
430+ afforded : [ & ' a [ A ] ; K ] ,
431+ starts : & ' a [ I ] ,
432+ i : usize ,
433+ }
434+
417435impl < A , I , const K : usize > Capt < K , A , I >
418436where
419437 A : Axis ,
@@ -849,6 +867,27 @@ where
849867 } )
850868 }
851869
870+ /// Get an iterator over the points in this Capt.
871+ /// The iterator skips non-finite points.
872+ /// It makes no guarantee of iteration order.
873+ ///
874+ ///
875+ /// ```
876+ /// # use capt::{Capt, Points};
877+ ///
878+ /// let capt = Capt::<2>::new(&[[0.0, 1.0]], (0.0, f32::INFINITY), 1);
879+ /// for point in capt.points() {
880+ /// println!("{point:?}");
881+ /// }
882+ /// ```
883+ pub fn points ( & self ) -> Points < ' _ , K , A , I > {
884+ Points {
885+ afforded : self . afforded . each_ref ( ) . map ( |x| & * * x) ,
886+ starts : & self . starts ,
887+ i : 0 ,
888+ }
889+ }
890+
852891 #[ must_use]
853892 #[ doc( hidden) ]
854893 /// Get the total memory used (stack + heap) by this structure, measured in bytes.
@@ -984,6 +1023,45 @@ where
9841023 }
9851024}
9861025
1026+ impl < const K : usize , A : Axis , I : Index > Iterator for Points < ' _ , K , A , I > {
1027+ type Item = [ A ; K ] ;
1028+
1029+ fn next ( & mut self ) -> Option < Self :: Item > {
1030+ while self . i + 1 < self . starts . len ( ) {
1031+ let j = self . starts [ self . i ]
1032+ . try_into ( )
1033+ . map_err ( |_| ( ) )
1034+ . expect ( "must be able to convert index into usize" ) ;
1035+ let j2 = self . starts [ self . i + 1 ]
1036+ . try_into ( )
1037+ . map_err ( |_| ( ) )
1038+ . expect ( "must be able to convert index into usize" ) ;
1039+ self . i += 1 ;
1040+
1041+ if j == j2 {
1042+ // zero points in the afforded set
1043+ continue ;
1044+ }
1045+ let ret = self . afforded . map ( |a| a[ j] ) ;
1046+
1047+ // skip non-finite points
1048+ if ret. iter ( ) . all ( |x| x. is_finite ( ) ) {
1049+ return Some ( ret) ;
1050+ }
1051+ }
1052+ None
1053+ }
1054+
1055+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
1056+ let n = if self . i + 1 >= self . starts . len ( ) {
1057+ 0
1058+ } else {
1059+ self . starts . len ( ) - self . i - 1
1060+ } ;
1061+ ( 0 , Some ( n) )
1062+ }
1063+ }
1064+
9871065fn distsq < A : Axis , const K : usize > ( a : [ A ; K ] , b : [ A ; K ] ) -> A {
9881066 let mut total = A :: ZERO ;
9891067 for i in 0 ..K {
@@ -1193,4 +1271,37 @@ mod tests {
11931271 assert ! ( capt. collides( & [ 0.6 , 0.0 ] , 0.2 ) ) ;
11941272 assert ! ( !capt. collides( & [ 0.6 , 0.0 ] , 0.05 ) ) ;
11951273 }
1274+
1275+ #[ test]
1276+ fn get_points ( ) {
1277+ let mut points = [
1278+ [ -1.0 , 0.0 ] ,
1279+ [ 0.001 , 0.0 ] ,
1280+ [ 0.0 , 0.5 ] ,
1281+ [ -1.0 , 10.0 ] ,
1282+ [ -2.0 , 10.0 ] ,
1283+ [ -3.0 , 10.0 ] ,
1284+ [ -0.5 , 0.0 ] ,
1285+ [ -11.0 , 1.0 ] ,
1286+ [ -1.0 , -0.5 ] ,
1287+ [ 1.0 , 1.0 ] ,
1288+ [ 2.0 , 2.0 ] ,
1289+ [ 3.0 , 3.0 ] ,
1290+ [ 4.0 , 4.0 ] ,
1291+ [ 5.0 , 5.0 ] ,
1292+ [ 6.0 , 6.0 ] ,
1293+ [ 7.0 , 7.0 ] ,
1294+ [ 9.0 , 0.0 ] ,
1295+ ] ;
1296+
1297+ // sort points in order
1298+ points. sort_by ( |p1, p2| p1. partial_cmp ( & p2) . unwrap ( ) ) ;
1299+
1300+ let capt = Capt :: < 2 > :: new ( & points, ( 0.0 , 0.1 ) , 1 ) ;
1301+ println ! ( "{:?}" , capt) ;
1302+ let mut points2 = capt. points ( ) . collect :: < Vec < _ > > ( ) ;
1303+ points2. sort_by ( |p1, p2| p1. partial_cmp ( & p2) . unwrap ( ) ) ;
1304+
1305+ assert_eq ! ( & points, & * points2) ;
1306+ }
11961307}
0 commit comments