Advertisement

rotation matrix slerp

Started by June 11, 2015 03:26 PM
3 comments, last by JohnnyCode 9 years, 8 months ago

Hi, I have sort of a trouble.

I tried to implement slerp of rotation matricies (3x3), by slerping their coresponding base vectors (columns) individualy. The things is, that it does not work- it is messed up. To ease the analyzation, I post the short lerp code that works as expected, and then the entire slerp code that exactly replaces the very posted lerp code and provides the messed up result.

lerp code, all works


targetmats[i+0]=fwinv*prevframematsF[ i+0]+fweight*nextframematsF[ i+0];
targetmats[i+1]=fwinv*prevframematsF[ i+1]+fweight*nextframematsF[ i+1];
targetmats[i+2]=fwinv*prevframematsF[ i+2]+fweight*nextframematsF[ i+2];
targetmats[i+3]=prevframematsF[ i+3]+fweight*(nextframematsF[ i+3]-prevframematsF[ i+3]);
targetmats[i+4]=fwinv*prevframematsF[ i+4]+fweight*nextframematsF[ i+4];
targetmats[i+5]=fwinv*prevframematsF[ i+5]+fweight*nextframematsF[ i+5];
targetmats[i+6]=fwinv*prevframematsF[ i+6]+fweight*nextframematsF[ i+6];
targetmats[i+7]=prevframematsF[ i+7]+fweight*(nextframematsF[ i+7]-prevframematsF[ i+7]);
targetmats[i+8]=fwinv*prevframematsF[ i+8]+fweight*nextframematsF[ i+8];
targetmats[i+9]=fwinv*prevframematsF[ i+9]+fweight*nextframematsF[ i+9];
targetmats[i+10]=fwinv*prevframematsF[ i+10]+fweight*nextframematsF[ i+10];
targetmats[i+11]=prevframematsF[ i+11]+fweight*(nextframematsF[ i+11]-prevframematsF[ i+11]);

and if I replace the upper with the following code, it gets corrupted


float dotXs=(prevframematsF[ i+0]*nextframematsF[ i+0]);
dotXs+=(prevframematsF[ i+4]*nextframematsF[ i+4]);
dotXs+=(prevframematsF[ i+8]*nextframematsF[ i+8]);

float dotYs=(prevframematsF[ i+1]*nextframematsF[ i+1]);
dotYs+=(prevframematsF[ i+5]*nextframematsF[ i+5]);
dotYs+=(prevframematsF[ i+9]*nextframematsF[ i+9]);

float dotZs=(prevframematsF[ i+2]*nextframematsF[ i+2]);
dotZs+=(prevframematsF[ i+6]*nextframematsF[ i+6]);
dotZs+=(prevframematsF[ i+10]*nextframematsF[ i+10]);

if (dotXs>1.0f)
dotXs=1.0f;
if (dotYs>1.0f)
dotYs=1.0f;
if (dotZs>1.0f)
dotZs=1.0f;

float asinX=Math.acos(dotXs);
float asinY=Math.acos(dotYs);
float asinZ=Math.acos(dotZs);


float prevscalarX=Math.cos(asinX*fweight);
float nextscalarX=Math.sin(asinX*fweight);
float prevscalarY=Math.cos(asinY*fweight);
float nextscalarY=Math.sin(asinY*fweight);
float prevscalarZ=Math.cos(asinZ*fweight);
float nextscalarZ=Math.sin(asinZ*fweight);


float oXx=nextframematsF[ i+0]-dotXs*prevframematsF[ i+0];
float oXy=nextframematsF[ i+4]-dotXs*prevframematsF[ i+4];
float oXz=nextframematsF[ i+8]-dotXs*prevframematsF[ i+8];
float olnX=Math.sqrt(oXx*oXx+oXy*oXy+oXz*oXz);

if (olnX<=0.00001f)
{olnX=0.0f;}
else
olnX=1.0f/olnX;

float oYx=nextframematsF[ i+1]-dotYs*prevframematsF[ i+1];
float oYy=nextframematsF[ i+5]-dotYs*prevframematsF[ i+5];
float oYz=nextframematsF[ i+9]-dotYs*prevframematsF[ i+9];
float olnY=Math.sqrt(oYx*oYx+oYy*oYy+oYz*oYz);
if (olnY<=0.00001f)
{olnY=0.0f;}
else
olnY=1.0f/olnY;

float oZx=nextframematsF[ i+2]-dotZs*prevframematsF[ i+2];
float oZy=nextframematsF[ i+6]-dotZs*prevframematsF[ i+6];
float oZz=nextframematsF[ i+10]-dotZs*prevframematsF[ i+10];
float olnZ=Math.sqrt(oZx*oZx+oZy*oZy+oZz*oZz);
if (olnZ<=0.00001f)
{olnZ=0.0f;}
else
olnZ=1.0f/olnZ;



targetmats[i+0]=prevscalarX*prevframematsF[ i+0]+nextscalarX*olnX*oXx;
targetmats[i+1]=prevscalarY*prevframematsF[ i+1]+nextscalarY*olnY*oYx;
targetmats[i+2]=prevscalarZ*prevframematsF[ i+2]+nextscalarZ*olnZ*oZx;
targetmats[i+3]=prevframematsF[ i+3]+fweight*(nextframematsF[ i+3]-prevframematsF[ i+3]);
targetmats[i+4]=prevscalarX*prevframematsF[ i+4]+nextscalarX*olnX*oXy;
targetmats[i+5]=prevscalarY*prevframematsF[ i+5]+nextscalarY*olnY*oYy;
targetmats[i+6]=prevscalarZ*prevframematsF[ i+6]+nextscalarZ*olnZ*oZy;
targetmats[i+7]=prevframematsF[ i+7]+fweight*(nextframematsF[ i+7]-prevframematsF[ i+7]);
targetmats[i+8]=prevscalarX*prevframematsF[ i+8]+nextscalarX*olnX*oXz;
targetmats[i+9]=prevscalarY*prevframematsF[ i+9]+nextscalarY*olnY*oYz;
targetmats[i+10]=prevscalarZ*prevframematsF[ i+10]+nextscalarZ*olnZ*oZz;
targetmats[i+11]=prevframematsF[ i+11]+fweight*(nextframematsF[ i+11]-prevframematsF[ i+11]);

The matricies are thus correctly addressed, but there is this thing that I am not sure about wheather it couses this, those matricies are object space matricies but are all post multipled by following matrix

[-1,0,0,0]

[0,1,0,0]

[0,0,1,0]

[0,0,0,1]

could it couse any trouble when decompositing the 3x3 rotation ?

There is no reason why the intermediate matrices should be orthogonal, and in general they will not be. I recommend using quaternions if you need to interpolate between rotations.
Advertisement

There is no reason why the intermediate matrices should be orthogonal, and in general they will not be. I recommend using quaternions if you need to interpolate between rotations.


so do I understand corectly that if I slerp base vectors individualy, they will not keep their orthogonality?

Yes. Imagine three points on a sphere such that any pair determines an angle of 90 degrees from the center of the sphere (e.g., the North pole and two points on the equator at longitudes 0 and 90 degrees). Call them A, B and C. Now imagine gradually moving A towards B, B towards C and C towards A. At the end of the transition, we are back to a situation where they are orthogonal. But halfway through the operation, the three points are closer together than is required.

Does that mental picture help you?

Yes. Imagine three points on a sphere such that any pair determines an angle of 90 degrees from the center of the sphere (e.g., the North pole and two points on the equator at longitudes 0 and 90 degrees). Call them A, B and C. Now imagine gradually moving A towards B, B towards C and C towards A. At the end of the transition, we are back to a situation where they are orthogonal. But halfway through the operation, the three points are closer together than is required.

Does that mental picture help you?


great example, I could not imagine it physicaly at all.

This topic is closed to new replies.

Advertisement