gnash-dev
[Top][All Lists]
Advanced

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

Re: [Gnash-dev] does _height work??


From: Eric Hughes
Subject: Re: [Gnash-dev] does _height work??
Date: Sat, 14 Apr 2007 09:11:26 -0600

[I wrote this up the other day, but the server ate my email. Twice. No, really. --EH]

At 10:09 AM 4/12/2007, strk wrote:
I'm not sure current implementation is fine nor I know if it makes
any sense to separate rotation and scaling when it comes to setting those
values in the matrix.

As implemented in matrix.cpp, the function set_scale_rotation() scales first and then rotates. Rotation and scaling are not commutative. There could be also, if you wanted it, another function set_rotation_scale(), that would rotate first and then scale.

        // WORKS
        m1.set_scale_rotation(1, 3, 0);
        check_equals(m1.get_x_scale(), 1);
        check_equals(m1.get_y_scale(), 3);
        check_equals(m1.get_rotation(), 0);

This works because the rotation operation is the identity (angle = 0).

        // WORKS
        m1.set_scale_rotation(1, 1, 2);
        check_equals(m1.get_x_scale(), 1);
        check_equals(m1.get_y_scale(), 1);
        check_equals(m1.get_rotation(), 2);

This works because the x and y scales are equal. The combination of these two is a dilation, and dilations and rotations do commute.

        // FAILS !
        m.set_scale_rotation(2, 1, 2);
        check_equals(m1.get_x_scale(), 2); // get 1.23269
        check_equals(m1.get_y_scale(), 1); // get 1.8656
        check_equals(m1.get_rotation(), 2)

So, first of all, should I expect the above to work ?

It depends, but probably yes. I've looked at the code, and it's not really well-documented what's supposed to happen. In the interpretation that seems to be the one actually intended, this function retrieves "canonical" parameters for the affine transformation that the matrix represents. (These matrices are shear-free, so three parameters suffice for the orthogonal group part.) By canonical, I mean the parameters of a canonical form that equals the matrix. The canonical form here is a product of three matrices:
        rotation * scale_y * scale_x
The order of the last two is indifferent. Matrices are applied right-to-left (like function composition), so this matches what I said up top. set_scale_rotation uses the canonical form above. get_x_scale, as implemented, seems like it might a reverse canonical form, where rotation and scale are swapped.

Under this interpretation, your test should have run and the implementations of get_x_scale and get_y_scale do not match that of set_scale_rotation. The next question is "what's desired"? Ultimately, the right answer is what Flash does, which means some testing.

What I'm guessing, though, is that scaling is applied first and then rotation. That's because typical cognition is "first define a shape, then position it". Scaling changes the shape, rotation doesn't. If this is right, set_scale_rotation is correct and get_x_scale is not.

Fixed code below, untested. You'll also have to fix matrix::get_max_scale right above.

Eric
==================================================
float
matrix::get_x_scale() const
{
        float   scale = sqrtf(m_[0][0] * m_[0][0] + m_[1][0] * m_[1][0]);

        // Are we turned inside out?
        if (get_determinant() < 0.f)
        {
                scale = -scale;
        }

        return scale;
}

float
matrix::get_y_scale() const
{
        return sqrtf(m_[1][1] * m_[1][1] + m_[0][1] * m_[0][1]);
}






reply via email to

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