corrected conversion of quaternion to AxisAngle and Euler angles.
This commit is contained in:
parent
35f9e91e73
commit
3d86c9b363
|
@ -297,9 +297,14 @@ class Quaternion:
|
||||||
def asAngleAxis(self):
|
def asAngleAxis(self):
|
||||||
if self.w > 1:
|
if self.w > 1:
|
||||||
self.normalize()
|
self.normalize()
|
||||||
angle = 2 * math.acos(self.w)
|
|
||||||
s = math.sqrt(1 - self.w ** 2)
|
s = math.sqrt(1. - self.w**2)
|
||||||
if s < 0.001:
|
x = 2*self.w**2 - 1.
|
||||||
|
y = 2*self.w * s
|
||||||
|
|
||||||
|
angle = math.atan2(y,x)
|
||||||
|
|
||||||
|
if angle < 1e-3:
|
||||||
return angle, numpy.array([1.0, 0.0, 0.0])
|
return angle, numpy.array([1.0, 0.0, 0.0])
|
||||||
else:
|
else:
|
||||||
return angle, numpy.array([self.x / s, self.y / s, self.z / s])
|
return angle, numpy.array([self.x / s, self.y / s, self.z / s])
|
||||||
|
@ -311,22 +316,49 @@ class Quaternion:
|
||||||
return numpy.array([float('inf')]*3)
|
return numpy.array([float('inf')]*3)
|
||||||
|
|
||||||
def asEulers(self,type='bunge'):
|
def asEulers(self,type='bunge'):
|
||||||
|
'''
|
||||||
|
conversion taken from:
|
||||||
|
Melcher, A.; Unser, A.; Reichhardt, M.; Nestler, B.; Pötschke, M.; Selzer, M.
|
||||||
|
Conversion of EBSD data by a quaternion based algorithm to be used for grain structure simulations
|
||||||
|
Technische Mechanik 30 (2010) pp 401--413
|
||||||
|
'''
|
||||||
angles = [0.0,0.0,0.0]
|
angles = [0.0,0.0,0.0]
|
||||||
if type.lower() == 'bunge' or type.lower() == 'zxz':
|
|
||||||
angles[0] = math.atan2( self.x*self.z+self.y*self.w,
|
|
||||||
-self.y*self.z+self.x*self.w)
|
|
||||||
# angles[1] = math.acos(-self.x**2-self.y**2+self.z**2+self.w**2)
|
|
||||||
angles[1] = math.acos(1.0 - 2*(self.x**2+self.y**2))
|
|
||||||
angles[2] = math.atan2( self.x*self.z-self.y*self.w,
|
|
||||||
+self.y*self.z+self.x*self.w)
|
|
||||||
|
|
||||||
if angles[0] < 0.0:
|
if type.lower() == 'bunge' or type.lower() == 'zxz':
|
||||||
angles[0] += 2*math.pi
|
if abs(self.x - self.y) < 1e-8:
|
||||||
if angles[1] < 0.0:
|
print 'q.x approx q.y !!'
|
||||||
angles[1] += math.pi
|
x = self.w**2 - self.z**2
|
||||||
angles[2] *= -1
|
y = 2.*self.w*self.z
|
||||||
if angles[2] < 0.0:
|
angles[0] = math.atan2(y,x)
|
||||||
angles[2] += 2*math.pi
|
elif abs(self.w - self.z) < 1e-8:
|
||||||
|
print 'q.w approx q.z !!'
|
||||||
|
x = self.x**2 - self.y**2
|
||||||
|
y = 2.*self.x*self.y
|
||||||
|
angles[0] = math.atan2(y,x)
|
||||||
|
angles[1] = math.pi
|
||||||
|
else:
|
||||||
|
chi = math.sqrt((self.w**2 + self.z**2)*(self.x**2 + self.y**2))
|
||||||
|
|
||||||
|
x = (self.w * self.x - self.y * self.z)/2./chi
|
||||||
|
y = (self.w * self.y + self.x * self.z)/2./chi
|
||||||
|
angles[0] = math.atan2(y,x)
|
||||||
|
|
||||||
|
x = self.w**2 + self.z**2 - (self.x**2 + self.y**2)
|
||||||
|
y = 2.*chi
|
||||||
|
angles[1] = math.atan2(y,x)
|
||||||
|
|
||||||
|
x = (self.w * self.x + self.y * self.z)/2./chi
|
||||||
|
y = (self.z * self.x - self.y * self.w)/2./chi
|
||||||
|
angles[2] = math.atan2(y,x)
|
||||||
|
|
||||||
|
# if angles[0] < 0.0:
|
||||||
|
# angles[0] += 2*math.pi
|
||||||
|
# if angles[1] < 0.0:
|
||||||
|
# angles[1] += math.pi
|
||||||
|
# angles[2] *= -1
|
||||||
|
# if angles[2] < 0.0:
|
||||||
|
# angles[2] += 2*math.pi
|
||||||
|
|
||||||
return angles
|
return angles
|
||||||
|
|
||||||
|
|
||||||
|
@ -740,13 +772,13 @@ class Orientation:
|
||||||
return 'Symmetry: %s\n' % (self.symmetry) + \
|
return 'Symmetry: %s\n' % (self.symmetry) + \
|
||||||
'Quaternion: %s\n' % (self.quaternion) + \
|
'Quaternion: %s\n' % (self.quaternion) + \
|
||||||
'Matrix:\n%s\n' % ( '\n'.join(['\t'.join(map(str,self.asMatrix()[i,:])) for i in range(3)]) ) + \
|
'Matrix:\n%s\n' % ( '\n'.join(['\t'.join(map(str,self.asMatrix()[i,:])) for i in range(3)]) ) + \
|
||||||
'Bunge Eulers: %s' % ('\t'.join(map(lambda x:str(numpy.degrees(x)),self.asEulers('Bunge'))) )
|
'Bunge Eulers / deg: %s' % ('\t'.join(map(lambda x:str(numpy.degrees(x)),self.asEulers('bunge'))) )
|
||||||
|
|
||||||
def asQuaternion(self):
|
def asQuaternion(self):
|
||||||
return self.quaternion.asList()
|
return self.quaternion.asList()
|
||||||
|
|
||||||
|
|
||||||
def asEulers(self,type):
|
def asEulers(self,type='bunge'):
|
||||||
return self.quaternion.asEulers(type)
|
return self.quaternion.asEulers(type)
|
||||||
|
|
||||||
|
|
||||||
|
@ -781,10 +813,11 @@ class Orientation:
|
||||||
for me in self.symmetry.equivalentQuaternions(self.quaternion):
|
for me in self.symmetry.equivalentQuaternions(self.quaternion):
|
||||||
me.conjugate()
|
me.conjugate()
|
||||||
for they in other.symmetry.equivalentQuaternions(other.quaternion):
|
for they in other.symmetry.equivalentQuaternions(other.quaternion):
|
||||||
theQ = me * they
|
# theQ = me * they
|
||||||
|
theQ = they * me
|
||||||
# if theQ.x < 0.0 or theQ.y < 0.0 or theQ.z < 0.0: theQ.conjugate() # speed up scanning since minimum angle is usually found for positive x,y,z
|
# if theQ.x < 0.0 or theQ.y < 0.0 or theQ.z < 0.0: theQ.conjugate() # speed up scanning since minimum angle is usually found for positive x,y,z
|
||||||
breaker = lowerSymmetry.inDisorientationSST(theQ.asRodrigues()) \
|
breaker = lowerSymmetry.inDisorientationSST(theQ.asRodrigues()) #\
|
||||||
or lowerSymmetry.inDisorientationSST(theQ.conjugated().asRodrigues())
|
# or lowerSymmetry.inDisorientationSST(theQ.conjugated().asRodrigues())
|
||||||
if breaker: break
|
if breaker: break
|
||||||
if breaker: break
|
if breaker: break
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue