def from_euler(cls, euler): """Creates a rotation from an array of Euler angles. Parameters ---------- euler : array-like Euler angles in the Bunge convention. """ # Bunge convention euler = np.array(euler) n = euler.shape[:-1] alpha, beta, gamma = euler[..., 0], euler[..., 1], euler[..., 2] alpha -= np.pi / 2 gamma -= 3 * np.pi / 2 zero = np.zeros(n) qalpha = Quaternion( np.stack((np.cos(alpha / 2), zero, zero, np.sin(alpha / 2)), axis=-1)) qbeta = Quaternion( np.stack((np.cos(beta / 2), zero, np.sin(beta / 2), zero), axis=-1)) qgamma = Quaternion( np.stack((np.cos(gamma / 2), zero, zero, np.sin(gamma / 2)), axis=-1)) data = qalpha * qbeta * qgamma rot = cls(data.data) rot.improper = zero return rot
def __mul__(self, other): if isinstance(other, Rotation): q = Quaternion(self) * Quaternion(other) r = other.__class__(q) i = np.logical_xor(self.improper, other.improper) r.improper = i return r if isinstance(other, Quaternion): q = Quaternion(self) * other return q if isinstance(other, Vector3d): v = Quaternion(self) * other improper = (self.improper * np.ones(other.shape)).astype(bool) v[improper] = -v[improper] return v try: other = np.atleast_1d(other).astype(int) except ValueError: pass if isinstance(other, np.ndarray): assert np.all( abs(other) == 1), "Rotations can only be multiplied by 1 or -1" r = Rotation(self.data) r.improper = np.logical_xor(self.improper, other == -1) return r return NotImplemented
def __gt__(self, other): c = Quaternion(self).dot_outer(Quaternion(other)).data inside = np.logical_or(np.all(np.greater_equal(c, 0), axis=0), np.all(np.less_equal(c, 0), axis=0)) return inside
def quaternion(request): return Quaternion(request.param)
def test_init(input_length): with pytest.raises(DimensionError): Quaternion(tuple(range(input_length)))
def something(request): return Quaternion(request.param)
def identity(): return Quaternion((1, 0, 0, 0))
def test_multiply_vector(quaternion, vector, expected): q = Quaternion(quaternion) v = Vector3d(vector) v_new = q * v assert np.allclose(v_new.data, expected)
import numpy as np import pytest from texpy.base import DimensionError from texpy.quaternion import Quaternion from texpy.vector import Vector3d values = [(0.707, 0., 0., 0.707), (0.5, -0.5, -0.5, 0.5), (0., 0., 0., 1.), (1., 1., 1., 1.), ( (0.5, -0.5, -0.5, 0.5), (0., 0., 0., 1.), ), Quaternion([[ (0., 0., 0., 1.), (0.707, 0., 0., 0.707), ], [ (1., 1., 1., 1.), (0.707, 0., 0., 0.707), ]]), np.array((4, 3, 2, 1))] @pytest.fixture(params=values) def quaternion(request): return Quaternion(request.param) @pytest.fixture def identity(): return Quaternion((1, 0, 0, 0))