[Qt-interest] How to multiply a QTransform by float without affecting the scale?

Luiz Geovani Vier lgvier at gmail.com
Fri Jan 14 14:11:13 CET 2011


Thanks for the insights, K.

I ended up using a trick to get the angle:

QPointF pos1 = item->mapToScene(0, 0);
QPointF pos2 = item->mapToScene(1, 0);
float angle = MathUtils::angle(pos2 - pos1);

MathUtils::angle is
    if (x == 0.f) {
        if (y < 0.f) return 270.f; else return 90.f;
    } else if (y == 0.f) {
        if (x < 0.f) return 180.f; else return 0.f;
    }
    if (y > 0.f)
        if (x > 0.f)
            return atan(y / x) * RAD_TO_DEG;
        else
            return 180.f - atan(y / -x) * RAD_TO_DEG;
    else if (x > 0.f)
        return 360.f - atan(-y / x) * RAD_TO_DEG;
    else
        return 180.f + atan(-y / -x) * RAD_TO_DEG;

Cheers,
-Geovani

On Wed, Jan 12, 2011 at 3:07 AM, K. Frank <kfrank29.c at gmail.com> wrote:

> Hi Geovani!
>
> On Tue, Jan 11, 2011 at 10:02 PM, Luiz Geovani Vier <lgvier at gmail.com>
> wrote:
> > Hello all,
> > So I have a QTransform containing rotation and translation.
> > I'd like to animate a transformation by multiplying the old matrix by 1.0
> -
> > [0..1] and new matrix by [0..1]. (btw, Is there a better way to do that?)
> > However, when I multiply QTransform by a float, that also affects the
> > scaling (e.g. * 0.1 = very tiny item :-)
> > How should I be handling this so that only rotation and translation is
> > applied?
>
> The problem, as you've found out, is that if R1 and R2 are rotations
> (more precisely, rotation matrices), then the interpolated matrix,
> R = (1 - alpha) R1  +  alpha R2 is not a rotation.
>
> What you need to do instead is interpolate the angles by which
> you are rotating.
>
> (However, interpolating translations, v = (1 - alpha) v1  +  alpha v2,
> where v1 and v2 are translation vectors, is perfectly fine, and gives
> you what you want.)
>
> If the QTransform matrix consists of only a rotation and translation,
> then it will be of a special form, and the { {m11, m12}, {m21, m22} }
> piece of the matrix will be of the form
>
>    { { cos (theta), sin (theta) }, { -sin (theta), cos (theta) } }
>
> where theta is the angle by which you are rotating.
>
> Given an angle theta, Qt lets you create a QTransform representing
> a rotation by that angle (using the QTransform::rotate() member
> function), but does not appear to let you extract the rotation angle
> from a given QTransform.
>
> You have to extract the angle by hand.  Assuming that the QTransform
> is a pure rotation plus translation, then the rotation angle is
>
>   theta  =  arctan (m12 / m11)   (for m11 > 0)
>   theta  =  arctan (m12 / m11)  +  180 deg.   (for m11 < 0)
>
> (Arctan is the inverse tangent function.)
>
> So, if you want to interpolate between two QTransforms, T1 and T2,
> that are both a rotation plus a translation, you need to extract the
> two rotation angles, theta1 and theta2, as above, and the two translation
> vectors, v1 = (T1.m31(), T1.m32()) and v2 = (T2.m31(), T2.m32).
>
> Then interpolate the angles
>
>   theta  =  (1 - alpha) theta1  +  alpha theta2
>
> interpolate the translations
>
>   v  =  (v_x, v_y)  = (1 - alpha) v1  +  alpha v2
>
> and construct a QTransform from the interpolated values, e.g.,
>
>   QTransform().rotate (theta).translate (v_x, v_y)
>
> Given which functions are (and are not) provided by Qt, I think that
> this is the most straightforward way to do the interpolations for the
> animation you want.
>
> > Thanks,
> > -Geovani
>
> Good luck.
>
>
> K. Frank
> _______________________________________________
> Qt-interest mailing list
> Qt-interest at qt.nokia.com
> http://lists.qt.nokia.com/mailman/listinfo/qt-interest
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20110114/8f82838a/attachment.html 


More information about the Qt-interest-old mailing list