@@ -751,6 +751,16 @@ where
751751 Self :: from_nalgebra_vector ( self . inner . normalize ( ) )
752752 }
753753
754+ /// Returns a unit vector with the same direction as this vector.
755+ ///
756+ /// Returns `None` if this vector's magnitude is less than or equal to `min_norm`.
757+ #[ must_use]
758+ pub fn try_normalized ( & self , min_norm : f64 ) -> Option < Self > {
759+ self . inner
760+ . try_normalize ( min_norm)
761+ . map ( Self :: from_nalgebra_vector)
762+ }
763+
754764 /// Computes the dot (scalar) product between this vector and another.
755765 ///
756766 /// Note that this method's return value is unitless since the unit of the dot product is not
@@ -1392,6 +1402,29 @@ mod tests {
13921402 assert_eq ! ( v. to_cartesian( ) , [ m( 0.0 ) , m( 0.0 ) , m( 0.0 ) ] ) ;
13931403 }
13941404
1405+ #[ test]
1406+ fn try_normalized_zero_vector_returns_none ( ) {
1407+ let v = Vector :: < TestFrd > :: zero ( ) ;
1408+
1409+ assert_eq ! ( v. try_normalized( 0.0 ) , None ) ;
1410+ }
1411+
1412+ #[ test]
1413+ fn try_normalized_nonzero_vector_returns_unit_vector ( ) {
1414+ let v = vector ! ( f = m( 3.0 ) , r = m( 0.0 ) , d = m( 4.0 ) ; in TestFrd ) ;
1415+
1416+ let normalized = v. try_normalized ( 0.0 ) . expect ( "non-zero vector" ) ;
1417+
1418+ assert_abs_diff_eq ! ( normalized. magnitude( ) . get:: <meter>( ) , 1.0 ) ;
1419+ }
1420+
1421+ #[ test]
1422+ fn try_normalized_returns_none_below_min_norm ( ) {
1423+ let v = vector ! ( f = m( 3.0 ) , r = m( 0.0 ) , d = m( 4.0 ) ; in TestFrd ) ; // magnitude is 5, but we set min_norm to 6
1424+
1425+ assert_eq ! ( v. try_normalized( 6.0 ) , None ) ;
1426+ }
1427+
13951428 #[ test]
13961429 fn lerp_works ( ) {
13971430 let v1 = vector ! ( f = m( 0.0 ) , r = m( 0.0 ) , d = m( 0.0 ) ; in TestFrd ) ;
0 commit comments