旋转矩阵之间的插值 [英] interpolate between rotation matrices

查看:1357
本文介绍了旋转矩阵之间的插值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个描述任意旋转两个旋转矩阵。 (4×4兼容OpenGL)

i have two rotation matrices that describe arbitrary rotations. (4x4 opengl compatible)

现在我希望他们之间进行内插,以便它跟随从一个旋转装置中的其他的径向路径。想在三脚架上的照相机寻找一种方式,然后旋转。

now i want to interpolate between them, so that it follows a radial path from one rotation to the other. think of a camera on a tripod looking one way and then rotating.

如果我插每一个组件,我收到了挤压,所以我想我需要进行插值矩阵的某些组件。但哪些?

if i interpolate every component i get a squeezing result, so i think i need to interpolate only certain components of the matrix. but which ones?

推荐答案

您必须使用球面线性插值的矩阵的旋转部件和线性的其他部分。最好的办法是把你的矩阵到四元数和使用(简单)四元数球面线性插值: http://en.wikipedia.org/wiki /球面线性插值

You have to use SLERP for the rotational parts of the matrices, and linear for the other parts. The best way is to turn your matrices into quaternions and use the (simpler) quaternion SLERP: http://en.wikipedia.org/wiki/Slerp.

我建议您阅读图形宝石II或III,特别是关于矩阵分解成简单的转换部分。下面是斯​​宾塞·W·托马斯源本章内容:

I suggest reading Graphic Gems II or III,specifically the sections about decomposing matrices into simpler transformations. Here's Spencer W. Thomas' source for this chapter:

<一个href="http://tog.acm.org/resources/GraphicsGems/gemsii/unmatrix.c">http://tog.acm.org/resources/GraphicsGems/gemsii/unmatrix.c

当然,我建议你学习如何做自己。这真的不是那么难,只是很多恼人的代数。最后,这里是关于如何把一个矩阵到四元,而回,由id Software公司有很大纸:<一href="http://cache-www.intel.com/cd/00/00/29/37/293748_293748.pdf">http://cache-www.intel.com/cd/00/00/29/37/293748_293748.pdf

Of course, I suggest you learn how to do this yourself. It's really not that hard, just a lot of annoying algebra. And finally, here's a great paper on how to turn a matrix into a quaternion, and back, by Id software: http://cache-www.intel.com/cd/00/00/29/37/293748_293748.pdf

修改:这是公式pretty的很多大家举,这是从1985年SIGGRAPH论文

Edit: This is the formula pretty much everyone cites, it's from a 1985 SIGGRAPH paper.

其中,的:

- 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

code:

Code:

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;
}

从:<一href="http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/">http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/

这篇关于旋转矩阵之间的插值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆