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