Hi again,
I realized why we were having problem in our code.
We're building a matrix, then extracting the scale through extractScaling() and
the rotation
through extractEulerXYZ().
Doing so is incorrect, as you apparently need to remove the scaling and shear
before calling extractEulerXYZ(),
even though the first operation that extractEulerXYZ is doing is "removing the
scale". All it does is normalizing
the rows, so any negative scale is left.
I'm sure it's not a bug, but I actually expected extractEulerXYZ() to produce
the same result as extractSHRT().
Benoit
--
int main(int argc, char **argv)
{
Imath::M44f m;
Imath::V3f vec;
for (int i=0;i<4;++i)
for (int j=0;j<4;++j)
{
m.x[i][j] = 0;
}
m.x[3][3] = 1;
m.x[0][0] = -1; m.x[1][1] = 2; m.x[2][2] = 3;
Imath::V3f s, h, r, t;
if (extractSHRT(m,s,h,r,t))
std::cout <<"extracted SHRT:" <<std::endl << s << std::endl << h << std::endl << r
<< std::endl << t << std::endl << std::endl;
Imath::V3f rotVec;
Imath::extractEulerXYZ(m,rotVec);
std::cout <<"rotation XYZ without removing scale before" << std::endl << rotVec
<< std::endl << std::endl;;
Imath::M44f m2 = m;
if (! extractAndRemoveScalingAndShear(m2, s, h))
std::cout <<"error" <<std::endl;
Imath::extractEulerXYZ(m2,rotVec);
std::cout <<"rotation XYZ" << std::endl << rotVec << std::endl <<
std::endl;
return 0;
}
extracted SHRT:
(-1 -2 -3)
(0 0 0)
(-3.14159 -0 -0)
(0 0 0)
rotation XYZ without removing scale before
(0 -0 -0)
rotation XYZ
(-3.14159 -0 -0)
Benoit Leveau wrote:
Hi Florian,
Yes, this makes sense. Thanks for the detailed answer!
Cheers,
Benoit
Florian Kainz wrote:
Hi Benoit,
extracting scaling and rotation from a matrix is ambiguous:
a rotation by 180 degrees around one axis is equivalent to
scaling by -1 in the other two axes. The matrix contains
no information about whether you meant to express rotation
or scaling when you assembled your matrix.
The Imath functions that extract scaling and rotation are
written such that you get what you'd expect when your
matrix has been assembled from rotations and all-positive
scale operations. When negative scaling is involved, there
is no single right answer; the result you get from Imath
will be a correct representation of the original matrix,
but it may not be what you expect.
For consistency, Imath::extractScaling() will return the
same scale factors as Imath::extractSHRT(). In your example,
M44f m (-1, 0, 0, 0,
0, 2, 0, 0,
0, 0, 3, 0,
0, 0, 0, 1);
Imath::extractSHRT (m, scale, shear, rotation, translation)
produces
scale = ( -1, -2, -3)
shear = ( 0, 0, 0)
rotation = (-pi, 0, 0)
translation = ( 0, 0, 0)
The 180-degree rotation around x compensates for negative y
and z scale factors.
Hope this helps,
Florian
Benoit Leveau wrote:
Hi,
I'm probably doing something wrong, but it looks like if you have a
negative scaling in your matrix the extractScaling function (and
other functions like removeScaling that use it)
doesn't work properly.
I just tried the following very simple example, and got the same
incorrect result using OpenEXR 1.4 or 1.7.
Thanks for your help,
Benoit
----------------
#include <OpenEXR/ImathMatrixAlgo.h>
#include <iostream>
int main(int argc, char **argv)
{
Imath::M44f m;
Imath::V3f vec;
for (int i=0;i<4;++i)
for (int j=0;j<4;++j)
{
m.x[i][j] = 0;
}
m.x[3][3] = 1;
m.x[0][0] = 1; m.x[1][1] = 2; m.x[2][2] = 3;
std::cout <<"matrix = " << std::endl << m << std::endl;
if (extractScaling(m,vec,true))
std::cout <<"extracted scaling:" <<std::endl << vec <<
std::endl;
m.x[0][0] = -1; m.x[1][1] = 2; m.x[2][2] = 3;
std::cout <<"matrix = " << std::endl << m << std::endl;
if (extractScaling(m,vec,true))
std::cout <<"extracted scaling:" <<std::endl << vec <<
std::endl;
return 0;
}
----------------
Output:
-------
matrix = ( 1.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00
0.000000e+00 2.000000e+00 0.000000e+00 0.000000e+00
0.000000e+00 0.000000e+00 3.000000e+00 0.000000e+00
0.000000e+00 0.000000e+00 0.000000e+00 1.000000e+00)
extracted scaling:
(1 2 3)
matrix = ( -1.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00
0.000000e+00 2.000000e+00 0.000000e+00 0.000000e+00
0.000000e+00 0.000000e+00 3.000000e+00 0.000000e+00
0.000000e+00 0.000000e+00 0.000000e+00 1.000000e+00)
extracted scaling:
(-1 -2 -3)
_______________________________________________
Openexr-devel mailing list
Openexr-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/openexr-devel
_______________________________________________
Openexr-devel mailing list
Openexr-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/openexr-devel
_______________________________________________
Openexr-devel mailing list
Openexr-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/openexr-devel