首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在旋转矩阵之间进行插值

在旋转矩阵之间进行插值
EN

Stack Overflow用户
提问于 2010-11-05 01:24:18
回答 2查看 15.5K关注 0票数 13

我有两个旋转矩阵来描述任意旋转。(兼容4x4 opengl )

现在我想在它们之间进行插值,以便它沿着从一个旋转到另一个旋转的径向路径。想象一下,三脚架上的相机朝一边看,然后旋转。

如果我插值每个分量,我会得到一个压缩结果,所以我认为我只需要插值矩阵的某些分量。但是是哪几个呢?

EN

回答 2

Stack Overflow用户

发布于 2010-11-05 01:29:46

对于矩阵的旋转部分,您必须使用SLERP,对于其他部分,您必须使用线性。最好的方法是将矩阵转换为四元数,并使用(更简单的)四元数SLERP:http://en.wikipedia.org/wiki/Slerp

我建议阅读Gems II或III,特别是关于将矩阵分解为更简单的变换的部分。以下是Spencer W. Thomas在本章中的来源:

http://tog.acm.org/resources/GraphicsGems/gemsii/unmatrix.c

当然,我建议您自己学习如何做到这一点。这真的不是很难,只是有很多烦人的代数。最后,这里有一篇关于如何通过Id软件将矩阵转换为四元数并将其转换回来的优秀论文:http://www.mrelusive.com/publications/papers/SIMD-From-Quaternion-to-Matrix-and-Back.pdf

编辑:这是几乎每个人都引用的公式,它来自1985年的一篇SIGGRAPH论文。

哪里

代码语言:javascript
复制
- qm = interpolated quaternion
- qa = quaternion a (first quaternion to be interpolated between)
- qb = quaternion b (second quaternion to be interpolated between)
- t = a scalar between 0.0 (at qa) and 1.0 (at qb)
- θ is half the angle between qa and qb

代码:

代码语言:javascript
复制
quat slerp(quat qa, quat qb, double t) {
    // quaternion to return
    quat qm = new quat();
    // Calculate angle between them.
    double cosHalfTheta = qa.w * qb.w + qa.x * qb.x + qa.y * qb.y + qa.z * qb.z;
    // if qa=qb or qa=-qb then theta = 0 and we can return qa
    if (abs(cosHalfTheta) >= 1.0){
        qm.w = qa.w;qm.x = qa.x;qm.y = qa.y;qm.z = qa.z;
        return qm;
    }
    // Calculate temporary values.
    double halfTheta = acos(cosHalfTheta);
    double sinHalfTheta = sqrt(1.0 - cosHalfTheta*cosHalfTheta);
    // if theta = 180 degrees then result is not fully defined
    // we could rotate around any axis normal to qa or qb
    if (fabs(sinHalfTheta) < 0.001){ // fabs is floating point absolute
        qm.w = (qa.w * 0.5 + qb.w * 0.5);
        qm.x = (qa.x * 0.5 + qb.x * 0.5);
        qm.y = (qa.y * 0.5 + qb.y * 0.5);
        qm.z = (qa.z * 0.5 + qb.z * 0.5);
        return qm;
    }
    double ratioA = sin((1 - t) * halfTheta) / sinHalfTheta;
    double ratioB = sin(t * halfTheta) / sinHalfTheta; 
    //calculate Quaternion.
    qm.w = (qa.w * ratioA + qb.w * ratioB);
    qm.x = (qa.x * ratioA + qb.x * ratioB);
    qm.y = (qa.y * ratioA + qb.y * ratioB);
    qm.z = (qa.z * ratioA + qb.z * ratioB);
    return qm;
}

来自:http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/

票数 14
EN

Stack Overflow用户

发布于 2010-11-05 01:28:18

您需要将矩阵转换为不同的表示形式-四元数可以很好地实现这一点,而插值四元数是一个定义良好的操作。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4099369

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档