Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
Vector3d([[1, 2, 3], [-3, -2, -1]]),
[[0, 0, 0], [4, 4, 4]],
marks=pytest.mark.xfail(raises=ValueError)
),
([1, 2, 3], Scalar([4]), [4, 8, 12]),
([1, 2, 3], 0.5, [0.5, 1., 1.5]),
([1, 2, 3], [-1, 2], [[-1, -2, -3], [2, 4, 6]]),
([1, 2, 3], np.array([-1, 1]), [[-1, -2, -3], [1, 2, 3]]),
pytest.param([1, 2, 3], 'dracula', None, marks=pytest.mark.xfail),
], indirect=['vector'])
def test_mul(vector, other, expected):
s1 = vector * other
s2 = other * vector
assert np.allclose(s1.data, expected)
assert np.allclose(s1.data, s2.data)
([1, 2, 3], Vector3d([[1, 2, 3], [-3, -2, -1]]), [[0, 0, 0], [4, 4, 4]]),
([1, 2, 3], Scalar([4]), [-3, -2, -1]),
([1, 2, 3], 0.5, [0.5, 1.5, 2.5]),
([1, 2, 3], [-1, 2], [[2, 3, 4], [-1, 0, 1]]),
([1, 2, 3], np.array([-1, 1]), [[2, 3, 4], [0, 1, 2]]),
pytest.param([1, 2, 3], 'dracula', None, marks=pytest.mark.xfail),
], indirect=['vector'])
def test_sub(vector, other, expected):
s1 = vector - other
s2 = other - vector
assert np.allclose(s1.data, expected)
assert np.allclose(-s1.data, s2.data)
def vector(request):
return Vector3d(request.param)
def vector(request):
return Vector3d(request.param)
neo-Eulerian vectors have different scaling functions applied to the angle
of rotation for different properties of the space. For example, the axis-angle
representation does not scale the angle of rotation, making it easy for direct
interpretation, whereas the Rodrigues representation applies a scaled tangent
function, such that any straight lines in Rodrigues space represent rotations
about a fixed axis.
"""
import abc
import numpy as np
from orix.scalar import Scalar
from orix.vector import Vector3d
class NeoEuler(Vector3d, abc.ABC):
"""Base class for neo-Eulerian vectors.
"""
@classmethod
@abc.abstractmethod
def from_rotation(cls, rotation): # pragma: no cover
"""NeoEuler : Create a new vector from the given rotation."""
pass
@property
@abc.abstractmethod
def angle(self): # pragma: no cover
"""Scalar : the angle of rotation."""
pass
def axis(self):
"""Vector3d : the axis of rotation."""
return Vector3d(self.unit)
def get_axis_orders(self):
s = self[self.angle > 0]
if s.size == 0:
return {}
return {
Vector3d(a): b + 1
for a, b in zip(*np.unique(s.axis.data, axis=0, return_counts=True))
}
def from_axes_angles(cls, axes, angles):
"""Create new AxAngle object explicitly from the given axes and angles.
Parameters
----------
axes : Vector3d or array_like
The axis of rotation.
angles : array_like
The angle of rotation, in radians.
Returns
-------
AxAngle
"""
axes = Vector3d(axes).unit
angles = np.array(angles)
axangle_data = angles[..., np.newaxis] * axes.data
return cls(axangle_data)
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
if isinstance(other, int) or isinstance(other, list): # has to plus/minus 1
other = np.atleast_1d(other).astype(int)
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