如何从QTransform中提取旋转角度?

11
5个回答

10
假设变换仅包含旋转,则很容易:只需对m11元素取acos即可。
如果变换包含平移,它仍然有效,但如果包含错切或缩放,则无法得到正确结果。可以通过将矩阵分解为错切、缩放和旋转矩阵来重建这些内容,但你得到的结果可能不是你想要的。

SVD分解非翻译部分也浮现在脑海中(旋转的组合,沿x-y轴的各向异性缩放和旋转)。 - Jason S

9
最简单的一般方法是将(0,0)和(1,0)进行变换,然后使用三角函数(arctan)获取角度。

4

变换矩阵是用于3D图形的实现,它简化了数学计算以加快点/物体的3D位置/旋转方向。由于变换累计了连续的平移/旋转/缩放,因此从变换中提取方向确实非常困难。

这里有一个建议。拿一个指向简单方向的向量,例如(1,0,0),然后将变换应用于它。您得到的结果向量将被平移和旋转,从而得到类似于(27.8, 19.2, 77.4)的东西。将变换应用于(0,0,0),得到类似于(26.1, 19.4, 50.8)的东西。您可以使用这两个点来计算应用的旋转,基于它们的起始点(1,0,0)。

这有帮助吗?


1
QTransform使用3x3矩阵执行2D变换。使用4x4矩阵进行3D变换非常相似,但在2D情况下的数学运算略微简单一些。话虽如此,除了Nils之外,似乎每个人都忘记了剪切变换,例如[[1,1,0],[0,1,0],[0,0,1]],在这种情况下,仅通过两个点将不会返回足够描述性的结果。 - ephemient

2

通常需要使用反三角函数,但需要注意象限的不确定性,这时候应该使用 atan2(有时拼写为 arctan2)。因此,要么将单位向量[0,1]旋转到[x,y],然后使用atan2(y,x),或者如果矩阵仅实现旋转,则可以使用 atan2(m12,m11)。(这些与Javier和Nils的答案类似,但它们不使用 atan2。)


2

我曾经使用QGraphicsItem的setRotate方法,没有遇到任何问题,直到我添加了旋转组功能。问题在于,当调用destroyItemGroup时,它将旋转应用为项目的变换,而不是旋转。因此,我必须从QTransform对象中恢复旋转。

我的解决方法是在itemChange方法中添加以下代码(感谢tom10的回答):

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();
    }
    ...
}

注:使用acos和m11()的另一种解决方案不起作用。根据Tom10的解释,它会在某些值下崩溃。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接