Merge branch 'vectorized-orientation-conversion' into no-python-quaternion
This commit is contained in:
commit
99684c3e86
|
@ -246,9 +246,8 @@ class Rotation:
|
||||||
################################################################################################
|
################################################################################################
|
||||||
# static constructors. The input data needs to follow the convention, options allow to
|
# static constructors. The input data needs to follow the convention, options allow to
|
||||||
# relax these convections
|
# relax these convections
|
||||||
@classmethod
|
@staticmethod
|
||||||
def fromQuaternion(cls,
|
def fromQuaternion(quaternion,
|
||||||
quaternion,
|
|
||||||
acceptHomomorph = False,
|
acceptHomomorph = False,
|
||||||
P = -1):
|
P = -1):
|
||||||
|
|
||||||
|
@ -263,11 +262,10 @@ class Rotation:
|
||||||
if not np.isclose(np.linalg.norm(qu), 1.0):
|
if not np.isclose(np.linalg.norm(qu), 1.0):
|
||||||
raise ValueError('Quaternion is not of unit length.\n{} {} {} {}'.format(*qu))
|
raise ValueError('Quaternion is not of unit length.\n{} {} {} {}'.format(*qu))
|
||||||
|
|
||||||
return cls(qu)
|
return Rotation(qu)
|
||||||
|
|
||||||
@classmethod
|
@staticmethod
|
||||||
def fromEulers(cls,
|
def fromEulers(eulers,
|
||||||
eulers,
|
|
||||||
degrees = False):
|
degrees = False):
|
||||||
|
|
||||||
eu = eulers if isinstance(eulers, np.ndarray) and eulers.dtype == np.dtype(float) \
|
eu = eulers if isinstance(eulers, np.ndarray) and eulers.dtype == np.dtype(float) \
|
||||||
|
@ -276,11 +274,10 @@ class Rotation:
|
||||||
if np.any(eu < 0.0) or np.any(eu > 2.0*np.pi) or eu[1] > np.pi:
|
if np.any(eu < 0.0) or np.any(eu > 2.0*np.pi) or eu[1] > np.pi:
|
||||||
raise ValueError('Euler angles outside of [0..2π],[0..π],[0..2π].\n{} {} {}.'.format(*eu))
|
raise ValueError('Euler angles outside of [0..2π],[0..π],[0..2π].\n{} {} {}.'.format(*eu))
|
||||||
|
|
||||||
return cls(eu2qu(eu))
|
return Rotation(eu2qu(eu))
|
||||||
|
|
||||||
@classmethod
|
@staticmethod
|
||||||
def fromAxisAngle(cls,
|
def fromAxisAngle(angleAxis,
|
||||||
angleAxis,
|
|
||||||
degrees = False,
|
degrees = False,
|
||||||
normalise = False,
|
normalise = False,
|
||||||
P = -1):
|
P = -1):
|
||||||
|
@ -295,11 +292,10 @@ class Rotation:
|
||||||
if not np.isclose(np.linalg.norm(ax[0:3]), 1.0):
|
if not np.isclose(np.linalg.norm(ax[0:3]), 1.0):
|
||||||
raise ValueError('Axis angle rotation axis is not of unit length.\n{} {} {}'.format(*ax[0:3]))
|
raise ValueError('Axis angle rotation axis is not of unit length.\n{} {} {}'.format(*ax[0:3]))
|
||||||
|
|
||||||
return cls(ax2qu(ax))
|
return Rotation(ax2qu(ax))
|
||||||
|
|
||||||
@classmethod
|
@staticmethod
|
||||||
def fromBasis(cls,
|
def fromBasis(basis,
|
||||||
basis,
|
|
||||||
orthonormal = True,
|
orthonormal = True,
|
||||||
reciprocal = False,
|
reciprocal = False,
|
||||||
):
|
):
|
||||||
|
@ -318,18 +314,16 @@ class Rotation:
|
||||||
or not np.isclose(np.dot(om[2],om[0]), 0.0):
|
or not np.isclose(np.dot(om[2],om[0]), 0.0):
|
||||||
raise ValueError('matrix is not orthogonal.\n{}'.format(om))
|
raise ValueError('matrix is not orthogonal.\n{}'.format(om))
|
||||||
|
|
||||||
return cls(om2qu(om))
|
return Rotation(om2qu(om))
|
||||||
|
|
||||||
@classmethod
|
@staticmethod
|
||||||
def fromMatrix(cls,
|
def fromMatrix(om,
|
||||||
om,
|
|
||||||
):
|
):
|
||||||
|
|
||||||
return cls.fromBasis(om)
|
return Rotation.fromBasis(om)
|
||||||
|
|
||||||
@classmethod
|
@staticmethod
|
||||||
def fromRodrigues(cls,
|
def fromRodrigues(rodrigues,
|
||||||
rodrigues,
|
|
||||||
normalise = False,
|
normalise = False,
|
||||||
P = -1):
|
P = -1):
|
||||||
|
|
||||||
|
@ -342,35 +336,32 @@ class Rotation:
|
||||||
if ro[3] < 0.0:
|
if ro[3] < 0.0:
|
||||||
raise ValueError('Rodriques rotation angle not positive.\n'.format(ro[3]))
|
raise ValueError('Rodriques rotation angle not positive.\n'.format(ro[3]))
|
||||||
|
|
||||||
return cls(ro2qu(ro))
|
return Rotation(ro2qu(ro))
|
||||||
|
|
||||||
@classmethod
|
@staticmethod
|
||||||
def fromHomochoric(cls,
|
def fromHomochoric(homochoric,
|
||||||
homochoric,
|
P = -1):
|
||||||
P = -1):
|
|
||||||
|
|
||||||
ho = homochoric if isinstance(homochoric, np.ndarray) and homochoric.dtype == np.dtype(float) \
|
ho = homochoric if isinstance(homochoric, np.ndarray) and homochoric.dtype == np.dtype(float) \
|
||||||
else np.array(homochoric,dtype=float)
|
else np.array(homochoric,dtype=float)
|
||||||
if P > 0: ho *= -1 # convert from P=1 to P=-1
|
if P > 0: ho *= -1 # convert from P=1 to P=-1
|
||||||
|
|
||||||
return cls(ho2qu(ho))
|
return Rotation(ho2qu(ho))
|
||||||
|
|
||||||
@classmethod
|
@staticmethod
|
||||||
def fromCubochoric(cls,
|
def fromCubochoric(cubochoric,
|
||||||
cubochoric,
|
P = -1):
|
||||||
P = -1):
|
|
||||||
|
|
||||||
cu = cubochoric if isinstance(cubochoric, np.ndarray) and cubochoric.dtype == np.dtype(float) \
|
cu = cubochoric if isinstance(cubochoric, np.ndarray) and cubochoric.dtype == np.dtype(float) \
|
||||||
else np.array(cubochoric,dtype=float)
|
else np.array(cubochoric,dtype=float)
|
||||||
ho = cu2ho(cu)
|
ho = cu2ho(cu)
|
||||||
if P > 0: ho *= -1 # convert from P=1 to P=-1
|
if P > 0: ho *= -1 # convert from P=1 to P=-1
|
||||||
|
|
||||||
return cls(ho2qu(ho))
|
return Rotation(ho2qu(ho))
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@staticmethod
|
||||||
def fromAverage(cls,
|
def fromAverage(rotations,
|
||||||
rotations,
|
|
||||||
weights = []):
|
weights = []):
|
||||||
"""
|
"""
|
||||||
Average rotation.
|
Average rotation.
|
||||||
|
@ -400,11 +391,11 @@ class Rotation:
|
||||||
else M + r.asM() * n # noqa add (multiples) of this rotation to average noqa
|
else M + r.asM() * n # noqa add (multiples) of this rotation to average noqa
|
||||||
eig, vec = np.linalg.eig(M/N)
|
eig, vec = np.linalg.eig(M/N)
|
||||||
|
|
||||||
return cls.fromQuaternion(np.real(vec.T[eig.argmax()]),acceptHomomorph = True)
|
return Rotation.fromQuaternion(np.real(vec.T[eig.argmax()]),acceptHomomorph = True)
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@staticmethod
|
||||||
def fromRandom(cls):
|
def fromRandom():
|
||||||
r = np.random.random(3)
|
r = np.random.random(3)
|
||||||
A = np.sqrt(r[2])
|
A = np.sqrt(r[2])
|
||||||
B = np.sqrt(1.0-r[2])
|
B = np.sqrt(1.0-r[2])
|
||||||
|
@ -412,7 +403,7 @@ class Rotation:
|
||||||
x = np.sin(2.0*np.pi*r[1])*B
|
x = np.sin(2.0*np.pi*r[1])*B
|
||||||
y = np.cos(2.0*np.pi*r[1])*B
|
y = np.cos(2.0*np.pi*r[1])*B
|
||||||
z = np.sin(2.0*np.pi*r[0])*A
|
z = np.sin(2.0*np.pi*r[0])*A
|
||||||
return cls.fromQuaternion([w,x,y,z],acceptHomomorph=True)
|
return Rotation.fromQuaternion([w,x,y,z],acceptHomomorph=True)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1181,9 +1172,8 @@ class Orientation:
|
||||||
return color
|
return color
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@staticmethod
|
||||||
def fromAverage(cls,
|
def fromAverage(orientations,
|
||||||
orientations,
|
|
||||||
weights = []):
|
weights = []):
|
||||||
"""Create orientation from average of list of orientations."""
|
"""Create orientation from average of list of orientations."""
|
||||||
if not all(isinstance(item, Orientation) for item in orientations):
|
if not all(isinstance(item, Orientation) for item in orientations):
|
||||||
|
|
Loading…
Reference in New Issue