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
address@hidden
http://lists.nongnu.org/mailman/listinfo/openexr-devel