Question

I have a QTransform object and would like to know the angle in degrees that the object is rotated by, however there is no clear example of how to do this:

http://doc.trolltech.com/4.4/qtransform.html#basic-matrix-operations

Setting it is easy, getting it back out again is hard.

Was it helpful?

Solution

Assuming, that the transform ONLY contains a rotation it's easy: Just take the acos of the m11 element.

It still works if the transform contains a translation, but if it contains shearing or scaling you're out of luck. These can be reconstructed by decomposing the matrix into a shear, scale and rotate matrix, but the results you get aren't most likely what you're looking for.

OTHER TIPS

The simplest general way is to transform (0,0) and (1,0), then use trigonometric functions (arctan) to get the angle

The Transformation Matrix is an implementation used for 3d graphics. It simplifies the math in order to speed up 3d positional / rotational orientations of points / objects. It is indeed very hard to pull out orientation from the Transformation because of the way it accumulates successive translations / rotations / scales.

Here's a suggestion. Take a vector that points in a simple direction like (1,0,0), and then apply the Transform to it. Your resulting vector will be translated and rotated to give you something like this: (27.8, 19.2, 77.4). Apply the Transform to (0,0,0), to get something like (26.1, 19.4, 50.8). You can use these two points to calculate the rotations that have been applied based on knowing their starting points of (1,0,0).

Does this help?

Generally you need an inverse trig function, but you need to watch out for quadrant ambiguities, and this is what you should use atan2 (sometimes spelled arctan2). So either rotate a unit vector [0, 1] to [x, y] and then use atan2(y,x), or if the matrix is only implementing a rotation you can use atan2(m12,m11). (These are similar to Javier and Nils answers, except they don't use atan2.)

I was using QGraphicsItem with just setRotate and wasn't having any kind of problem, until I add a rotate group functionality. The problem is that when destroyItemGroup is called, it applies the rotation as a transformation to the items, and not as a rotation. Because of that I had to recover the rotation from this QTransform object.

My fix was to add the following lines to the itemChange method (credit to tom10's answer):

QVariant MyGraphicItem::itemChange(GraphicsItemChange change, const QVariant &value)
{
    if(change == ItemTransformChange)
    {
        auto transform = value.value<QTransform>();
        setRotation(rotation() + qRadiansToDegrees(qAtan2(transform.m12(), transform.m11())));
        return QVariant();
    }
    ...
}

PS.: The other solution with acos and m11() didn't work. It crashes for certain values, as explained by tom10.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top