[Top][All Lists]
[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]);
}