游戏开发论坛

 找回密码
 立即注册
搜索
查看: 24429|回复: 29

4元数宝典

[复制链接]

9

主题

102

帖子

343

积分

中级会员

Rank: 3Rank: 3

积分
343
发表于 2007-2-24 19:02:00 | 显示全部楼层 |阅读模式
这是国内找不到的超好文章。(为什么大陆的4元数文章很垃圾呢?)
(翻译中。。。奉献给大家~~)

70秒即懂,能使用,用四元数,4元数,阔特尼恩,Quaternion旋转
(C) 中田  亨  (独立行政法人  产业技术综合研究所  数字人类研究中心  研究员 博士(工学))
2003年11月25日

★这个页面的对象读者
想把三次元的旋转,用CG等定量地处理的人
使用欧拉角(Euler Angles)的话,不懂得其道理的人
卡尔丹角和欧拉角(Cardan Angles)不能区别的人
对吉恩瓦尔洛克很困惑的人
但是,对数学之类麻烦的事情很讨厌的人
想要实例程序的人
没有时间的人

★旋转篇:
 我将说明使用了四元数(si yuan shu, quaternion)的旋转的操作步骤
(1)四元数的虚部,实部和写法
所谓四元数,就是把4个实数组合起来的东西。
4个元素中,一个是实部,其余3个是虚部。
比如,叫做Q的四元数,实部t而虚部是x,y,z构成,则像下面这样写。
Q = (t; x, y, z)
又,使用向量 V=(x,y,z),
Q = (t; V)  
也可以这么写。

正规地用虚数单位i,j,k的写法的话,
Q = t + xi + yj + zk
也这样写,不过,我不大使用

(2)四元数之间的乘法
虚数单位之间的乘法
ii = -1, ij = -ji = k (其他的组合也是循环地以下同文)
有这么一种规则。(我总觉得,这就像是向量积(外积),对吧)
用这个规则一点点地计算很麻烦,所以请用像下面这样的公式计算。

A = (a; U)
B = (b; V)
AB = (ab - U·V; aV + bU + U×V)
不过,“U·V”是内积,「U×V」是外积的意思。
注意:一般AB<>BA所以乘法的左右要注意!

(3)3次元的坐标的四元数表示
如要将某坐标(x,y,z)用四元数表示,
P = (0; x, y, z)
则要这么写。

另外,即使实部是零以外的值,下文的结果也一样。用零的话省事所以我推荐。

(4)旋转的四元数表示
以原点为旋转中心,旋转的轴是(α, β, γ)
(但 α^2 + β^2 + γ^2 = 1),
(右手系的坐标定义的话,望向向量(α, β, γ)的前进方向反时针地)
转θ角的旋转,用四元数表示就是,
Q = (cos(θ/2); α sin(θ/2), β sin(θ/2), γ sin(θ/2))
R = (cos(θ/2); -α sin(θ/2), -β sin(θ/2), -γ sin(θ/2))
(另外R 叫 Q 的共轭四元数。)

那么,如要实行旋转,
则 R P Q = (0; 答案)

请像这样三明治式地计算。这个值的虚部就是旋转之后的点的坐标值。
(另外,实部应该为零。请验算看看)

*未完。。。

9

主题

102

帖子

343

积分

中级会员

Rank: 3Rank: 3

积分
343
 楼主| 发表于 2007-2-24 19:06:00 | 显示全部楼层

Re:4元数宝典

/// Quaternion.cpp
/// (C) Toru Nakata, toru-nakata@aist.go.jp
/// 2004 Dec 29
  
#include <math.h>
#include <iostream.h>
  
/// Define Data type
typedef struct
{
              double t; // real-component
              double x; // x-component
              double y; // y-component
              double z; // z-component
} quaternion;
  
  
//// Kakezan
quaternion Kakezan(quaternion left, quaternion right)
{
              quaternion ans;
              double d1, d2, d3, d4;
  
              d1 =  left.t * right.t;
              d2 = -left.x * right.x;
              d3 = -left.y * right.y;
              d4 = -left.z * right.z;
              ans.t = d1+ d2+ d3+ d4;
  
              d1 =  left.t * right.x;
              d2 =  right.t * left.x;
              d3 =  left.y * right.z;
              d4 = -left.z * right.y;
              ans.x =  d1+ d2+ d3+ d4;
  
              d1 =  left.t * right.y;
              d2 =  right.t * left.y;
              d3 =  left.z * right.x;
              d4 = -left.x * right.z;
              ans.y =  d1+ d2+ d3+ d4;
  
              d1 =  left.t * right.z;
              d2 =  right.t * left.z;
              d3 =  left.x * right.y;
              d4 = -left.y * right.x;
              ans.z =  d1+ d2+ d3+ d4;
              
              return ans;
}
  
//// Make Rotational quaternion
quaternion MakeRotationalQuaternion(double radian, double AxisX, double AxisY, double AxisZ)
{
              quaternion ans;
              double norm;
              double ccc, sss;
              
              ans.t = ans.x = ans.y = ans.z = 0.0;
  
              norm = AxisX *  AxisX +  AxisY *  AxisY +  AxisZ *  AxisZ;
              if(norm <= 0.0) return ans;
  
              norm = 1.0 / sqrt(norm);
              AxisX *= norm;
              AxisY *= norm;
              AxisZ *= norm;
  
              ccc = cos(0.5 * radian);
              sss = sin(0.5 * radian);
  
              ans.t = ccc;
              ans.x = sss * AxisX;
              ans.y = sss * AxisY;
              ans.z = sss * AxisZ;
  
              return ans;
}
  
//// Put XYZ into  quaternion
quaternion PutXYZToQuaternion(double PosX, double PosY, double PosZ)
{
              quaternion ans;
  
              ans.t = 0.0;
              ans.x = PosX;
              ans.y = PosY;
              ans.z = PosZ;
  
              return ans;
}
  
///// main
int main()
{
              double px, py, pz;
              double ax, ay, az, th;
              quaternion ppp, qqq, rrr;
  
              cout << &quotoint Position (x, y, z) " << endl;
              cout << "  x = ";
              cin >> px;
              cout << "  y = ";
              cin >> py;
              cout << "  z = ";
              cin >> pz;
              ppp = PutXYZToQuaternion(px, py, pz);
  
              while(1) {
                            cout << "\nRotation Degree ? (Enter 0 to Quit) " << endl;
                            cout << "  angle = ";
                            cin >> th;
                            if(th == 0.0) break;
  
                            cout << "Rotation Axis Direction ? (x, y, z) " << endl;
                            cout << "  x = ";
                            cin >> ax;
                            cout << "  y = ";
                            cin >> ay;
                            cout << "  z = ";
                            cin >> az;
  
  
                            th *= 3.1415926535897932384626433832795 / 180.0; /// Degree -> radian;
  
                            qqq = MakeRotationalQuaternion(th, ax, ay, az);
                            rrr = MakeRotationalQuaternion(-th, ax, ay, az);
  
                            ppp = Kakezan(rrr, ppp);
                            ppp = Kakezan(ppp, qqq);
  
                            cout << "\nAnser X = " << ppp.x
                                          <<  "\n      Y = " << ppp.y
                                          <<  "\n      Z = " << ppp.z << endl;
  
              }
  
              return 0;
}  

*未完。。。

35

主题

1735

帖子

1739

积分

金牌会员

Rank: 6Rank: 6

积分
1739
QQ
发表于 2007-2-24 19:56:00 | 显示全部楼层

Re:4元数宝典

顶一下,果然是宝典,俗话说:欲练神功,必先自宫.若不自宫,也能成功,若已自宫,未必成功.

14

主题

245

帖子

256

积分

中级会员

Rank: 3Rank: 3

积分
256
QQ
发表于 2007-2-25 08:42:00 | 显示全部楼层

Re:4元数宝典

确实不错。。四元数,旋转必备啊。

197

主题

1041

帖子

1104

积分

金牌会员

Rank: 6Rank: 6

积分
1104
QQ
发表于 2007-2-25 10:40:00 | 显示全部楼层

Re:4元数宝典

我在物力系统中用得很多。AIR系统中也有应用。旋转我是用的向量转换法。

我就是数学不好,如果自己可以根据需要开发新的几何算法,会少走很多弯路。现在我全是一边补习高数,一边在做游戏。

44

主题

248

帖子

274

积分

中级会员

Rank: 3Rank: 3

积分
274
发表于 2007-2-26 13:59:00 | 显示全部楼层

Re:4元数宝典

把原文地址给出一下吧

0

主题

199

帖子

199

积分

注册会员

Rank: 2

积分
199
发表于 2007-2-26 17:13:00 | 显示全部楼层

Re:4元数宝典

很容易就搜到了
http://staff.aist.go.jp/toru-nakata/quaternion.html
不过是日文的,看不懂

9

主题

21

帖子

21

积分

注册会员

Rank: 2

积分
21
发表于 2007-2-28 23:27:00 | 显示全部楼层

Re:4元数宝典

顶,还在继续翻译不?

9

主题

102

帖子

343

积分

中级会员

Rank: 3Rank: 3

积分
343
 楼主| 发表于 2007-3-1 17:42:00 | 显示全部楼层

Re:4元数宝典

我靠,你怎么搜到的。

0

主题

199

帖子

199

积分

注册会员

Rank: 2

积分
199
发表于 2007-3-2 21:36:00 | 显示全部楼层

Re:4元数宝典

用google搜 4元数 中田 亨 就能搜到
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-12-19 23:39

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表