matrix interpolation

Started by
3 comments, last by Marianne 17 years, 9 months ago
hi, i'm trying to do matrix interpolation, to have a 3D object smoothly pass from one location to another (only rotation matters here, i can do the translation myself) . All i have is two matrices and a delta. (I know an older topic already mentions this here, but i couldn't anything to work!) i have tried converting my matrices to quaternions, but the object starts moving in the wrong direction (?) i have tried converting to axis-angle, however it only works one way, e.g. clockwise is okay, counter-clockwise isn't (either going in the wrong way, or sometimes going the right way but much too slowly (?) ) i have also tried direclty interpolating each number inside the matrix. well it works but as i expected the object gets distorted in the process. so right now the one that seems to work best is axis-angle... how could i know in which way to rotate the angle then? thanks! (if you need to see a bit what i've tried, just ask i can post some pseudo code)
Advertisement
If quaternions are not working for you, it's likely that there's a problem with your quaternion-to-matrix or matrix-to-quaternion conversion code. For example, the functions may be inconsistent in their use of row or column vectors, which could cause the behavior you describe.

There are ways to perform the interpolation using matrices, but I'd stick with quaternions until you get it working (there's really no reason it shouldn't if properly implemented). If you're not sure where the error is, you might post your quat-mat conversion functions, and perhaps your slerp() function. It should be fairly easy to at least spot any basis vector orientation problems.
but i'd like to a know a way to do it with matr ices if possible because my whole program is based on matrices, so with Quaternions i need to convert my matrices to quats, interpolate them and then convert them back to a matrix. performance isn't crucial in my program but still it's awkward.

well i oduble-checked my conversion codes with the one presented on the website where i got them (i'm not yet fluent with thiese maths so i can probably let something slip very easily... i adapted code from http://www.euclideanspace.com/maths/)

personnaly i'd think the mistake would be in the matrix to quat code rather than in slerp

to avoid the nasty 2D arrays in C++ i just used a single dimension array in this order:

0 1 2
3 4 5
6 7 8

(i'm doing this mostly to learn so please excuse stupid mistakes!)

// ------------------------ Matrix to quat --------------------------    float trace = matrix->i[0] + matrix->i[4] + matrix->i[8] + 1.0f;/*--> here i'm not sure... the code on the website was'if (trace > M_EPSILON)' however i couldn't findM_EPSILON anywhere... the text along the code stated'if bigger than zero' so i just put zero.that might be the problem*/     if( trace > 0 ) {        float s = 0.5f / sqrtf(trace);        qw = 0.25f / s;        qx = ( matrix->i[5] - matrix->i[7] ) * s;        qy = ( matrix->i[6] - matrix->i[2] ) * s;        qz = ( matrix->i[1] - matrix->i[3] ) * s;    } else {        if ( matrix->i[0] > matrix->i[4] && matrix->i[0] > matrix->i[8] ) {            float s = 2.0f * sqrtf( 1.0f + matrix->i[0] - matrix->i[4] - matrix->i[8]);            qx = 0.25f * s;            qy = (matrix->i[3] + matrix->i[1] ) / s;            qz = (matrix->i[6] + matrix->i[2] ) / s;            qw = (matrix->i[7] - matrix->i[5] ) / s;        } else if (matrix->i[4] > matrix->i[8]) {            float s = 2.0f * sqrtf( 1.0f + matrix->i[4] - matrix->i[0] - matrix->i[8]);            qx = (matrix->i[3] + matrix->i[1] ) / s;            qy = 0.25f * s;            qz = (matrix->i[7] + matrix->i[5] ) / s;            qw = (matrix->i[6] - matrix->i[2] ) / s;        } else {            float s = 2.0f * sqrtf( 1.0f + matrix->i[8] - matrix->i[0] - matrix->i[4] );            qx = (matrix->i[6] + matrix->i[2] ) / s;            qy = (matrix->i[7] + matrix->i[5] ) / s;            qz = 0.25f * s;            qw = (matrix->i[3] - matrix->i[1] ) / s;        }    }    // ----------------------- Quat to matrix -----------------    Matrix* matrix=new Matrix();        matrix->i[0] = 1 - 2*_SQUARE(qy) - 2*_SQUARE(qz);    matrix->i[1] = 2*qx*qy - 2*qz*qw;    matrix->i[2] = 2*qx*qz + 2*qy*qw;    matrix->i[3] = 2*qx*qy + 2*qz*qw;    matrix->i[4] = 1 - 2*_SQUARE(qx) - 2*_SQUARE(qz);    matrix->i[5] = 2*qy*qz - 2*qx*qw;    matrix->i[6] = 2*qx*qz - 2*qy*qw;    matrix->i[7] = 2*qy*qz + 2*qx*qw;    matrix->i[8] = 1 - 2*_SQUARE(qx) - 2*_SQUARE(qy);        return matrix;// ---------------------- SLERP -----------------------Quat* slerp(Quat* qa, Quat* qb, double t) {    // quaternion to return    Quat* qm = new Quat();    // Calculate angle beteen them.    double costheta = qa->qw * qb->qw + qa->qx * qb->qx + qa->qy * qb->qy + qa->qz * qb->qz;    double theta = acos(costheta);    // if theta = 0 then return qa    if (abs(theta) < 0.01){        qm->qw = qa->qw;        qm->qx = qa->qx;        qm->qy = qa->qy;        qm->qz = qa->qz;        return qm;    }    // Calculate temporary values.    double sinTheta = sqrt(1.0 - costheta*costheta);    // if theta*2 = 180 degrees then result is undefined    if (abs(sinTheta) < 0.01){        qm->qw = (qa->qw * 0.5 + qb->qw * 0.5);        qm->qx = (qa->qx * 0.5 + qb->qx * 0.5);        qm->qy = (qa->qy * 0.5 + qb->qy * 0.5);        qm->qz = (qa->qz * 0.5 + qb->qz * 0.5);        return qm;    }    double ratioA = sin((1 - t) * theta) / sinTheta;    double ratioB = sin(t * theta) / sinTheta;        //calculate Quaternion.    qm->qw = (qa->qw * ratioA + qb->qw * ratioB);    qm->qx = (qa->qx * ratioA + qb->qx * ratioB);    qm->qy = (qa->qy * ratioA + qb->qy * ratioB);    qm->qz = (qa->qz * ratioA + qb->qz * ratioB);    return qm;}
Quote:Original post by Marianne
personnaly i'd think the mistake would be in the matrix to quat code rather than in slerp


Your matrix to quaternion code is producing the *conjugate* of what you want. It is producing (w,x,y,z) when your matrix convention requires (w,-x,-y,-z).

Any time you use someone's conversion code, you have to know their conventions and how they compare to yours. (1) Is matrix times vector R*V (V is 3x1) or V*R (V is 1x3)? (2) Does a positive angle correspond to counterclockwise rotation when an observer is looking in the negative direction of the rotation axis? (3) Are they using a coordinate system with a handedness different from yours?
it works!!! :D

many thanks, i didn't know i was so close to get it to work. next time i'll try to look carefully at the conventions, however the page i got my info at didn't mention them (or maybe i'm blind!)

This topic is closed to new replies.

Advertisement