more user friendly constructors
This commit is contained in:
parent
ef3fc0b58a
commit
97ac437686
2
PRIVATE
2
PRIVATE
|
@ -1 +1 @@
|
|||
Subproject commit 25006bc974b752faf3464b082511590d50093c37
|
||||
Subproject commit 406d482f8059b4459634af729ce85491a9a3245c
|
|
@ -79,8 +79,8 @@ parser.add_option('-z',
|
|||
help = 'label of lab z vector (expressed in crystal coords)')
|
||||
|
||||
parser.set_defaults(output = [],
|
||||
labrotation = (0.,1.,1.,1.), # no rotation about 1,1,1
|
||||
crystalrotation = (0.,1.,1.,1.), # no rotation about 1,1,1
|
||||
labrotation = (0.,1.,0.,0.), # no rotation about 1,0,0
|
||||
crystalrotation = (0.,1.,0.,0.), # no rotation about 1,0,0
|
||||
degrees = False,
|
||||
)
|
||||
|
||||
|
@ -108,8 +108,8 @@ if np.sum(input) != 1: parser.error('needs exactly one input format.')
|
|||
(options.quaternion,4,'quaternion'),
|
||||
][np.where(input)[0][0]] # select input label that was requested
|
||||
|
||||
r = damask.Rotation.fromAngleAxis(np.array(options.crystalrotation),options.degrees) # crystal frame rotation
|
||||
R = damask.Rotation.fromAngleAxis(np.array(options.labrotation),options.degrees) # lab frame rotation
|
||||
r = damask.Rotation.fromAngleAxis(options.crystalrotation,options.degrees) # crystal frame rotation
|
||||
R = damask.Rotation.fromAngleAxis(options.labrotation,options.degrees) # lab frame rotation
|
||||
|
||||
# --- loop over input files ------------------------------------------------------------------------
|
||||
|
||||
|
@ -153,13 +153,13 @@ for name in filenames:
|
|||
outputAlive = True
|
||||
while outputAlive and table.data_read(): # read next data line of ASCII table
|
||||
if inputtype == 'eulers':
|
||||
o = damask.Rotation.fromEulers(np.array(list(map(float,table.data[column:column+3]))),options.degrees)
|
||||
o = damask.Rotation.fromEulers(list(map(float,table.data[column:column+3])),options.degrees)
|
||||
|
||||
elif inputtype == 'rodrigues':
|
||||
o = damask.Rotation.fromRodrigues(np.array(list(map(float,table.data[column:column+3]))))
|
||||
o = damask.Rotation.fromRodrigues(list(map(float,table.data[column:column+3])))
|
||||
|
||||
elif inputtype == 'matrix':
|
||||
o = damask.Rotation.fromMatrix(np.array(list(map(float,table.data[column:column+9]))).reshape(3,3))
|
||||
o = damask.Rotation.fromMatrix(list(map(float,table.data[column:column+9])).reshape(3,3))
|
||||
|
||||
elif inputtype == 'frame':
|
||||
M = np.array(list(map(float,table.data[column[0]:column[0]+3] + \
|
||||
|
@ -168,7 +168,7 @@ for name in filenames:
|
|||
o = damask.Rotation.fromMatrix(M/np.linalg.norm(M,axis=0))
|
||||
|
||||
elif inputtype == 'quaternion':
|
||||
o = damask.Rotation.fromQuaternion(np.array(list(map(float,table.data[column:column+4]))))
|
||||
o = damask.Rotation.fromQuaternion(list(map(float,table.data[column:column+4])))
|
||||
|
||||
o= r*o*R # apply additional lab and crystal frame rotations
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: UTF-8 no BOM -*-
|
||||
|
||||
import os,sys,math
|
||||
import os,sys
|
||||
import numpy as np
|
||||
from optparse import OptionParser
|
||||
import damask
|
||||
|
@ -29,9 +29,9 @@ parser.add_option('-r', '--rotation',
|
|||
parser.add_option('--degrees',
|
||||
dest = 'degrees',
|
||||
action = 'store_true',
|
||||
help = 'angles are given in degrees [%default]')
|
||||
help = 'angle is given in degrees [%default]')
|
||||
|
||||
parser.set_defaults(rotation = (0.,1.,1.,1.), # no rotation about 1,1,1
|
||||
parser.set_defaults(rotation = (0.,1.,0.,0.), # no rotation about 1,0,0
|
||||
degrees = False,
|
||||
)
|
||||
|
||||
|
@ -40,7 +40,7 @@ parser.set_defaults(rotation = (0.,1.,1.,1.),
|
|||
if options.data is None:
|
||||
parser.error('no data column specified.')
|
||||
|
||||
r = damask.Rotation.fromAngleAxis(options.rotation,degrees)
|
||||
r = damask.Rotation.fromAngleAxis(options.rotation,options.degrees,normalise=True)
|
||||
|
||||
# --- loop over input files -------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -63,9 +63,9 @@ parser.set_defaults(center = (.0,.0,.0),
|
|||
if options.dimension is None:
|
||||
parser.error('no dimension specified.')
|
||||
if options.angleaxis is not None:
|
||||
rotation = damask.Rotation.fromAngleAxis(np.array(options.angleaxis),options.degrees,normalise=True)
|
||||
rotation = damask.Rotation.fromAngleAxis(options.angleaxis,options.degrees,normalise=True)
|
||||
elif options.quaternion is not None:
|
||||
rotation = damask.Rotation.fromQuaternion(np.array(options.quaternion))
|
||||
rotation = damask.Rotation.fromQuaternion(options.quaternion)
|
||||
else:
|
||||
rotation = damask.Rotation()
|
||||
|
||||
|
|
|
@ -236,7 +236,12 @@ class Rotation:
|
|||
__slots__ = ['quaternion']
|
||||
|
||||
def __init__(self,quaternion = np.array([1.0,0.0,0.0,0.0])):
|
||||
"""Initializes to identity unless specified"""
|
||||
"""
|
||||
Initializes to identity unless specified
|
||||
|
||||
If a quaternion is given, it needs to comply with the convection. Use .fromQuaternion
|
||||
to check the input.
|
||||
"""
|
||||
self.quaternion = Quaternion2(q=quaternion[0],p=quaternion[1:4])
|
||||
self.quaternion.homomorph() # ToDo: Needed?
|
||||
|
||||
|
@ -248,6 +253,8 @@ class Rotation:
|
|||
'Bunge Eulers / deg: {}'.format('\t'.join(list(map(str,self.asEulers(degrees=True)))) ),
|
||||
])
|
||||
|
||||
################################################################################################
|
||||
# convert to different orientation representations (numpy arrays)
|
||||
|
||||
def asQuaternion(self):
|
||||
return self.quaternion.asArray()
|
||||
|
@ -277,13 +284,15 @@ class Rotation:
|
|||
return qu2cu(self.quaternion.asArray())
|
||||
|
||||
|
||||
|
||||
################################################################################################
|
||||
# static constructors. The input data needs to follow the convention, options allow to
|
||||
# relax these convections
|
||||
@classmethod
|
||||
def fromQuaternion(cls,
|
||||
quaternion,
|
||||
P = -1):
|
||||
|
||||
qu = quaternion
|
||||
qu = quaternion if isinstance(quaternion, np.ndarray) else np.array(quaternion)
|
||||
if P > 0: qu[1:4] *= -1 # convert from P=1 to P=-1
|
||||
if qu[0] < 0.0:
|
||||
raise ValueError('Quaternion has negative first component.\n{}'.format(qu[0]))
|
||||
|
@ -297,7 +306,8 @@ class Rotation:
|
|||
eulers,
|
||||
degrees = False):
|
||||
|
||||
eu = np.radians(eulers) if degrees else eulers
|
||||
eu = eulers if isinstance(eulers, np.ndarray) else np.array(eulers)
|
||||
eu = np.radians(eu) if degrees else eu
|
||||
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))
|
||||
|
||||
|
@ -310,7 +320,7 @@ class Rotation:
|
|||
normalise = False,
|
||||
P = -1):
|
||||
|
||||
ax = angleAxis
|
||||
ax = angleAxis if isinstance(angleAxis, np.ndarray) else np.array(angleAxis)
|
||||
if P > 0: ax[1:4] *= -1 # convert from P=1 to P=-1
|
||||
if degrees: ax[0] = np.degrees(ax[0])
|
||||
if normalise: ax[1:4] /=np.linalg.norm(ax[1:4])
|
||||
|
@ -323,9 +333,13 @@ class Rotation:
|
|||
|
||||
@classmethod
|
||||
def fromMatrix(cls,
|
||||
matrix):
|
||||
matrix,
|
||||
containsStretch = False): #ToDo: better name?
|
||||
|
||||
om = matrix
|
||||
om = matrix if isinstance(matrix, np.ndarray) else np.array(matrix)
|
||||
if containsStretch:
|
||||
(U,S,Vh) = np.linalg.svd(om) # singular value decomposition
|
||||
om = np.dot(U,Vh)
|
||||
if not np.isclose(np.linalg.det(om),1.0):
|
||||
raise ValueError('matrix is not a proper rotation.\n{}'.format(om))
|
||||
if not np.isclose(np.dot(om[0],om[1]), 0.0) \
|
||||
|
@ -341,7 +355,7 @@ class Rotation:
|
|||
normalise = False,
|
||||
P = -1):
|
||||
|
||||
ro = rodrigues
|
||||
ro = rodrigues if isinstance(rodrigues, np.ndarray) else np.array(rodrigues)
|
||||
if P > 0: ro[1:4] *= -1 # convert from P=1 to P=-1
|
||||
if normalise: ro[1:4] /=np.linalg.norm(ro[1:4])
|
||||
if not np.isclose(np.linalg.norm(ro[1:4]), 1.0):
|
||||
|
@ -356,7 +370,7 @@ class Rotation:
|
|||
"""
|
||||
Multiplication
|
||||
|
||||
Rotation: Details needed (active/passive), more cases (3,3), (3,3,3,3) need to be considered
|
||||
Rotation: Details needed (active/passive), more rotation of (3,3,3,3) should be considered
|
||||
"""
|
||||
if isinstance(other, Rotation): # rotate a rotation
|
||||
return self.__class__((self.quaternion * other.quaternion).asArray())
|
||||
|
|
Loading…
Reference in New Issue