程序中的四元数表示法

网上有很多四元数相关的文章。

百度百科 http://baike.baidu.com/view/319754.htm

某位的博客 http://caterpillar.onlyfun.net/Gossip/ComputerGraphics/QuaternionsRotate.htm

但当你看完这些后。再看着下面这样的代码,你能快速回过神来么?

class     CQuaternion 

public: 
    CQuaternion(const float fScalar,const Vector3& rVec) 
    { 
        mVector=rVec ; 
        mScalar=fScalar; 
    }

    void FromAxisAngle (const Vector3& rAxis, const F32 Angle) 
    { 
        F32 fSin, fCos; 
        //取得一个弧度角的SIN COS值 
        SinCos( Angle*0.5f, fSin, fCos); 
        mVector = rAxis*fSin; 
        mScalar = fCos; 
    } 
private: 
    float mScalar; 
    float mVector; 
}

class CMatrix44 

public: 
    enum      { _X_,_Y_,_Z_,_W_ }; 
    void QuaternionToMatrix(const CQuaternion& q) 
    { 
        F32 s,xs,ys,zs,wx,wy,wz,xx,xy,xz,yy,yz,zz; 
        s = q.Length2(); 
        s = (s>0 ? 2.f/s : 0);

        xs = q.Vect[_X_]*s;        ys = q.Vect[_Y_]*s;        zs = q.Vect[_Z_]*s; 
        wx = q.Scalar*xs;        wy = q.Scalar*ys;        wz = q.Scalar*zs; 
        xx = q.Vect[_X_]*xs;    xy = q.Vect[_X_]*ys;    xz = q.Vect[_X_]*zs; 
        yy = q.Vect[_Y_]*ys;    yz = q.Vect[_Y_]*zs;    zz = q.Vect[_Z_]*zs;

        (*this)[0].Set(1.f-(yy+zz),xy+wz,      xz-wy,      0.f);  // col 0 
        (*this)[1].Set(xy-wz,      1.f-(xx+zz),yz+wx,      0.f);  // col 1 
        (*this)[2].Set(xz+wy,      yz-wx,      1.f-(xx+yy),0.f);  // col 2 
    } 
    //忽略其它无关紧要的 
    //、、、、、、、 
};

//========================================================

不用多说,肯定有回过神来的,也有没有回过神来的。

正如上面那某位的博客里面讲到的。

对于旋转轴A,绕其旋转一定的角度,则可以表示为

x = s * Xa 
y = s * Xb 
z = s * Xc 
w = cos(θ/2) 
s = sin(θ/2)

这正是我们FromAxisAngle 所做的事情。

 

而QuaternionToMatrix则是对应了

 

我想说明的是,数学库本身并不在于代码。而是在于数学公式,代码仅是将其用另一种符号表示出来而已。只要仔细去看,定能明白其中的道理。

 

关于文中介绍的公式推导以及万向锁,可以GOOGLE和百度。

另外,编程中还经常用到欧拉角和矩阵的转换。

 

这三个的特点。

矩阵运算的数据相对来说比较直观,容易调试和诊断。但数据存储量大,特别是旋转的时候,会浪费很多空间。

欧拉角储存小,但有万向锁,并且插值不够平滑。

四元数据量介于二者之间。但插值容易。

在骨骼动画中,可以在文件中存储欧拉角,加载后将旋转数据转换为四元数。最后动画计算时统一采用矩阵运算。

要说的东西很多,一言难尽。今天就到这里吧。

作者:码瘾少年·麒麟子 
出处:http://www.cnblogs.com/geniusalex/ 
蛮牛专栏:麒麟子 
简介:09年入行,喜欢游戏和编程,对3D游戏和引擎尤其感兴趣。 
版权声明:本文版权归作者和博客园共有,欢迎转载。转载必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载:http://www.cnblogs.com/geniusalex/archive/2010/12/19/1910879.html

时间: 2024-10-27 10:22:56

程序中的四元数表示法的相关文章

在ASP中使用均速分页法提高分页速度

分页|速度 均速分页法 一.适用范围 均速分页法主要适用于文章系统,新闻系统等排序方法固定的ASP+ACCESS应用 二.特点说明 很多用过一些文章系统或是新闻系统的朋友知道,一般的文章系统或是新闻系统,在分类分页时,通常是通过读取数据库中满足条件的排序后数据,然后根据请求页号,通过定位操作,指向某条数据,并且开始读取这条数据后面的若干条数据作为一页.这种分页方法,原理简单,但是存在的问题是每次都需要把数据库中满足条件的排序后数据都读取出来,如果有两千条数据,这个还好,如果有两万条呢?显示,这会

六个方法解决应用程序中死锁现象的出现

在应用程序中就可以采用下面的一些方法来避免死锁: (1)合理安排表访问顺序. (2)在事务中尽量避免用户干预,尽量使一个事务处理的任务少些, 保持事务简短并在一个批处理中. (3)数据访问时域离散法, 数据访问时域离散法是指在客户机/服务器结构中,采取各种控制手段控制对数据库或数据库中的对象访问时间段.主要通过以下方式实现: 合理安排后台事务的执行时间,采用工作流对后台事务进行统一管理.工作流在管理任务时,一方面限制同一类任务的线程数(往往限制为1个),防止资源过多占用; 另一方面合理安排不同任

在ASP中使用均速分页法提高分页速度的方法_应用技巧

均速分页法 一.适用范围 均速分页法主要适用于文章系统,新闻系统等排序方法固定的ASP+ACCESS应用 二.特点说明     很多用过一些文章系统或是新闻系统的朋友知道,一般的文章系统或是新闻系统,在分类分页时,通常是通过读取数据库中满足条件的排序后数据,然后根据请求页号,通过定位操作,指向某条数据,并且开始读取这条数据后面的若干条数据作为一页.这种分页方法,原理简单,但是存在的问题是每次都需要把数据库中满足条件的排序后数据都读取出来,如果有两千条数据,这个还好,如果有两万条呢?显示,这会占用

将规则集嵌入到由公共云托管的Web应用程序中的架构和流程

在本系列的第 2 部分中,我们将介绍用于将规则集嵌入到由公共云托管的 Web 应用程序中的架构和流程. 本专栏面向 http://www.aliyun.com/zixun/aggregation/13387.html">WebSphere Operational Decision Management 开发人员,并假设读者能够从开发人员的角度较好地理解该产品.参阅 参考资料 部分,了解完成本专栏介绍的步骤需要具备的知识.在撰写本专栏时,我使用的产品版本为 WebSphere Operati

请大家帮个忙:在java中 构造器和放法的根本区别是什么?

问题描述 请大家帮个忙:在java中 构造器和放法的根本区别是什么? 在java中 构造器和放法的根本区别是什么?我真迷惑了 解决方案 没有根本的区别,它们之间是包涵的关系,构造函数是特殊的方法. 特殊在哪里?不能定义返回值,不能重写,不能任意起名,不能随意调用(用new调用). 好比正方形和矩形的关系,正方形是特殊的矩形. 解决方案二: 构造器是你创建一个实例对象时调用到的,它默认的是不带参数的.你可以自己写带参数的构造函数. 方法是还分实例方法和类方法.如果是实例方法,那么就是由上面的构造器

在ASP中使用均速分页法提高分页速度_应用技巧

一.适用范围 均速分页法主要适用于文章系统,新闻系统等排序方法固定的ASP+ACCESS应用 二.特点说明 很多用过一些文章系统或是新闻系统的朋友知道,一般的文章系统或是新闻系统,在分类分页时,通常是通过读取数据库中满足条件的排序后数据,然后根据请求页号,通过定位操作,指向某条数据,并且开始读取这条数据后面的若干条数据作为一页.这种分页方法,原理简单,但是存在的问题是每次都需要把数据库中满足条件的排序后数据都读取出来,如果有两千条数据,这个还好,如果有两万条呢?显示,这会占用大量的内存,浪费很多

java-JAVA程序中,校验传入的参数是否是正确,最优方法

问题描述 JAVA程序中,校验传入的参数是否是正确,最优方法 各位大神,指导下 在java程序中,校验传入的参数是否是正确,我现用的有2种方法: 1:是直接自定义抛出参数异常[IllegalArgumentException] 2:不抛出异常,把这个参数异常的计入日志直接return 哪种好些呢? 或者还有其他的最佳实践吗? 解决方案 个人认为还是写入日志比较好. 解决方案二: 看异常的性质,如果异常发生不处理会导致程序出现不可预料的结果,最好还是直接丢出,这样调试起来容易. 解决方案三: 是否

在ASP中使用均速分页法提高分页速度的方法

均速分页法 一.适用范围 均速分页法主要适用于文章系统,新闻系统等排序方法固定的ASP+ACCESS应用 二.特点说明     很多用过一些文章系统或是新闻系统的朋友知道,一般的文章系统或是新闻系统,在分类分页时,通常是通过读取数据库中满足条件的排序后数据,然后根据请求页号,通过定位操作,指向某条数据,并且开始读取这条数据后面的若干条数据作为一页.这种分页方法,原理简单,但是存在的问题是每次都需要把数据库中满足条件的排序后数据都读取出来,如果有两千条数据,这个还好,如果有两万条呢?显示,这会占用

在Java程序中实现FTP的上传下载

FtpList部分是用来显示FTP服务器上的文件:GetButton部分为从FTP服务器下传一个文件:PutButton部分为向FTP服务器上传一个文件. 别忘了在程序中还要引入两个库文件(importsun.net.*,import sun.net.ftp.*). 以下是这三部分的JAVA源程序: (1)显示FTP服务器上的文件 void ftpList_actionPerformed(ActionEvent e) { String server=serverEdit.getText(); /