• Advertisement
Sign in to follow this  

Quaternion multiplication

This topic is 598 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

The code I see for Quaternion multiplication on System.Numerics.Vectors is different (reversed) from all the other code I see on the Internet. What gives?

 

http://www.dotnetframework.org/default.aspx/DotNET/DotNET/8@0/untmp/WIN_WINDOWS/lh_tools_devdiv_wpf/Windows/wcp/Core/System/Windows/Media3D/Quaternion@cs/1/Quaternion@cs

 

        public static Quaternion operator *(Quaternion left, Quaternion right)
        {
            if (left.IsDistinguishedIdentity)
            {
                return right;
            }
            if (right.IsDistinguishedIdentity)
            {
                return left;
            }
 
            double x = left._w * right._x + left._x * right._w + left._y * right._z - left._z * right._y;
            double y = left._w * right._y + left._y * right._w + left._z * right._x - left._x * right._z;
            double z = left._w * right._z + left._z * right._w + left._x * right._y - left._y * right._x;
            double w = left._w * right._w - left._x * right._x - left._y * right._y - left._z * right._z;
            Quaternion result = new Quaternion(x,y,z,w);
            return result;
 
        }
 

https://github.com/dotnet/corefx/blob/master/src/System.Numerics.Vectors/src/System/Numerics/Quaternion.cs

 

        public static Quaternion operator *(Quaternion value1, Quaternion value2)
        {
            Quaternion ans;
 
            float q1x = value1.X;
            float q1y = value1.Y;
            float q1z = value1.Z;
            float q1w = value1.W;
 
            float q2x = value2.X;
            float q2y = value2.Y;
            float q2z = value2.Z;
            float q2w = value2.W;
 
            // cross(av, bv)
            float cx = q1y * q2z - q1z * q2y;
            float cy = q1z * q2x - q1x * q2z;
            float cz = q1x * q2y - q1y * q2x;
 
            float dot = q1x * q2x + q1y * q2y + q1z * q2z;
 
            ans.X = q1x * q2w + q2x * q1w + cx;
            ans.Y = q1y * q2w + q2y * q1w + cy;
            ans.Z = q1z * q2w + q2z * q1w + cz;
            ans.W = q1w * q2w - dot;
 
            return ans;
        }
Edited by ExpensiveInk

Share this post


Link to post
Share on other sites
Advertisement
Quaternion multiplication is well defined in the Math literature. i*j = -j*i = k, j*k = -k*j = i, k*i = -i*k = j, and everything else can be deduced from the fact that 1 is the neutral element of multiplication and by linearity.

Try to multiply i*j and if you get something different than k, it's broken.

Share this post


Link to post
Share on other sites

Let's define a quaternion like this:

struct Quaternion 
{
    Vector3 v; 
    float s;
};

Then the quaternion product is defined as:

Quaternion operator*( const Quaternion& q1, const Quaternion& q2 )
{
    Quaternion result;
    result.v = cross( q1.v, q2.v )+ q1.s * q2.v + q2.s * q1.v;
    result.s = q1.s * q2.s - dot( q1, q2 );

    return result;
}

Both your functions are equivalent. The vector'ish form is just less usual in literature in my experience. If you write the definition above component-wise you will get the same result!

Edited by Dirk Gregorius

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement