Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/164.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何从QTransform提取旋转角度?_C++_Qt_Math_Transform - Fatal编程技术网

C++ 如何从QTransform提取旋转角度?

C++ 如何从QTransform提取旋转角度?,c++,qt,math,transform,C++,Qt,Math,Transform,我有一个QTransform对象,希望知道该对象旋转的角度(以度为单位),但没有明确的示例说明如何执行此操作: 设置它很容易,但重新获取它却很难。最简单的一般方法是变换(0,0)和(1,0),然后使用三角函数(arctan)来获取角度假设变换仅包含旋转,这很容易:只需取m11元素的ACO即可 如果变换包含平移,它仍然有效,但是如果它包含剪切或缩放,那么你就倒霉了。这些可以通过将矩阵分解为剪切、缩放和旋转矩阵来重建,但得到的结果不太可能是您想要的结果。变换矩阵是用于三维图形的实现。它简化了数学运

我有一个QTransform对象,希望知道该对象旋转的角度(以度为单位),但没有明确的示例说明如何执行此操作:


设置它很容易,但重新获取它却很难。

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

假设变换仅包含旋转,这很容易:只需取m11元素的ACO即可


如果变换包含平移,它仍然有效,但是如果它包含剪切或缩放,那么你就倒霉了。这些可以通过将矩阵分解为剪切、缩放和旋转矩阵来重建,但得到的结果不太可能是您想要的结果。

变换矩阵是用于三维图形的实现。它简化了数学运算,以加快点/对象的三维位置/旋转方向。从变换中提取方向确实非常困难,因为它累积连续平移/旋转/缩放的方式

这里有一个建议。取一个指向简单方向(如(1,0,0))的向量,然后对其应用变换。结果向量将被平移和旋转,得到如下结果:(27.8,19.2,77.4)。将变换应用于(0,0,0),得到类似(26.1,19.4,50.8)的结果。可以使用这两个点计算已应用的旋转,前提是知道它们的起点(1,0,0)


这有帮助吗?

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

在添加旋转组功能之前,我只使用了QGraphicsItem和setRotate,没有任何问题。问题是,当调用destroyItemGroup时,它将旋转作为对项的转换而不是旋转应用。因此,我必须从这个QTransform对象恢复旋转

我的解决方案是在itemChange方法中添加以下行(归功于tom10的回答):

QVariant MyGraphicItem::itemChange(GraphicsItemChange更改,常量QVariant&value)
{
if(change==ItemTransformChange)
{
自动转换=value.value();
setRotation(rotation()+qRadiansToDegrees(qAtan2(transform.m12(),transform.m11()));
返回QVariant();
}
...
}

注:另一个使用acos和m11()的解决方案不起作用。正如tom10解释的那样,对于某些值,它会崩溃。

+1用于技术准确性。非平移部分的SVD分解(旋转合成、沿x-y轴的各向异性缩放和旋转))QTransform使用3x3矩阵执行2D变换。具有4x4矩阵的3D变换非常相似,但2D情况下的数学计算稍微简单一些。这就是说,除了Nils之外,所有人似乎都忘记了剪切变换,比如[[1,1,0],[0,1,0],[0,0,1]],在这种情况下,仅仅推两个点不会返回足够的描述性结果。
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();
    }
    ...
}