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