openexr-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Openexr-devel] extractScaling from matrices doesn't work with negat


From: Benoit Leveau
Subject: Re: [Openexr-devel] extractScaling from matrices doesn't work with negative scales?
Date: Thu, 11 Nov 2010 15:29:04 +0000
User-agent: Thunderbird 2.0.0.12 (X11/20080213)

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




_______________________________________________
Openexr-devel mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/openexr-devel





reply via email to

[Prev in Thread] Current Thread [Next in Thread]