@@ -371,7 +371,7 @@ public static Quaternion Ln( this Quaternion q ) {
371371 double vMag = Math . Sqrt ( vMagSq ) ;
372372 double qMag = Math . Sqrt ( vMagSq + ( double ) q . w * q . w ) ;
373373 double theta = Math . Atan2 ( vMag , q . w ) ;
374- double scV = vMag < 0.01f ? Mathfs . SincRcp ( theta ) / qMag : theta / vMag ;
374+ double scV = vMag < 0.001 ? Mathfs . SincRcp ( theta ) / qMag : theta / vMag ;
375375 return new Quaternion (
376376 ( float ) ( scV * q . x ) ,
377377 ( float ) ( scV * q . y ) ,
@@ -385,7 +385,7 @@ public static Quaternion LnUnit( this Quaternion q ) {
385385 double vMagSq = ( double ) q . x * q . x + ( double ) q . y * q . y + ( double ) q . z * q . z ;
386386 double vMag = Math . Sqrt ( vMagSq ) ;
387387 double theta = Math . Atan2 ( vMag , q . w ) ;
388- double scV = vMag < 0.01f ? Mathfs . SincRcp ( theta ) : theta / vMag ;
388+ double scV = vMag < 0.001 ? Mathfs . SincRcp ( theta ) : theta / vMag ;
389389 return new Quaternion (
390390 ( float ) ( scV * q . x ) ,
391391 ( float ) ( scV * q . y ) ,
@@ -411,42 +411,24 @@ public static Quaternion ExpPureIm( this Quaternion q ) {
411411
412412 /// <summary>Returns the quaternion raised to a real power</summary>
413413 public static Quaternion Pow ( this Quaternion q , float x ) {
414- switch ( x ) {
415- case 0f : return new Quaternion ( 0 , 0 , 0 , 1 ) ;
416- case 1f : return q ;
417- }
418- double vSqMag = q . x * q . x + q . y * q . y + q . z * q . z ;
419- double rSqMag = q . w * q . w ;
420- double vMag = Math . Sqrt ( vSqMag ) ;
421- double qMag = Math . Sqrt ( rSqMag + vSqMag ) ;
422- double nx = q . x / vMag ;
423- double ny = q . y / vMag ;
424- double nz = q . z / vMag ;
425- double ang = Math . Acos ( ( q . w / qMag ) . ClampNeg1to1 ( ) ) ;
426- double theta = ang * x ;
427- double magPow = Math . Pow ( qMag , x ) ;
428- double cos = magPow * Math . Cos ( theta ) ;
429- double sin = magPow * Math . Sin ( theta ) ;
430- return new Quaternion ( ( float ) ( sin * nx ) , ( float ) ( sin * ny ) , ( float ) ( sin * nz ) , ( float ) cos ) ;
414+ return x switch {
415+ 0f => new Quaternion ( 0 , 0 , 0 , 1 ) ,
416+ 1f => q ,
417+ _ => q . Ln ( ) . Mul ( x ) . Exp ( )
418+ } ;
431419 }
432420
433421 /// <summary>Returns the unit quaternion raised to a real power</summary>
434422 public static Quaternion PowUnit ( this Quaternion q , float x ) {
435- switch ( x ) {
436- case 0f : return new Quaternion ( 0 , 0 , 0 , 1 ) ;
437- case 1f : return q ;
438- }
439- double vSqMag = q . x * q . x + q . y * q . y + q . z * q . z ;
440- double vMag = Math . Sqrt ( vSqMag ) ;
441- double nx = q . x / vMag ;
442- double ny = q . y / vMag ;
443- double nz = q . z / vMag ;
444- double ang = Math . Acos ( q . w . ClampNeg1to1 ( ) ) ;
445- double theta = ang * x ;
446- double cos = Math . Cos ( theta ) ;
447- double sin = Math . Sin ( theta ) ;
448- return new Quaternion ( ( float ) ( sin * nx ) , ( float ) ( sin * ny ) , ( float ) ( sin * nz ) , ( float ) cos ) ;
423+ return x switch {
424+ 0f => new Quaternion ( 0 , 0 , 0 , 1 ) ,
425+ 1f => q ,
426+ _ => q . LnUnit ( ) . Mul ( x ) . ExpPureIm ( )
427+ } ;
449428 }
429+
430+ /// <summary>Returns the imaginary part of a quaternion as a vector</summary>
431+ public static Vector3 Imag ( this Quaternion q ) => new Vector3 ( q . x , q . y , q . z ) ;
450432
451433 /// <summary>Returns the squared magnitude of this quaternion</summary>
452434 public static float SqrMagnitude ( this Quaternion q ) => ( float ) ( ( double ) q . w * q . w + ( double ) q . x * q . x + ( double ) q . y * q . y + ( double ) q . z * q . z ) ;
@@ -472,6 +454,20 @@ public static Quaternion PowUnit( this Quaternion q, float x ) {
472454 /// <inheritdoc cref="Quaternion.Inverse(Quaternion)"/>
473455 public static Quaternion Inverse ( this Quaternion q ) => Quaternion . Inverse ( q ) ;
474456
457+ /// <summary>The inverse of a unit quaternion, equivalent to the quaternion conjugate</summary>
458+ public static Quaternion InverseUnit ( this Quaternion q ) {
459+ return new Quaternion ( - q . x , - q . y , - q . z , q . w ) ;
460+ }
461+
462+ /// <summary>The inverse of a pure imaginary unit quaternion, where w is assumed to be 0</summary>
463+ public static Quaternion InversePureIm ( this Quaternion q ) {
464+ float sqMag = q . x * q . x + q . y * q . y + q . z * q . z ;
465+ return new Quaternion ( - q . x / sqMag , - q . y / sqMag , - q . z / sqMag , 0 ) ;
466+ }
467+
468+ /// <summary>Add to the magnitude of this quaternion</summary>
469+ public static Quaternion AddMagnitude ( this Quaternion q , float amount ) => amount == 0f ? q : q . Mul ( 1 + amount / q . Magnitude ( ) ) ;
470+
475471 #endregion
476472
477473 #region Transform extensions
0 commit comments