Sunday, 5 May 2019

Weighted Average of Quaternions Without Flipping?


























If you look around the Internet for the best mechanism to create an average quaternion, and particularly a weighted average of multiple quaternions you will almost always end up at this pdf from NASA.

A simpler way of averaging quaternions is possibly just to sequentially lerp or slerp between pairs of quaternions and adjust the weights at each step but this may or may not be accurate depending on the order in which you select the pairs. There's some debate on the best way to do this.

An additional problem with simply lerping quaternions is that they have a “double-cover” property, where there are two different quaternions (negatives of each other) that represent the same 3D rotation.  Normal lerp between them is dependent on which of those 'doubles' the quaternion actually is - you can go the long way round or the short way round. Looking at the orientation in the viewport you have no idea which one is being used. If, say, you have two similar quaternions but one is using something close to the negative of the other you can get very fast rotations around 180 degrees which look like flips. Slerp solves this problem but only between pairs (as well as providing a constant velocity as the interpolant increases which normal lerp doesn't).

When you use primuv to interpolate quaternions across a polygon in Houdini, that interpolation is a simple lerp between the numbers in the quaternions - you cannot guarantee that the blend will take the shortest arc (in which case you'll get strange intermediate rotations).

I found some Python code for implementing the NASA paper and made a scene to compare and contrast the different types of interpolation. The NASA results do look way better than naive primuv-style lerp. But, since it's python/numpy it's not that fast.

File is here.

No comments:

Post a comment