Input: (Note that it is almost diagonal.)
Code: Select all
In btMatrix3x3::diagonalize(btMatrix3x3& rot, btScalar threshold, int maxSteps) :-
this =
{6.66666674e-05, 9.09494702e-13, 0.000000000, 0.000000000}
{-9.09494702e-13, 6.66666674e-05, 0.000000000, 0.000000000}
{0.000000000, 0.000000000, 6.66666674e-05, 0.000000000}
threshold = 0.00001
maxStep = 20
Code: Select all
rot become
{0.707106769, 0.707106769, 0.000000000, 0.000000000}
{-0.707106769, 0.707106769, 0.000000000, 0.000000000}
{0.000000000, 0.000000000, 1.00000000, 0.000000000}
Analysis
1. It run only 1 iteration :-
Code: Select all
btScalar t = threshold * (btFabs(m_el[0][0]) + btFabs(m_el[1][1]) + btFabs(m_el[2][2]));
if (max <= t) //<-- max = 9.09494702e-13 , t = 1.99999994e-09
{
if (max <= SIMD_EPSILON * t)
{
return;
}
step = 1; //<--- run pass this statement, I think it is correct to do so.
}
It should pass the second block #2 instead of #1 because the input is near diagonal.
Code: Select all
btScalar mpq = m_el[p][q]; //<--- mpq = 9.09494702e-13
btScalar theta = (m_el[q][q] - m_el[p][p]) / (2 * mpq); //<--- theta = 0.000000000
btScalar theta2 = theta * theta; //<--- theta2 = 0.000000000
btScalar cos;
btScalar sin;
if (theta2 * theta2 < btScalar(10 / SIMD_EPSILON)) //#1
{
t = (theta >= 0) ? 1 / (theta + btSqrt(1 + theta2))
: 1 / (theta - btSqrt(1 + theta2)); //<--- t = 1.00000000
cos = 1 / btSqrt(1 + t * t); //<---- cos = 0.707106769 wrong
sin = cos * t;
}else{ //#2
// approximation for large theta-value, i.e., a nearly diagonal matrix
.....
}
Edit: Thank, Erwin! (see the following reply)
If somebody want to debug, here is some useful link (example of c++ code, I didn't test):- http://stackoverflow.com/questions/4372 ... omposition