旋转矩阵转四元数原理及C++ Code

原理如下:

R = ( R 00 R 01 R 02 R 10 R 11 R 12 R 20 R 21 R 22 ) R = \left(\begin{matrix} R00 & R01 & R02\\ R10 & R11 & R12\\ R20 & R21 & R22\\ \end{matrix}\right) R= R00R10R20R01R11R21R02R12R22

D i a g o n a l R = R 00 + R 11 + R 22 D i a g o n a l R 00 = R 00 − R 11 − R 22 D i a g o n a l R 11 = R 11 − R 00 − R 22 D i a g o n a l R 22 = R 22 − R 00 − R 11 DiagonalR = R00 + R11 +R22\\ DiagonalR00 = R00 - R11 - R22\\ DiagonalR11 = R11-R00-R22\\ DiagonalR22 = R22 - R00 - R11 DiagonalR=R00+R11+R22DiagonalR00=R00R11R22DiagonalR11=R11R00R22DiagonalR22=R22R00R11

分情况如下:

情况一
i f ( D i a g o n a l R 00 > = D i a g o n a l R 11 & & D i a g o n a l R 00 > = D i a g o n a l R 22 & & D i a g o n a l R 00 > = D i a g o n a l R ) q u a r t . x = D i a g o n a l R 00 + 1 2 q u a r t . y = R 10 + R 01 4.0 ∗ q u a r t . x q u a r t . z = R 20 + R 01 4.0 ∗ q u a r t . x q u a r t . w = R 21 − R 12 4.0 ∗ q u a r t . x if(DiagonalR00 >= DiagonalR11 \quad\&\& \quad DiagonalR00 >= DiagonalR22 \quad\&\& \quad DiagonalR00 >=DiagonalR)\\\\ \begin{aligned} &quart.x = \frac{\sqrt{DiagonalR00 + 1}}{2}\\ &quart.y = \frac{R10 + R01}{4.0*quart.x}\\ &quart.z = \frac{R20 + R01}{4.0*quart.x}\\ &quart.w = \frac{R21 - R12}{4.0*quart.x}\\ \end{aligned} if(DiagonalR00>=DiagonalR11&&DiagonalR00>=DiagonalR22&&DiagonalR00>=DiagonalR)quart.x=2DiagonalR00+1 quart.y=4.0quart.xR10+R01quart.z=4.0quart.xR20+R01quart.w=4.0quart.xR21R12

情况二:
i f ( D i a g o n a l R 00 < D i a g o n a l R 11 ∣ ∣ D i a g o n a l R 00 < D i a g o n a l R 22 ∣ ∣ D i a g o n a l R 00 < D i a g o n a l R ) i f ( D i a g o n a l R 11 > = D i a g o n a l R 00 & & D i a g o n a l R 11 > = D i a g o n a l R 22 & & D i a g o n a l R 11 > = D i a g o n a l R ) if(DiagonalR00 < DiagonalR11 \quad|| \quad DiagonalR00 < DiagonalR22 \quad|| \quad DiagonalR00 < DiagonalR)\\ if(DiagonalR11 >= DiagonalR00 \quad\&\& \quad DiagonalR11 >= DiagonalR22 \quad\&\& \quad DiagonalR11 >=DiagonalR) if(DiagonalR00<DiagonalR11∣∣DiagonalR00<DiagonalR22∣∣DiagonalR00<DiagonalR)if(DiagonalR11>=DiagonalR00&&DiagonalR11>=DiagonalR22&&DiagonalR11>=DiagonalR)

q u a r t . x = R 10 + R 01 4.0 ∗ q u a r t . y q u a r t . y = D i a g o n a l R 11 + 1 2 q u a r t . z = R 21 + R 12 4.0 ∗ q u a r t . y q u a r t . w = R 02 − R 20 4.0 ∗ q u a r t . y \begin{aligned} &quart.x = \frac{R10 + R01}{4.0*quart.y}\\ &quart.y = \frac{\sqrt{DiagonalR11 + 1}}{2}\\ &quart.z = \frac{R21 + R12}{4.0*quart.y}\\ &quart.w = \frac{R02 - R20}{4.0*quart.y}\\ \end{aligned} quart.x=4.0quart.yR10+R01quart.y=2DiagonalR11+1 quart.z=4.0quart.yR21+R12quart.w=4.0quart.yR02R20
情况三:
i f ( D i a g o n a l R 00 < D i a g o n a l R 11 ∣ ∣ D i a g o n a l R 00 < D i a g o n a l R 22 ∣ ∣ D i a g o n a l R 00 < D i a g o n a l R ) if(DiagonalR00 < DiagonalR11 \quad|| \quad DiagonalR00 < DiagonalR22 \quad|| \quad DiagonalR00 < DiagonalR) if(DiagonalR00<DiagonalR11∣∣DiagonalR00<DiagonalR22∣∣DiagonalR00<DiagonalR)

i f ( D i a g o n a l R 11 < D i a g o n a l R 00 ∣ ∣ D i a g o n a l R 11 < D i a g o n a l R 22 ∣ ∣ D i a g o n a l R 11 < D i a g o n a l R ) if(DiagonalR11 < DiagonalR00 \quad|| \quad DiagonalR11 < DiagonalR22 \quad|| \quad DiagonalR11 < DiagonalR) if(DiagonalR11<DiagonalR00∣∣DiagonalR11<DiagonalR22∣∣DiagonalR11<DiagonalR)

i f ( D i a g o n a l R 22 > D i a g o n a l R 00 & & D i a g o n a l R 22 > D i a g o n a l R 11 & & D i a g o n a l R 22 > D i a g o n a l R ) if(DiagonalR22 > DiagonalR00 \quad\&\& \quad DiagonalR22 > DiagonalR11 \quad\&\& \quad DiagonalR22 > DiagonalR) if(DiagonalR22>DiagonalR00&&DiagonalR22>DiagonalR11&&DiagonalR22>DiagonalR)

q u a r t . x = R 20 + R 02 4.0 ∗ q u a r t . z q u a r t . y = R 21 + R 12 4.0 ∗ q u a r t . z q u a r t . z = D i a g o n a l R 22 + 1 2 q u a r t . w = R 10 − R 01 4.0 ∗ q u a r t . z \begin{aligned} &quart.x = \frac{R20 + R02}{4.0*quart.z}\\ &quart.y = \frac{R21 + R12}{4.0*quart.z}\\ &quart.z = \frac{\sqrt{DiagonalR22 + 1}}{2}\\ &quart.w = \frac{R10 - R01}{4.0*quart.z}\\ \end{aligned} quart.x=4.0quart.zR20+R02quart.y=4.0quart.zR21+R12quart.z=2DiagonalR22+1 quart.w=4.0quart.zR10R01

情况四:
i f ( D i a g o n a l R 00 < D i a g o n a l R 11 ∣ ∣ D i a g o n a l R 00 < D i a g o n a l R 22 ∣ ∣ D i a g o n a l R 00 < D i a g o n a l R ) if(DiagonalR00 < DiagonalR11 \quad|| \quad DiagonalR00 < DiagonalR22\quad|| \quad DiagonalR00 < DiagonalR) if(DiagonalR00<DiagonalR11∣∣DiagonalR00<DiagonalR22∣∣DiagonalR00<DiagonalR)

i f ( D i a g o n a l R 11 < D i a g o n a l R 00 ∣ ∣ D i a g o n a l R 11 < D i a g o n a l R 22 ∣ ∣ D i a g o n a l R 11 < D i a g o n a l R ) if(DiagonalR11 < DiagonalR00 \quad|| \quad DiagonalR11 < DiagonalR22 \quad|| \quad DiagonalR11 < DiagonalR) if(DiagonalR11<DiagonalR00∣∣DiagonalR11<DiagonalR22∣∣DiagonalR11<DiagonalR)

i f ( D i a g o n a l R 22 < = D i a g o n a l R 00 ∣ ∣ D i a g o n a l R 22 < = D i a g o n a l R 11 ∣ ∣ D i a g o n a l R 22 < = D i a g o n a l R ) if(DiagonalR22 <= DiagonalR00 \quad|| \quad DiagonalR22 <= DiagonalR11 \quad|| \quad DiagonalR22 <= DiagonalR) if(DiagonalR22<=DiagonalR00∣∣DiagonalR22<=DiagonalR11∣∣DiagonalR22<=DiagonalR)

q u a r t . x = R 21 − R 12 4.0 ∗ q u a r t . w q u a r t . y = R 02 − R 20 4.0 ∗ q u a r t . w q u a r t . z = R 10 − R 01 4.0 ∗ q u a r t . w q u a r t . w = D i a g o n a l R + 1 2 \begin{aligned} &quart.x = \frac{R21 - R12}{4.0*quart.w}\\ &quart.y = \frac{R02 - R20}{4.0*quart.w}\\ &quart.z = \frac{R10 - R01}{4.0*quart.w}\\ &quart.w = \frac{\sqrt{DiagonalR + 1}}{2}\\ \end{aligned} quart.x=4.0quart.wR21R12quart.y=4.0quart.wR02R20quart.z=4.0quart.wR10R01quart.w=2DiagonalR+1

void RtoQuart(double* R, double* oQ)
{
    double R00 = R[0]; double R01 = R[1]; double R02 = R[2];
    double R10 = R[3]; double R11 = R[4]; double R12 = R[5];
    double R20 = R[6]; double R21 = R[7]; double R22 = R[8];


    double DiagonalR = R00 + R11 + R22;
    double DiagonalR00 = R00 + R00 - DiagonalR;
    double DiagonalR11 = R11 + R11 - DiagonalR;
    double DiagonalR22 = R22 + R22 - DiagonalR;

    double Quart[4] = { 0.0 };
    double Value;
    double Factor;
    if (DiagonalR00 < DiagonalR11 || DiagonalR00 < DiagonalR22 || DiagonalR00 < DiagonalR)
    {
        if (DiagonalR11 < DiagonalR00 || DiagonalR11 < DiagonalR22 || DiagonalR11 < DiagonalR)
        {
            if (DiagonalR22 <= DiagonalR00 || DiagonalR22 <= DiagonalR11 || DiagonalR22 <= DiagonalR)
            {

                Value = sqrt((DiagonalR + 1.0) * 0.25);
                Factor = 1.0 / (Value * 4.0);

                Quart[0] = (R21 - R12) * Factor;
                Quart[1] = (R02 - R20) * Factor;
                Quart[2] = (R10 - R01) * Factor;
                Quart[3] = Value;
            }
            else
            {
                Value = sqrt((DiagonalR22 + 1.0) * 0.25);
                Factor = 1.0 / (Value * 4.0);


                Quart[0] = (R20 + R02) * Factor;
                Quart[1] = (R21 + R12) * Factor;
                Quart[2] = Value;
                Quart[3] = (R10 - R01) * Factor;
            }
        }
        else
        {

            Value = sqrt((DiagonalR11 + 1.0) * 0.25);
            Factor = 1.0 / (Value * 4.0);
            Quart[0] = (R10 + R01) * Factor;
            Quart[1] = Value;
            Quart[2] = (R21 + R12) * Factor;
            Quart[3] = (R02 - R20)* Factor;
        }
    }
    else
    {
        Value = sqrt((DiagonalR00 + 1.0) * 0.25);
        Factor = 1.0 / (Value * 4.0);

        Quart[0] = Value;
        Quart[1] = (R10 + R01) * Factor;
        Quart[2] = (R20 + R02) * Factor;
        Quart[3] = (R21 - R12) * Factor;
    }

    double QLen = sqrt(Quart[0] * Quart[0] + Quart[1] * Quart[1] + Quart[2] * Quart[2] + Quart[3] * Quart[3]);

    Quart[0] = Quart[0] / QLen;
    Quart[1] = Quart[1] / QLen;
    Quart[2] = Quart[2] / QLen;
    Quart[3] = Quart[3] / QLen;

    if (Quart[3] < 0)
    {
        Quart[0] = -Quart[0];
        Quart[1] = -Quart[1];
        Quart[2] = -Quart[2];
        Quart[3] = -Quart[3];
    }

    oQ[0] = Quart[0];
    oQ[1] = Quart[1];
    oQ[2] = Quart[2];
    oQ[3] = Quart[3];
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值