好用高效的python四元数库-quaternion

一、简介

https://github.com/moble/quaternion

这个库主要是在Numpy的基础上增加一个quaternion的类型,不仅实现了四元数相关操作的numpy实现,同时也将numpy的很多用法拓展到了相关四元数上。并且这个库的核心实现使用c语言实现的,保证了这个库在运算上的较高速度。

在近期进行四元数的学习中,比较了多个库,其中包括Scipy的旋转相关库,以及其他库,最终还是选择了这个库,原因在于其对于numpy的支持,但是由于其说明文档中只有四元数很小一部分的使用说明,但其实这个库所能实现的功能是远大于作者写的说明文档的,故写下这篇中文文档,供自己记录学习。

二、安装

如果是在conda环境下的,最好使用

conda install -c conda-forge quaternion

如果出现了,下载安装后No module name ‘quaternion’,可以适当降低numpy版本,目前numpy-1.20.3适配quater

nion-2022.4.3版本

也可以使用pip

python -m pip install --upgrade --force-reinstall numpy-quaternion

根据Releases · moble/quaternion (github.com)中说明的使用依赖仍然需要安装conda install scipy numba

三、基础用法

import numpy as np

import quaternion

首先构建几个四元数

q1 = np.quaternion(1,2,3,4)

q2 = quaternion.from_float_array([1,2,3,4])

# 生成的都是单位四元数

q3 = quaternion.from_rotation_matrix([[1,2,3],[1,2,3],[1,2,3]])

q4 = quaternion.from_euler_angles([1,2,3])

print(q1,q2,q3,q4)

四元数叉乘

(

w

1

,

x

1

,

y

1

,

z

1

)

(

w

2

,

x

2

,

y

2

,

z

2

)

=

(

w

1

w

2

x

1

x

2

y

1

y

2

z

1

z

2

,

w

1

x

2

+

x

1

w

2

+

z

1

y

2

y

1

z

2

,

w

1

y

2

+

y

1

w

2

+

x

1

z

2

z

1

x

2

,

w

1

z

2

+

z

1

w

2

+

y

1

x

2

x

1

y

2

)

(w_1,x_1,y_1,z_1) \otimes (w_2,x_2,y_2,z_2) = \begin{matrix} (&w_1w_2-x_1x_2-y_1y_2-z_1z_2,\\&w_1x_2+x_1w_2+z_1y_2-y_1z_2,\\&w_1y_2+y_1w_2+x_1z_2-z_1x_2,\\&w_1z_2+z_1w_2+y_1x_2-x_1y_2&) \end{matrix}

(w1​,x1​,y1​,z1​)⊗(w2​,x2​,y2​,z2​)=(​w1​w2​−x1​x2​−y1​y2​−z1​z2​,w1​x2​+x1​w2​+z1​y2​−y1​z2​,w1​y2​+y1​w2​+x1​z2​−z1​x2​,w1​z2​+z1​w2​+y1​x2​−x1​y2​​)​

# dot方法这里也是叉乘

print(np.dot(q1,q2))

print(q1 * q2)

print(np.multiply(q1,q2))

四元数的模

q

=

w

2

+

x

2

+

y

2

+

z

2

\lvert q \rvert = \sqrt{w^2+x^2+y^2+z^2}

∣q∣=w2+x2+y2+z2

# 计算四元数的模

print(q1.abs())

print(q1.absolute())

print(np.sqrt(q1.norm()))

# 四元数的归一化

print(q1 / q1.abs())

print(q1.normalized())

四元数的Cayley norm

q

=

w

2

+

x

2

+

y

2

+

z

2

\lVert q \rVert = w^2+x^2+y^2+z^2

∥q∥=w2+x2+y2+z2

注意四元数的Norm和numpy中的np.linalg.norm方法不同,numpy中是Euclidean norm,而四元数中的norm是Cayley norm

print(q1.norm())

四元数的共轭与逆

四元数的共轭就是让四元数的向量部分取负

q

=

(

w

,

x

,

y

,

z

)

=

(

w

,

x

,

y

,

z

)

q^* = (w,x,y,z)^* = (w,-x,-y,-z)

q∗=(w,x,y,z)∗=(w,−x,−y,−z)

四元数的逆就是四元数的共轭除以它的Cayley norm

q

1

=

q

q

q^{-1} = \frac{q^*}{\lVert q \rVert}

q−1=∥q∥q∗​

一般用单位四元数,此时它的逆和共轭是相等的

# 四元数求共轭

print(q1.conjugate())

# 四元数求逆

print(q1.inverse())

# 单位四元数的共轭和逆是相等的

q_normolized = q1.normalized()

print(q_normolized.conjugate())

print(q_normolized.conjugate() / q_normolized.norm())

两个四元数间的旋转量

表示一个方位到另一个方位的旋转量

q

=

q

b

e

g

i

n

q

a

f

t

e

r

q = q_{begin}^* * q_{after}

q=qbegin∗​∗qafter​(

q

b

e

g

i

n

,

q

a

f

t

e

r

q_{begin},q_{after}

qbegin​,qafter​是单位四元数)

q

=

q

b

e

g

i

n

1

q

a

f

t

e

r

q = q_{begin}^{-1} * q_{after}

q=qbegin−1​∗qafter​(

q

b

e

g

i

n

,

q

a

f

t

e

r

q_{begin},q_{after}

qbegin​,qafter​不是单位四元数)

q = q3.conjugate() * q4

print(q)

# 要注意四元数叉乘顺序

print(q * q3)

print(q3 * q)

print(q4)

q3New = 2 * q3

print(q3New)

q = q3New.inverse() * q4

print(q.normalized())

四元数点乘

用于度量两个四元数的相似性,和向量的点乘类似,两四元数点乘绝对值越大其代表的旋转约相似,点乘趋近于-1或者1,都意味着相似,因为

(

1

,

0

,

0

,

0

)

(1,0,0,0)

(1,0,0,0)和

(

1

,

0

,

0

,

0

)

(-1,0,0,0)

(−1,0,0,0)的意义是当旋转角为360度的整数倍时,方位没有改变

# 在quaternion库中没有对应的方法

def quatDot(q1,q2):

return np.abs((q1.w * q2.w + q1.x * q2.x + q1.y * q2.y + q1.z * q2.z) / q1.absolute()*q2.absolute() )

四、参考

四元数基础 - 圣骑士wind - 博客园 (cnblogs.com)

四元数的基本运算_飘零过客的博客-CSDN博客_四元数运算

文章来源

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: