예제 #1
0
    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
예제 #2
0
 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
예제 #3
0
 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
예제 #4
0
def quaternion(request):
    return Quaternion(request.param)
예제 #5
0
def test_init(input_length):
    with pytest.raises(DimensionError):
        Quaternion(tuple(range(input_length)))
예제 #6
0
def something(request):
    return Quaternion(request.param)
예제 #7
0
def identity():
    return Quaternion((1, 0, 0, 0))
예제 #8
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)
예제 #9
0
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))