@@ -374,17 +374,26 @@ public Vector3d Normalize()
374374 /// If the vector is zero-length or already normalized, no operation is performed, but the original magnitude will still be output.
375375 /// </remarks>
376376 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
377- public Vector3d Normalize ( out Fixed64 m )
377+ public Vector3d Normalize ( out Fixed64 mag )
378378 {
379- Fixed64 mag = Magnitude ;
380- if ( mag > Fixed64 . Zero && mag != Fixed64 . One )
379+ mag = GetMagnitude ( this ) ;
380+
381+ // If magnitude is zero, return a zero vector to avoid divide-by-zero errors
382+ if ( mag == Fixed64 . Zero )
381383 {
382- x /= mag ;
383- y /= mag ;
384- z /= mag ;
384+ x = Fixed64 . Zero ;
385+ y = Fixed64 . Zero ;
386+ z = Fixed64 . Zero ;
387+ return this ;
385388 }
386389
387- m = mag ;
390+ // If already normalized, return as-is
391+ if ( mag == Fixed64 . One )
392+ return this ;
393+
394+ x /= mag ;
395+ y /= mag ;
396+ z /= mag ;
388397
389398 return this ;
390399 }
@@ -394,7 +403,7 @@ public Vector3d Normalize(out Fixed64 m)
394403 /// </summary>
395404 public bool IsNormalized ( )
396405 {
397- return Magnitude . Round ( ) - Fixed64 . One == Fixed64 . Zero ;
406+ return FixedMath . Abs ( Magnitude - Fixed64 . One ) <= Fixed64 . Epsilon ;
398407 }
399408
400409 /// <summary>
@@ -561,14 +570,21 @@ public static Vector3d Slerp(Vector3d start, Vector3d end, Fixed64 percent)
561570 public static Vector3d GetNormalized ( Vector3d value )
562571 {
563572 Fixed64 mag = GetMagnitude ( value ) ;
564- if ( mag > Fixed64 . Zero && mag != Fixed64 . One )
565- {
566- Fixed64 xM = value . x / mag ;
567- Fixed64 yM = value . y / mag ;
568- Fixed64 zM = value . z / mag ;
569- return new Vector3d ( xM , yM , zM ) ;
570- }
571- return value ;
573+
574+ // If magnitude is zero, return a zero vector to avoid divide-by-zero errors
575+ if ( mag == Fixed64 . Zero )
576+ return new Vector3d ( Fixed64 . Zero , Fixed64 . Zero , Fixed64 . Zero ) ;
577+
578+ // If already normalized, return as-is
579+ if ( mag == Fixed64 . One )
580+ return value ;
581+
582+ // Normalize it exactly
583+ return new Vector3d (
584+ value . x / mag ,
585+ value . y / mag ,
586+ value . z / mag
587+ ) ;
572588 }
573589
574590 /// <summary>
@@ -579,8 +595,13 @@ public static Vector3d GetNormalized(Vector3d value)
579595 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
580596 public static Fixed64 GetMagnitude ( Vector3d vector )
581597 {
582- Fixed64 temp1 = ( vector . x * vector . x ) + ( vector . y * vector . y ) + ( vector . z * vector . z ) ;
583- return temp1 != Fixed64 . Zero ? FixedMath . Sqrt ( temp1 ) : Fixed64 . Zero ;
598+ Fixed64 mag = ( vector . x * vector . x ) + ( vector . y * vector . y ) + ( vector . z * vector . z ) ;
599+
600+ // If rounding error pushed magnitude slightly above 1, clamp it
601+ if ( mag > Fixed64 . One && mag <= Fixed64 . One + Fixed64 . Epsilon )
602+ return Fixed64 . One ;
603+
604+ return mag != Fixed64 . Zero ? FixedMath . Sqrt ( mag ) : Fixed64 . Zero ;
584605 }
585606
586607 /// <summary>
@@ -1010,7 +1031,7 @@ public static Vector3d InverseRotate(Vector3d source, Vector3d position, FixedQu
10101031 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
10111032 public static Vector3d operator * ( Fixed4x4 matrix , Vector3d point )
10121033 {
1013- if ( matrix . IsAffine )
1034+ if ( matrix . IsAffine )
10141035 {
10151036 return new Vector3d (
10161037 matrix . m00 * point . x + matrix . m01 * point . y + matrix . m02 * point . z + matrix . m03 + matrix . m30 ,
0 commit comments