No need to normalize this quaternion

Started by
10 comments, last by Dmytry 19 years, 7 months ago
Just a quicky. I'm not gonna pretend like I know what I'm talking about. Quaternions are pretty new to me (Heh, [looksaround] ..matrices are pretty new to me). From what I understand, a normalized unit quaternion is where the square-root of the sum of x,y,z and w sqaured is 1, right? Or something like this..
(x*x) + (y*y) + (z*z) + (w*w) == 1
If I have two unit quaternions, and I want to add them together, do I need to normalize if the percentages I'm adding together will always be 1? Example..

float perc = 0.7f;
float opp_perc = 1.0f - perc;

// these two quaternions come from elsewhere, and are both
// always units and normalized..
QUAT a,b;

// interpolated result
QUAT c = (a * perc) + (b * opp_perc);


Will quaternion c always be a normalized unit? Testing it seems great, but my lack of knowledge in this area means there could be deep holes somewhere down the road. Thanks for any advice.
Advertisement
I may have make a mistake in the following but...
a = (w,x,y,z) with ww+xx+yy+zz=1b = (W,X,Y,Z) with WW+XX+YY+ZZ=1c = p (w,x,y,z) + (1-p) (W,X,Y,Z)  = (W+pw-pW, X+px-pX, Y+py-pY, Z+pz-pZ)||c|| = (W+pw-pW)^2 + (X+px-pX)^2 + (Y+py-pY)^2 + (Z+pz-pZ)^2      = WW + ppww + ppWW +      2Wpw - 2WpW - 2ppwW +        XX + ppxx + ppXX +      2Xpx - 2XpX - 2ppxX +        YY + ppyy + ppYY +      2Ypy - 2YpY - 2ppyY +        ZZ + ppzz + ppZZ +      2Zpz - 2ZpZ - 2ppzZ       =  1 + pp   + pp   + 2p (  Ww   - WW   - pwW  +                                 Xx   - XX   - pxX  +                                 Yy   - YY   - pyY  +                                 Zz   - ZZ   - pzZ )      = 1 - 2p + 2pp + 2p(1-p) ( Ww + Xx + Yy + Zz )      = 1 + 2p(1-p)(a.b - 1)


Which won't be equal to 1, unless a.b = 1, p=0 or p=1.

[Edited by - Fruny on September 19, 2004 7:18:00 PM]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Nope, you can't guarenttee that. Quaternion addition is no different to vector addition, so think of it like a 2D vector. (EDIT: Well, a 4D vector, but the number of dimensions doesn't matter and 2D is easy to do ASCII art for [smile])

^
|
| A
|
|
<--------
B

Is the length of A+B equal to the length of A + the length of B?
Nope.
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
Hmm.. I think you'd more than likely need to renormalize it. I haven't checked, but I'm thinking unless A == B or perc == 0 or 1 then you'll never get a normalized result.

To visualize, think about the case of 2D vectors:
^___^___ ^ \ C|  /A \ | / B   \|/


If A and B are normalized (length == 1), then any vector between them (C) is going to have a length less than 1. Quaternions are 4D, but the idea is the same.

And just as an aside, if you're using a linear interpolation to interpolate quaternions for skeletal animation, you'd be able to get better (smoother) results by using spherical linear interpolation (slerp)

-nohbdy
You're saying that the result of adding them will not be a unit, or that a unit is not calculated in the way that I mentioned?

I can't understand why. If the sum of 4 numbers is 1, and another sum of 4 numbers is 1, isn't this always true?
(sum1 * factor) + (sum2 * (1.0 - factor)) == 1?// In other words, sum1 * 0.5 should makes the sum1 equal 0.5// instead of 1. Right? sum1 * 0.7 makes the sum equal to 0.7.(0.10 + 0.60 + 0.20 + 0.10) * 0.5 == (0.05 + 0.30 + 0.10 + 0.05)(0.30 + 0.20 + 0.10 + 0.40) * 0.5 == (0.15 + 0.10 + 0.05 + 0.20)// so(0.05 + 0.30 + 0.10 + 0.05) + (0.15 + 0.10 + 0.05 + 0.20)// results in(0.20 + 0.40 + 0.15 + 0.25)// HEAVILY edited - sorry for messing this up so bad

Where am I getting lossed?
Quote:Original post by Jiia
If the sum of 4 numbers is 1, and another sum of 4 numbers is 1, isn't this always true?


We don't care about the sum of the numbers, we care about the sum of their squares: (pw+(1-p)W)^2+(px+(1-p)X)^2+(py+(1-p)Y)^2+(pz+(1-p)Z)^2
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Here are some printed out values of real in-game quaternions. Am I accidently getting values that work? It always seems to work..?

Format is  (Ax, Ay, Az, Aw) * opp_perc+ (Bx, By, Bz, Bw) * perc= (Cx, Cy, Cz, Cw) (sum of C's sqaured values)  (-0.016, -0.197, 0.007, 0.980) * 0.210+ (-0.016, -0.218, 0.006, 0.976) * 0.790= -0.016, -0.214, 0.006, 0.977 (sum of sqaures = 1.000)  (-0.016, -0.229, 0.006, 0.973) * 0.320+ (-0.015, -0.248, 0.008, 0.969) * 0.680= -0.016, -0.242, 0.008, 0.970 (sum of sqaures = 1.000)  (-0.015, -0.259, 0.011, 0.966) * 0.460+ (-0.013, -0.267, 0.015, 0.964) * 0.540= -0.014, -0.263, 0.013, 0.965 (sum of sqaures = 1.000)  (-0.012, -0.281, 0.020, 0.959) * 0.540+ (-0.010, -0.289, 0.025, 0.957) * 0.460= -0.011, -0.285, 0.022, 0.958 (sum of sqaures = 1.000)  (-0.006, -0.313, 0.033, 0.949) * 0.590+ (-0.000, -0.320, 0.040, 0.947) * 0.410= -0.004, -0.316, 0.036, 0.948 (sum of sqaures = 1.000)  (0.012, -0.021, 0.080, 0.997) * 0.880+ (0.006, 0.035, 0.079, 0.996) * 0.120= 0.011, -0.015, 0.079, 0.996 (sum of sqaures = 1.000)  (-0.015, 0.149, 0.061, 0.987) * 0.810+ (-0.017, 0.174, 0.054, 0.983) * 0.190= -0.016, 0.154, 0.060, 0.986 (sum of sqaures = 1.000)  (-0.016, -0.197, 0.007, 0.980) * 0.990+ (-0.016, -0.218, 0.006, 0.976) * 0.010= -0.016, -0.197, 0.007, 0.980 (sum of sqaures = 1.000)


[Edited by - Jiia on September 19, 2004 8:19:08 PM]
Quote:Original post by Jiia
Here are some printed out values of real in-game quaternions. Am I accidently getting values that work? It always seems to work..?

*** Source Snippet Removed ***

First, those test quaternions are all very similar, so they will produce similar results. Second, you're cutting off precision.
-0.004^2 + -0.316^2 + 0.036^2 + 0.948^2 = 0.999872
Try using extreme cases, such as a rotation of 90 degrees around the X axis interpolated with a 90 degree rotation around the Y axis. You may be luck in that in-game values are 'close enough' that occasionaly normalisation to avoid numerical errors will hide the problem. But then again, you may not.
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
Quote:Original post by joanusdmentia
First, those test quaternions are all very similar, so they will produce similar results. Second, you're cutting off precision.
-0.004^2 + -0.316^2 + 0.036^2 + 0.948^2 = 0.999872
Try using extreme cases, such as a rotation of 90 degrees around the X axis interpolated with a 90 degree rotation around the Y axis. You may be luck in that in-game values are 'close enough' that occasionaly normalisation to avoid numerical errors will hide the problem. But then again, you may not.

Actually, those are in-game bones animating while running. But that's all I needed to hear. Thanks [smile]
A really obvious example would be

Q1 = (1, 0, 0, 0)
Q2 = (-1, 0, 0, 0)

Both have unit length

Add them together

Q3 = 0.5*(1, 0, 0, 0) + 0.5(-1, 0, 0, 0)
= (0, 0, 0, 0)

Which isnt unit length by any stretch of the imagination.

This topic is closed to new replies.

Advertisement