weighted sum of quaternion

Problems building or running the engine, queries about how to use features etc.
Post Reply
p_designc
Greenskin
Posts: 132
Joined: Sun Sep 03, 2006 4:49 pm

weighted sum of quaternion

Post by p_designc »

Hello,

I would like to know how can i do the weighted sum of quaternion? I cannot do it by slerp...
w1, w2, w3, ..., wn
q1, q2, q3,..., qn

Code: Select all

q = Quaternion::Slerp(w1, q1, q2);
q = q * Quaternion::Slerp(w2, q2, q3);
... ???
Anyone can help??? :D
Ogre's big fans
User avatar
subquantum
Goblin
Posts: 270
Joined: Tue Oct 02, 2007 10:23 pm
Location: Rochester, NY
Contact:

Post by subquantum »

If by "weighted sum" you mean a weighted average of orientations, then slerp might be your best bet. For instance, if you had q1, q2, and q3 with weights w1, w2, and w3, you could do:

q = slerp( ((w1 + w2) / (w1 + w2 + w3)) , slerp(w1/w2, q1, q2) , q3);

And this can expand as large as you need it. It seems like a good candidate for recursion, actually. (BTW, I haven't finished my coffee this morning, so if anyone has a better way...)
nbeato
Gnome
Posts: 372
Joined: Thu Dec 20, 2007 1:00 am
Location: Florida
x 3
Contact:

Post by nbeato »

Slerp will interpolate 2 rotations. The result will still be a unit quaternion. So, as proposed, you would have to come up with clever math on the interpolation parameters to get this working correctly.

I'd suggest "viewing" the rotations as torque vectors and summing the rotational force on the object.

Converting the quaternion to angle/axis.
Sum the axis vector weighted by the product of the angle and weight.
Take the magnitude of the result as the new angle and normalize the axis.
Convert back to quaternion.

Psuedocode:

Code: Select all

// in
quat_with_weight inputs[N];

// result net torque as a rotation vector
vec3 accum(0,0,0);

foreach(q in inputs)
{
    // add the torque contributation of this rotation
    accum += q.getAngle() * q.weight * q.getUnitAxis();
}

// convert angle/axis back to quaternion
quat result(accum.magnitude(), accum.asUnitVector());

ocv808
Gnoblar
Posts: 16
Joined: Wed Mar 23, 2011 7:52 pm
Location: San Jose, California

Re: weighted sum of quaternion

Post by ocv808 »

Hello I used @nbeato formula to try and average quaternions. I was able to successfully get the formula to average the quaternions however it does seem to have some sort of bug. It tends to want to flip the quaternion over in certain circumstances, it seems mostly when it has been rotated 1Pi (180*) around a particular axis. This makes me assume that it is trying to average values near -Pi and Pi together and thus the product is around 0 which makes it rotate 180 degrees. I just cant figure out what would be a good solution to correct this.

Here is what I am doing in my code

Code: Select all

			
Ogre::Vector3 vAccum = Ogre::Vector3(0,0,0);
			Ogre::Quaternion qTemp;
			Ogre::Radian fAngle;
			Ogre::Vector3 vAxis;
			Ogre::Real fBaseW = 1.0 / m_vQuats.size();

			for(std::list<Ogre::Quaternion>::iterator i = m_vQuats.begin(); i != m_vQuats.end(); ++i)
			{
				qTemp = *i;
				qTemp.ToAngleAxis(fAngle,vAxis);
				//vAxis.normalise();
				vAccum += fAngle.valueRadians()  * vAxis * fBaseW;
			}

			Ogre::Quaternion qFinal = Ogre::Quaternion((Ogre::Radian)vAccum.length(), vAccum.normalisedCopy());
If anyone has any suggestions that would be greatly appreciated :D . Or a suggestion on a better way to do this would be awesome as well. Pretty much I am trying to take raw calculations from a compass and accelerometer (which can be noisy) and apply it to a object but smooth it out in the process.
Post Reply