three.js之用一个四元数代替两个3D向量的旋转。

翻译自:http://lolengine.net/blog/2013/09/18/beautiful-maths-quaternion-from-vectors

 

用一个四元数代替两个3D向量的旋转。

 

一个旋转最好的表示方法就是使用一个旋转轴和一个旋转角。旋转轴可以通过两个向量的叉乘得出。

旋转角(最小)可以通过两个向量的点积获得。点积获取的刚好是最小的旋转角。如下两种方法:

 

有了角度和旋转轴我们便可以用代码生成四元数

 

接下来让我们看看通过旋转轴和旋转角构造四元数的公式:

看代码:

 

 

减少三角函数的使用:

通过下面三角函数的公式,减少代码中三角函数的使用,简化代码,

直接看代码:

 

减少平方根的使用:

上述代码中用到 3次nomalize, 每个normalize 里面又有一个Math.sqrt;

 计算法向量 (w) 的模,可以使用下面的公式,

 

sin(θ)的值可以使用

$$\sin\theta = 2 \sin\frac{\theta}{2} \cos\frac{\theta}{2}$$

那么代码即可简化为:

 

我们可以清楚的发现创建单位法向量(w)时除了一个 half_sin,构造四元数对象(quat) 又乘了half_sin,因此  half_sin是重复而多余的,简化代码如下:

 

在THREE.js  中进行改进

用些引擎normalize 的速度是很快的,如是我们可以进一步该进代码:

 

通过观察代码我们容易发现,构建四元素对象时,用的是half_cos 的平方,故开平方的代码可以省去:

 

我们可以让四元素乘上 norm_u_norm_v 进一步简化代码

 

如果强迫 使用单位向量(three.js 确实是这样做的) 代码还可以简化为

 

注意:两个向量可能不在同一个平面内,还要进行判断

所有代码如下:

 

如有不对,欢迎抛砖

转载于:https://www.cnblogs.com/jocker/p/5042864.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值