Jump to content
  • Advertisement
Sign in to follow this  
Jiia

No need to normalize this quaternion

This topic is 5026 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

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.

Share this post


Link to post
Share on other sites
Advertisement
I may have make a mistake in the following but...

a = (w,x,y,z) with ww+xx+yy+zz=1
b = (W,X,Y,Z) with WW+XX+YY+ZZ=1

c = 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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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.

Share this post


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

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!