MatrixToRotAxis() != RotAxisToMatrix()



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 25/11/2008 at 21:16, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   R10+ 
    Platform:   Windows  ;   
    Language(s) :     C++  ;

    ---------
    I'm trying to convert some local matrices (of null/bone/joint objects) into Angle/Axis pairs, but I'm having a problem of those Axis/Angle pairs not reproducing the original matrix...

        
        
          
        // --------- S N I P ---------
        
        
        
        
        Matrix ml1 = op->GetMln();  
        Vector pos = ml1.off;  
        Real angle;  
        Vector axis;
        
        
        
        
        MatrixDump(ml1, "Before"); // (debug print of matrix)
        
        
        
        
        // Convert Euler matrix to angle/axis  
        MatrixToRotAxis(ml1,&axis,&angle);
        
        
        
        
        // re-create matrix, using angle/axis  
        Matrix ml2 = RotAxisToMatrix(axis, angle);  
        ml2.off = ml1.off;
        
        
        
        MatrixDump(ml2, "After"); // (debug print of matrix)
        
        
        
        
        // --------- S N I P ---------  
        
    

    ...ml2 only ends up the same as ml1 if ml1 was an Identity Matrix.  Should I expect the above to reproduce the original Matrix? Or is it expected that the various matrix values get transposed in the new Matrix?
    As far as I can tell from some other code, the RotAxisToMatrix() part is working as expected, so the problem is happening with MatrixToRotAxis() , but I'm willing to listen to any help in accomplishing the desired results.
    Thanks,
    Keith



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 25/11/2008 at 21:35, xxxxxxxx wrote:

    Here's some helper routines in case you don't have something like this:

        
        
        #include <stdarg.h>
        
        #include <stdio.h>
        
          
        //-------------------------------------------------------------  
        // GePrintF()  
        //-------------------------------------------------------------  
        void GePrintF(const CHAR *format,...)  
        {  
        va_list arp;  
        CHAR buf[1024];
        
        
        
        
        va_start(arp,format);  
        vsprintf(buf,format,arp);  
        GePrint(buf);  
        va_end(arp);
        
        
        
        
        }
        
        
        
        
         
        
        
        
        
        //-------------------------------------------------------------  
        // MatrixDump()  
        //-------------------------------------------------------------  
        void MatrixDump(Matrix mx, char *name)  
        {  
        GePrintF("======%s=======", name);  
        GePrint("off.x = " + RealToString(mx.off.x) + " off.y = " + RealToString(mx.off.y) + " off.z = " + RealToString(mx.off.z) );  
        GePrint("v1.x = " + RealToString(mx.v1.x) + " v1.y = " + RealToString(mx.v1.y) + " v1.z = " + RealToString(mx.v1.z) );  
        GePrint("v2.x = " + RealToString(mx.v2.x) + " v2.y = " + RealToString(mx.v2.y) + " v2.z = " + RealToString(mx.v2.z) );  
        GePrint("v3.x = " + RealToString(mx.v3.x) + " v3.y = " + RealToString(mx.v3.y) + " v3.z = " + RealToString(mx.v3.z) );
        
        
        
        
        }  
        
    


  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 25/11/2008 at 21:48, xxxxxxxx wrote:

    Here's the transposing I was referring to...



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 25/11/2008 at 23:34, xxxxxxxx wrote:

    Erm... it looks like I stumbled across the answer...
    Here's the original MatrixToRotAxis() code from c4d_tools.cpp ...

        
        
          
        void MatrixToRotAxis(const Matrix &mm, Vector *v, Real *w)  
        {  
            Matrix m = mm;
        
        
        
        
            // MatrixVectoren MUESSEN normiert sein!!!  
            m.v1=!m.v1;  
            m.v2=!m.v2;  
            m.v3=!m.v3;
        
        
        
        
            // Winkel berechnen  
            *w = ACos((m.v1.x+m.v2.y+m.v3.z-1.0)/2.0);
        
        
        
        
            // Achse berechnen  
            v->x= m.v2.z-m.v3.y;  
            v->y= m.v3.x-m.v1.z;  
            v->z= m.v1.y-m.v2.x;  
            *v = !(*v);
        
        
        
        
            if (*v==0.0)  
            {  
                *v = Vector(0.0,1.0,0.0);  
                *w = 0.0;  
            }  
        }  
        
    

    ...switching (reversing) the order of subtraction when building the axis Vector fixes my problem...

        
        
          
        void MyMatrixToRotAxis(const Matrix &mm, Vector *v, Real *w)  
        {  
            Matrix m = mm;
        
        
        
        
            // MatrixVectoren MUESSEN normiert sein!!!  
            m.v1=!m.v1;  
            m.v2=!m.v2;  
            m.v3=!m.v3;
        
        
        
        
            // Winkel berechnen  
            *w = ACos((m.v1.x+m.v2.y+m.v3.z-1.0)/2.0);
        
        
        
        
            // NOTE: subtraction order reversed  
            // v->x= m.v2.z-m.v3.y;  
            // v->y= m.v3.x-m.v1.z;  
            // v->z= m.v1.y-m.v2.x;  
            v->x= m.v3.y-m.v2.z;  
            v->y= m.v1.z-m.v3.x;  
            v->z= m.v2.x-m.v1.y;  
            *v = !(*v);
        
        
        
        
            if (*v==0.0)  
            {  
                *v = Vector(0.0,1.0,0.0);  
                *w = 0.0;  
            }  
        }  
        
    

    ...I can now use RotAxisToMatrix() on the Angle/Axis generated by MyMatrixToRotAxis() to re-create the original Matrix.
    Would that count as a 'bug' in the original?
    Keith


Log in to reply