Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.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
Algorithm 旋转矩阵的特征重正交化_Algorithm_Math_Rotation_Eigen_Rotational Matrices - Fatal编程技术网

Algorithm 旋转矩阵的特征重正交化

Algorithm 旋转矩阵的特征重正交化,algorithm,math,rotation,eigen,rotational-matrices,Algorithm,Math,Rotation,Eigen,Rotational Matrices,在乘以大量旋转矩阵后,由于舍入问题(非正交化),最终结果可能不再是有效的旋转矩阵 重新正交化的一种方法是遵循以下步骤: 将旋转矩阵转换为轴角度表示形式() 将轴角度转换回旋转矩阵() 图书馆里有没有什么东西通过隐藏所有细节来做同样的事情?还是有更好的食谱 由于特殊的奇点情况,此过程必须小心处理,因此如果Eigen提供了一个更好的工具,这将是非常好的。我不使用Eigen,也没有费心查找API,但这里有一个简单、计算廉价且稳定的过程来重新正交旋转矩阵。此正交化过程取自 威廉·普莱梅兰尼和保罗·比扎德

在乘以大量旋转矩阵后,由于舍入问题(非正交化),最终结果可能不再是有效的旋转矩阵

重新正交化的一种方法是遵循以下步骤:

  • 将旋转矩阵转换为轴角度表示形式()
  • 将轴角度转换回旋转矩阵()
  • 图书馆里有没有什么东西通过隐藏所有细节来做同样的事情?还是有更好的食谱


    由于特殊的奇点情况,此过程必须小心处理,因此如果Eigen提供了一个更好的工具,这将是非常好的。

    我不使用Eigen,也没有费心查找API,但这里有一个简单、计算廉价且稳定的过程来重新正交旋转矩阵。此正交化过程取自 威廉·普莱梅兰尼和保罗·比扎德;方程19-21

    x
    y
    z
    为(稍微混乱的)旋转矩阵的行向量。设
    error=dot(x,y)
    其中
    dot()
    是点积。如果矩阵是正交的,
    x
    y
    的点积,即
    误差
    为零

    错误
    平均分布在
    x
    y
    上:
    x_-ort=x-(错误/2)*y
    y_-ort=y-(错误/2)*x
    。第三行
    z_-ort=cross(x_-ort,y_-ort)
    ,根据定义,它与
    x_-ort
    y_-ort
    正交

    现在,您仍然需要规范化
    x_-ort
    y_-ort
    z_-ort
    ,因为这些向量应该是单位向量

    x_new = 0.5*(3-dot(x_ort,x_ort))*x_ort
    y_new = 0.5*(3-dot(y_ort,y_ort))*y_ort
    z_new = 0.5*(3-dot(z_ort,z_ort))*z_ort
    
    就这些,我们都做了


    使用Eigen提供的API应该很容易实现这一点。你可以很容易地想出其他的拼音程序,但我不认为这会在实践中产生明显的不同。我在我的运动跟踪应用程序中使用了上述程序,它工作得非常好;它既稳定又快速。

    您可以使用QR分解系统地重新正交化,用Q因子替换原始矩阵。在库例程中,如有必要,您必须通过对Q中的相应列求反来检查和更正R的对角线项是否为正(如果原始矩阵接近正交,则接近1)

    最接近给定矩阵的旋转矩阵Q由极分解或QP分解获得,其中p是半正定对称矩阵。QP分解可以迭代计算,也可以使用SVD计算。如果后者具有因子分解USV',则Q=UV.

    同时:

    #include <Eigen/Geometry>
    
    Eigen::Matrix3d mmm;
    Eigen::Matrix3d rrr;
                    rrr <<  0.882966, -0.321461,  0.342102,
                            0.431433,  0.842929, -0.321461,
                           -0.185031,  0.431433,  0.882966;
                         // replace this with any rotation matrix
    
    mmm = rrr;
    
    Eigen::AngleAxisd aa(rrr);    // RotationMatrix to AxisAngle
    rrr = aa.toRotationMatrix();  // AxisAngle      to RotationMatrix
    
    std::cout <<     mmm << std::endl << std::endl;
    std::cout << rrr     << std::endl << std::endl;
    std::cout << rrr-mmm << std::endl << std::endl;
    
    #包括
    本征::矩阵3d-mmm;
    本征::矩阵3D rrr;
    rrr应该非常稳健。引用参考文献:

    设M=U∑V为M的奇异值分解,则R=UV


    对于矩阵,∑中的奇异值应该非常接近1。矩阵R保证为,这是旋转矩阵的定义性质。如果在计算原始旋转矩阵时没有任何舍入错误,那么R将与M完全相同,在数值精度范围内。

    另一种方法是使用
    特征::四元数来表示旋转。这更容易规范化,而且
    rotation*rotation
    产品通常更快。如果你有很多旋转*向量的乘积(使用相同的矩阵),你应该将四元数局部转换成3x3矩阵。

    “感谢迄今为止的答案!”在Stackoverflow,我们不说谢谢,而是向上投票和/或接受答案。“一个人怎么能确定他处理了所有的奇点呢?”我猜它假设
    rrr
    实际上是一个旋转矩阵。如果它不是(这就是你的问题所在,你的旋转矩阵被弄乱了),那么它很可能是做错了什么。这种方法似乎更像是一种特殊的破解,而不是一种解决方案。实际上不需要计算角度,只需将轴旋转矩阵相乘即可,而无需担心象限和奇点。这是使用Givens旋转方法进行的QR分解。如果您想改进A=QR分解,请检查R的非对角部分是否小,并使用Q*(I+(R-R')/2)作为更好的近似值。如果(R-I)稍大,则使用更好的近似值I+(R-R')/2+(R-R')^2/8或精确值来计算(R-R')/2的矩阵指数。(R'=R的转置,首先从矩阵中识别k,然后应用公式。)If肯定会给出比我的答案中的过程更好的结果,但代价是计算成本明显更高。是的,应该做最简单的事情。这个问题没有给出一个维度,所以它可能是3D的,就像你的答案一样,或者是其他的东西。[[Easy in 3D也是使用Givens旋转的QR分解(恰好使用旋转矩阵的Euler角表示)。编辑:我看到问题中提到了这一点,所以是3D。]]无论如何,至少我对你的答案投了赞成票。:)(虽然OP在我看来应该已经这样做了。)Hi Lutzl,在Eigen:
    rotation.householderQr().householderQ()中进行QR分解并获得Q矩阵很容易。不过,我不太熟悉户主的方法。这够好吗?另外,请您在回答中详细说明“检查并更正”和“否定相应列”作为额外步骤?任何参考资料或代码示例都会很好!通过将QR分解应用于单位矩阵
    I
    进行测试。结果可能是
    [Q,R]=[-I,-I]
    。这是因为Householder反射被选择为最稳定的,即避免被零或接近零分割。应该注意的是,这里的标准化过程使用泰勒展开来近似向量大小。如果高精度