@@ -511,12 +511,23 @@ macro_rules! impl_float_vector_fns {
511511 )
512512 }
513513
514- /// Returns the normalized vector pointing from this vector to `to`.
514+ /// Returns the normalized vector pointing from this vector to `to` or [`None`], if `self` and `to` are equal .
515515 ///
516- /// This is equivalent to using `(b - a).normalized()`.
516+ /// This is equivalent to using `(b - a).try_normalized()`. See also [`direction_to()`][Self::direction_to].
517+ #[ inline]
518+ pub fn try_direction_to( self , to: Self ) -> Option <Self > {
519+ ( to - self ) . try_normalized( )
520+ }
521+
522+ /// ⚠️ Returns the normalized vector pointing from this vector to `to`.
523+ ///
524+ /// This is equivalent to using `(b - a).normalized()`. See also [`try_direction_to()`][Self::try_direction_to].
525+ ///
526+ /// # Panics
527+ /// If `self` and `to` are equal.
517528 #[ inline]
518529 pub fn direction_to( self , to: Self ) -> Self {
519- ( to - self ) . normalized ( )
530+ self . try_direction_to ( to) . expect ( "direction_to() called on equal vectors" )
520531 }
521532
522533 /// Returns the squared distance between this vector and `to`.
@@ -575,17 +586,36 @@ macro_rules! impl_float_vector_fns {
575586 )
576587 }
577588
578- /// Returns the vector scaled to unit length. Equivalent to `self / self.length()`. See
579- /// also `is_normalized()`.
589+ /// Returns the vector scaled to unit length or [`None`], if called on a zero vector.
590+ ///
591+ /// Computes `self / self.length()`. See also [`normalized()`][Self::normalized] and [`is_normalized()`][Self::is_normalized].
592+ #[ inline]
593+ pub fn try_normalized( self ) -> Option <Self > {
594+ if self == Self :: ZERO {
595+ return None ;
596+ }
597+
598+ // Copy Godot's implementation since it's faster than using glam's normalize_or_zero().
599+ Some ( self / self . length( ) )
600+ }
601+
602+ /// ⚠️ Returns the vector scaled to unit length.
603+ ///
604+ /// Computes `self / self.length()`. See also [`try_normalized()`][Self::try_normalized] and [`is_normalized()`][Self::is_normalized].
580605 ///
581606 /// # Panics
582607 /// If called on a zero vector.
583608 #[ inline]
584609 pub fn normalized( self ) -> Self {
585- assert_ne!( self , Self :: ZERO , "normalized() called on zero vector" ) ;
610+ self . try_normalized( ) . expect( "normalized() called on zero vector" )
611+ }
586612
587- // Copy Godot's implementation since it's faster than using glam's normalize_or_zero().
588- self / self . length( )
613+ /// Returns the vector scaled to unit length or [`Self::ZERO`], if called on a zero vector.
614+ ///
615+ /// Computes `self / self.length()`. See also [`try_normalized()`][Self::try_normalized] and [`is_normalized()`][Self::is_normalized].
616+ #[ inline]
617+ pub fn normalized_or_zero( self ) -> Self {
618+ self . try_normalized( ) . unwrap_or_default( )
589619 }
590620
591621 /// Returns a vector composed of the [`FloatExt::fposmod`] of this vector's components and `pmod`.
0 commit comments