13.2.8. 齐次变换矩阵和四元数 MDAnalysis.lib.transformations

用于计算4x4矩阵的库,用于平移、旋转、反射、缩放、剪切、投影、正交化和叠加3D齐次坐标数组,以及用于在旋转矩阵、欧拉角和四元数之间进行转换。还包括Arcball控件对象和分解变换矩阵的函数。

作者:

Christoph Gohlke ,加州大学欧文分校荧光动力学实验室

版本:

2010.05.10

牌照:

BSD 3-子句

13.2.8.1. 要求

备注

API还不稳定,预计会在不同版本之间发生变化。

这段Python代码并没有针对速度进行优化。有关某些函数的更快实现,请参阅Transformations.c模块。

可以使用epydoc.生成HTML格式的文档。

矩阵(M)可以用以下公式求逆 numpy.linalg.inv(M) ,使用以下链接 numpy.dot(M0, M1) ,或用于转换齐次坐标(V),使用 numpy.dot(M, v) 对于形状 (4, *) 分别为“数组中的点” numpy.dot(v, M.T) 对于形状 (*, 4) “点数组”。

对OpenGL使用变换矩阵的转置 glMultMatrixd()

计算是用来进行的 numpy.float64 精确度。

向量、点、四元数和矩阵函数参数应为“类似数组”,即元组、列表或数值数组。

除非另行指定,否则返回类型都是数字数组。

除非另有说明,否则角度以弧度为单位。

四元数w+ix+jy+kz表示为 [w, x, y, z]

欧拉角的三元组可以以24种方式应用/解释,可以使用4个字符串或编码的4元组来指定:

  • Axes 4-string :例如‘sxyz’或‘ryxy’

    • 第一个字符:旋转应用于‘s’静态或‘r’旋转框架

    • 其余字符:连续旋转轴‘x’、‘y’或‘z’

  • Axes 4-tuple :例如(0,0,0,0)或(1,1,1,1)

    • 内轴:最右侧矩阵的轴(‘x’:0,‘y’:1,‘z’:2)的代码。

    • 奇偶:Even(0)如果内轴‘x’后面跟‘y’,‘y’后面跟‘z’,或者‘z’后面跟‘x’。否则就是奇怪的(1)。

    • 重复:第一个轴和最后一个轴相同(1)或不同(0)。

    • 框架:旋转应用于静态(0)或旋转(1)框架。

参考文献

  1. Ronald Goldman. Matrices and transformations. In Graphics Gems I, pages 472–475. Morgan Kaufmann, USA, 1990.

  2. Ken Shoemake. Uniform random rotations. In David Kirk, editor, Graphics Gems III, pages 124–132. Academic Press, 1992.

  3. Charles F.F. Karney. Quaternions in molecular modeling. Journal of Molecular Graphics and Modelling, 25(5):595–604, 2007. doi:https://doi.org/10.1016/j.jmgm.2006.04.002.

  4. Itzhack Y. Bar-Itzhack. New method for extracting the quaternion from a rotation matrix. Journal of Guidance, Control, and Dynamics, 23(6):1085–1087, 2000. doi:10.2514/2.4654.

  5. Ronald N. Goldman. Vii.4 - more matrices and transformations: shear and pseudo-perspective. In JAMES ARVO, editor, Graphics Gems II, pages 338–341. Morgan Kaufmann, San Diego, 1991. URL: https://www.sciencedirect.com/science/article/pii/B9780080507545500724, doi:https://doi.org/10.1016/B978-0-08-050754-5.50072-4.

  6. Spencer W. Thomas. Vii.1 - decomposing a matrix into simple transformations. In JAMES ARVO, editor, Graphics Gems II, pages 320–323. Morgan Kaufmann, San Diego, 1991. URL: https://www.sciencedirect.com/science/article/pii/B9780080507545500694, doi:https://doi.org/10.1016/B978-0-08-050754-5.50069-4.

  7. Ronald N. Goldman. Vii.2 - recovering the data from the transformation matrix. In James Arvo, editor, Graphics Gems II, pages 324–331. Morgan Kaufmann, San Diego, 1991. URL: https://www.sciencedirect.com/science/article/pii/B9780080507545500700, doi:https://doi.org/10.1016/B978-0-08-050754-5.50070-0.

  8. Ken Shoemake. Euler angle conversion. In Paul S. Heckbert, editor, Graphics Gems IV, pages 222–229. Morgan Kaufmann, 1994.

  9. Ken Shoemake. Arcball rotation control. In Paul S. Heckbert, editor, Graphics Gems IV, pages 175–192. Morgan Kaufmann, 1994.

  10. Ken Shoemake. Quaternions. In URL: https://www.ljll.math.upmc.fr/~frey/papers/scientific%20visualisation/Shoemake%20K.,%20Quaternions.pdf.

  11. James Diebel. Representing attitude: euler angles, unit quaternions, and rotation vectors. In 2006.

  12. W. Kabsch. A discussion of the solution for the best rotation to relate two sets of vectors. Acta Crystallographica Section A, 34(5):827–828, Sep 1978. URL: https://doi.org/10.1107/S0567739478001680, doi:10.1107/S0567739478001680.

  13. Berthold Horn. Closed-form solution of absolute orientation using unit quaternions. Journal of the Optical Society A, 4:629–642, 04 1987. doi:10.1364/JOSAA.4.000629.

  14. JMP van Waveren. From quaternion to matrix and back. In 2005. URL: http://www.intel.com/cd/ids/developer/asmo-na/eng/293748.htm.

示例

>>> from MDAnalysis.lib.transformations import *
>>> import numpy as np
>>> alpha, beta, gamma = 0.123, -1.234, 2.345
>>> origin, xaxis, yaxis, zaxis = (0, 0, 0), (1, 0, 0), (0, 1, 0), (0, 0, 1)
>>> I = identity_matrix()
>>> Rx = rotation_matrix(alpha, xaxis)
>>> Ry = rotation_matrix(beta, yaxis)
>>> Rz = rotation_matrix(gamma, zaxis)
>>> R = concatenate_matrices(Rx, Ry, Rz)
>>> euler = euler_from_matrix(R, 'rxyz')
>>> np.allclose([alpha, beta, gamma], euler)
True
>>> Re = euler_matrix(alpha, beta, gamma, 'rxyz')
>>> is_same_transform(R, Re)
True
>>> al, be, ga = euler_from_matrix(Re, 'rxyz')
>>> is_same_transform(Re, euler_matrix(al, be, ga, 'rxyz'))
True
>>> qx = quaternion_about_axis(alpha, xaxis)
>>> qy = quaternion_about_axis(beta, yaxis)
>>> qz = quaternion_about_axis(gamma, zaxis)
>>> q = quaternion_multiply(qx, qy)
>>> q = quaternion_multiply(q, qz)
>>> Rq = quaternion_matrix(q)
>>> is_same_transform(R, Rq)
True
>>> S = scale_matrix(1.23, origin)
>>> T = translation_matrix((1, 2, 3))
>>> Z = shear_matrix(beta, xaxis, origin, zaxis)
>>> R = random_rotation_matrix(np.random.rand(3))
>>> M = concatenate_matrices(T, R, Z, S)
>>> scale, shear, angles, trans, persp = decompose_matrix(M)
>>> np.allclose(scale, 1.23)
True
>>> np.allclose(trans, (1, 2, 3))
True
>>> np.allclose(shear, (0, math.tan(beta), 0))
True
>>> is_same_transform(R, euler_matrix(axes='sxyz', *angles))
True
>>> M1 = compose_matrix(scale, shear, angles, trans, persp)
>>> is_same_transform(M, M1)
True

13.2.8.2. 功能

在 0.11.0 版本发生变更: 转换库从MDAnalysis.core.Transformations移至MDAnalysis.lib.Transformations

class MDAnalysis.lib.transformations.Arcball(initial=None)[源代码]

虚拟轨迹球控制。

>>> from MDAnalysis.lib.transformations import Arcball
>>> import numpy as np
>>> ball = Arcball()
>>> ball = Arcball(initial=np.identity(4))
>>> ball.place([320, 320], 320)
>>> ball.down([500, 250])
>>> ball.drag([475, 275])
>>> R = ball.matrix()
>>> np.allclose(np.sum(R), 3.90583455)
True
>>> ball = Arcball(initial=[1, 0, 0, 0])
>>> ball.place([320, 320], 320)
>>> ball.setaxes([1,1,0], [-1, 1, 0])
>>> ball.setconstrain(True)
>>> ball.down([400, 200])
>>> ball.drag([200, 400])
>>> R = ball.matrix()
>>> np.allclose(np.sum(R), 0.2055924)
True
>>> ball.next()

初始化虚拟轨迹球控件。

首字母:四元数或旋转矩阵

down(point)[源代码]

设置初始光标窗口坐标并拾取约束轴。

drag(point)[源代码]

更新当前光标窗口坐标。

getconstrain()[源代码]

返回约束到轴模式的状态。

matrix()[源代码]

返回齐次旋转矩阵。

next(acceleration=0.0)[源代码]

继续沿最后一次拖动的方向旋转。

place(center, radius)[源代码]

放置Arcball,例如当窗口大小改变时。

居中序列 [2]

轨迹球中心的窗口坐标。

半径浮动

窗口坐标中的轨迹球半径。

setaxes(*axes)[源代码]

设置轴以约束旋转。

setconstrain(constrain)[源代码]

将约束的状态设置为轴模式。

MDAnalysis.lib.transformations.arcball_nearest_axis(point, axes)[源代码]

返回轴,该圆弧距离点最近。

MDAnalysis.lib.transformations.compose_matrix(scale=None, shear=None, angles=None, translate=None, perspective=None)[源代码]

从变换序列返回变换矩阵。

这是DEMPLAGE_MATRIX函数的逆函数。

转换顺序:

比例:3个比例因子的矢量切变:x-y、x-z、y-z轴的切变系数列表角度:关于静态x、y、z轴的欧拉角列表平移:沿x、y、z轴的平移向量透视:矩阵的透视分区

>>> from MDAnalysis.lib.transformations import (compose_matrix,
...     decompose_matrix, is_same_transform)
>>> import math
>>> import numpy as np
>>> scale = np.random.random(3) - 0.5
>>> shear = np.random.random(3) - 0.5
>>> angles = (np.random.random(3) - 0.5) * (2*math.pi)
>>> trans = np.random.random(3) - 0.5
>>> persp = np.random.random(4) - 0.5
>>> M0 = compose_matrix(scale, shear, angles, trans, persp)
>>> result = decompose_matrix(M0)
>>> M1 = compose_matrix(*result)
>>> is_same_transform(M0, M1)
True
MDAnalysis.lib.transformations.concatenate_matrices(*matrices)[源代码]

返回一系列转换矩阵的级联。

>>> from MDAnalysis.lib.transformations import concatenate_matrices
>>> import numpy as np
>>> M = np.random.rand(16).reshape((4, 4)) - 0.5
>>> np.allclose(M, concatenate_matrices(M))
True
>>> np.allclose(np.dot(M, M.T), concatenate_matrices(M, M.T))
True
MDAnalysis.lib.transformations.decompose_matrix(matrix)[源代码]

从转换矩阵返回转换序列。

矩阵array_like

非退化齐次变换矩阵

返回以下元素的元组:

比例:3个比例因子的矢量切变:x-y、x-z、y-z轴的切变系数列表角度:关于静态x、y、z轴的欧拉角列表平移:沿x、y、z轴的平移向量透视:矩阵的透视分区

如果矩阵类型错误或退化,则引发ValueError。

>>> from MDAnalysis.lib.transformations import (translation_matrix,
...     decompose_matrix, scale_matrix, euler_matrix)
>>> import numpy as np
>>> T0 = translation_matrix((1, 2, 3))
>>> scale, shear, angles, trans, persp = decompose_matrix(T0)
>>> T1 = translation_matrix(trans)
>>> np.allclose(T0, T1)
True
>>> S = scale_matrix(0.123)
>>> scale, shear, angles, trans, persp = decompose_matrix(S)
>>> scale[0]
0.123
>>> R0 = euler_matrix(1, 2, 3)
>>> scale, shear, angles, trans, persp = decompose_matrix(R0)
>>> R1 = euler_matrix(*angles)
>>> np.allclose(R0, R1)
True
MDAnalysis.lib.transformations.euler_from_quaternion(quaternion, axes='sxyz')[源代码]

从四元数返回指定轴序列的Euler角度。

>>> from MDAnalysis.lib.transformations import euler_from_quaternion
>>> import numpy as np
>>> angles = euler_from_quaternion([0.99810947, 0.06146124, 0, 0])
>>> np.allclose(angles, [0.123, 0, 0])
True
MDAnalysis.lib.transformations.projection_from_matrix(matrix, pseudo=False)[源代码]

从投影矩阵返回投影面和透视点。

返回值与PROJECTION_MATRATE函数的参数相同:POINT、NORMAL、DIRECTION、PEARTURE和PUSIC。

>>> from MDAnalysis.lib.transformations import (projection_matrix,
...     projection_from_matrix, is_same_transform)
>>> import numpy as np
>>> point = np.random.random(3) - 0.5
>>> normal = np.random.random(3) - 0.5
>>> direct = np.random.random(3) - 0.5
>>> persp = np.random.random(3) - 0.5
>>> P0 = projection_matrix(point, normal)
>>> result = projection_from_matrix(P0)
>>> P1 = projection_matrix(*result)
>>> is_same_transform(P0, P1)
True
>>> P0 = projection_matrix(point, normal, direct)
>>> result = projection_from_matrix(P0)
>>> P1 = projection_matrix(*result)
>>> is_same_transform(P0, P1)
True
>>> P0 = projection_matrix(point, normal, perspective=persp, pseudo=False)
>>> result = projection_from_matrix(P0, pseudo=False)
>>> P1 = projection_matrix(*result)
>>> is_same_transform(P0, P1)
True
>>> P0 = projection_matrix(point, normal, perspective=persp, pseudo=True)
>>> result = projection_from_matrix(P0, pseudo=True)
>>> P1 = projection_matrix(*result)
>>> is_same_transform(P0, P1)
True
MDAnalysis.lib.transformations.quaternion_imag(quaternion)[源代码]

返回四元数的虚部。

>>> from MDAnalysis.lib.transformations import quaternion_imag
>>> quaternion_imag([3.0, 0.0, 1.0, 2.0])
[0.0, 1.0, 2.0]
MDAnalysis.lib.transformations.quaternion_real(quaternion)[源代码]

返回四元数的实数部分。

>>> from MDAnalysis.lib.transformations import quaternion_real
>>> quaternion_real([3.0, 0.0, 1.0, 2.0])
3.0
MDAnalysis.lib.transformations.reflection_from_matrix(matrix)[源代码]

从反射矩阵返回镜面平面点和法向矢量。

>>> from MDAnalysis.lib.transformations import (reflection_matrix,
...     reflection_from_matrix, is_same_transform)
>>> import numpy as np
>>> v0 = np.random.random(3) - 0.5
>>> v1 = np.random.random(3) - 0.5
>>> M0 = reflection_matrix(v0, v1)
>>> point, normal = reflection_from_matrix(M0)
>>> M1 = reflection_matrix(point, normal)
>>> is_same_transform(M0, M1)
True
MDAnalysis.lib.transformations.rotation_from_matrix(matrix)[源代码]

从旋转矩阵返回旋转角度和轴。

>>> from MDAnalysis.lib.transformations import (rotation_matrix,
...     is_same_transform, rotation_from_matrix)
>>> import random, math
>>> import numpy as np
>>> angle = (random.random() - 0.5) * (2*math.pi)
>>> direc = np.random.random(3) - 0.5
>>> point = np.random.random(3) - 0.5
>>> R0 = rotation_matrix(angle, direc, point)
>>> angle, direc, point = rotation_from_matrix(R0)
>>> R1 = rotation_matrix(angle, direc, point)
>>> is_same_transform(R0, R1)
True
MDAnalysis.lib.transformations.rotaxis(a, b)[源代码]

返回旋转轴以将矢量a旋转到b。

参数:
  • a (array_like) -- 两个向量

  • b (array_like) -- 两个向量

返回:

c --向量将a旋转为b

返回类型:

np.ndarray

备注

如果a==b,则始终返回 [1,0,0]

MDAnalysis.lib.transformations.scale_from_matrix(matrix)[源代码]

从缩放矩阵返回缩放因子、原点和方向。

>>> from MDAnalysis.lib.transformations import (scale_matrix,
...      scale_from_matrix, is_same_transform)
>>> import random
>>> import numpy as np
>>> factor = random.random() * 10 - 5
>>> origin = np.random.random(3) - 0.5
>>> direct = np.random.random(3) - 0.5
>>> S0 = scale_matrix(factor, origin)
>>> factor, origin, direction = scale_from_matrix(S0)
>>> S1 = scale_matrix(factor, origin, direction)
>>> is_same_transform(S0, S1)
True
>>> S0 = scale_matrix(factor, origin, direct)
>>> factor, origin, direction = scale_from_matrix(S0)
>>> S1 = scale_matrix(factor, origin, direction)
>>> is_same_transform(S0, S1)
True
MDAnalysis.lib.transformations.shear_from_matrix(matrix)[源代码]

从剪切矩阵返回剪切角度、方向和平面。

>>> from MDAnalysis.lib.transformations import (shear_matrix,
...     shear_from_matrix, is_same_transform)
>>> import random, math
>>> import numpy as np
>>> angle = (random.random() - 0.5) * 4*math.pi
>>> direct = np.random.random(3) - 0.5
>>> point = np.random.random(3) - 0.5
>>> normal = np.cross(direct, np.random.random(3))
>>> S0 = shear_matrix(angle, direct, point, normal)
>>> angle, direct, point, normal = shear_from_matrix(S0)
>>> S1 = shear_matrix(angle, direct, point, normal)
>>> is_same_transform(S0, S1)
True
MDAnalysis.lib.transformations.translation_from_matrix(matrix)[源代码]

从翻译矩阵返回翻译向量。

>>> from MDAnalysis.lib.transformations import (translation_matrix,
...     translation_from_matrix)
>>> import numpy as np
>>> v0 = np.random.random(3) - 0.5
>>> v1 = translation_from_matrix(translation_matrix(v0))
>>> np.allclose(v0, v1)
True