예제 #1
0
		// ================================================================================

		/// <summary>
		/// Calculate the dot product (inner product) between two quaternions
		/// </summary>
		/// <param name="a"></param>
		/// <param name="b"></param>
		/// <returns></returns>
		static public float	DotProduct( Quaternion a, Quaternion b ) {
			return	a.X * b.X + 
					a.Y * b.Y + 
					a.Z * b.Z + 
					a.W * b.W;
		}
예제 #2
0
		/// <summary>
		/// Get the spherically interpolated quaternion at position t between
		/// a and b (UNVERIFIED)
		/// </summary>
		/// <param name="a"></param>
		/// <param name="b"></param>
		/// <param name="t"></param>
		/// <returns></returns>
		static public Quaternion Slerp( Quaternion a, Quaternion b, float t ) {
			// TODO: verify the validity of this function
			Debug.WriteLine( "Quaternion.Slerp() - warning, this function has not be checked for validity." );
			
			// Calculate the cosine of the angle between the two
			float fScale0, fScale1;
			double dCos = Quaternion.DotProduct( a, b );

			// If the angle is significant, use the spherical interpolation
			if( ( 1.0 - Math.Abs( dCos ) ) > 1e-6f ) {
				double dTemp = Math.Acos( Math.Abs( dCos ) );
				double dSin = Math.Sin( dTemp );
				fScale0 = (float)( Math.Sin( ( 1.0 - t ) * dTemp ) / dSin );
				fScale1 = (float)( Math.Sin( t * dTemp ) / dSin );
			}
				// Else use the cheaper linear interpolation
			else {
				fScale0 = 1.0f - t;
				fScale1 = t;
			}
			if(dCos < 0.0)
				fScale1 = -fScale1;

			// Return the interpolated result
			return (a * fScale0) + (b * fScale1);
		}
예제 #3
0
		/// <summary>
		/// Create a quaternion from a 3D homogeneous transform
		/// </summary>
		/// <param name="xfrm"></param>
		/// <returns></returns>
		static public Quaternion	FromTransform( Matrix3D xfrm ) {
			Quaternion quat = new Quaternion();
			
			// Check the sum of the diagonal
			float tr = xfrm[ 0, 0 ] + xfrm[ 1, 1 ] + xfrm[ 2, 2 ];
			if(tr > 0.0f) {
				// The sum is positive
				// 4 muls, 1 div, 6 adds, 1 trig function call
				float s = (float) Math.Sqrt( tr + 1.0f );
				quat.W = s * 0.5f;
				s = 0.5f / s;
				quat.X = ( xfrm[ 1, 2 ] - xfrm[ 2, 1 ] ) * s;
				quat.Y = ( xfrm[ 2, 0 ] - xfrm[ 0, 2 ] ) * s;
				quat.Z = ( xfrm[ 0, 1 ] - xfrm[ 1, 0 ] ) * s;
			}
			else {
				// The sum is negative
				// 4 muls, 1 div, 8 adds, 1 trig function call
				int[] nIndex = { 1, 2, 0 };
				int i, j, k;
				i = 0;
				if( xfrm[ 1, 1 ] >  xfrm[ i, i ] )
					i = 1;
				if( xfrm[ 2, 2 ] > xfrm[ i, i ] )
					i = 2;
				j = nIndex[i];
				k = nIndex[j];

				float s = (float) Math.Sqrt(( xfrm[ i, i ] - ( xfrm[ j, j ] + xfrm[ k, k ] ) ) + 1.0f );
				quat[ i ] = s * 0.5f;
				if( s != 0.0 ) {
					s = 0.5f / s;
				}
				quat[ j ] = ( xfrm[ i, j ] + xfrm[ j, i ] ) * s;
				quat[ k ] = ( xfrm[ i, k ] + xfrm[ k, i ] ) * s;
				quat[ 3 ] = ( xfrm[ j, k ] - xfrm[ k, j ] ) * s;
			}
			return quat;
		}