removed Rodrigues class; removed quaternion "inverse" method; adopted Rowenhorst algorithm for angle--axis; use math.isclose(...,0.0) to check for ==0.0

This commit is contained in:
Philip Eisenlohr 2018-12-17 09:55:02 -05:00
parent 1f2fbbee21
commit e82d3557d1
2 changed files with 24 additions and 59 deletions

View File

@ -13,7 +13,7 @@ from .asciitable import ASCIItable # noqa
from .config import Material # noqa from .config import Material # noqa
from .colormaps import Colormap, Color # noqa from .colormaps import Colormap, Color # noqa
from .orientation import Quaternion, Rodrigues, Symmetry, Orientation # noqa from .orientation import Quaternion, Symmetry, Orientation # noqa
#from .block import Block # only one class #from .block import Block # only one class
from .result import Result # noqa from .result import Result # noqa

View File

@ -7,24 +7,6 @@
import math,os import math,os
import numpy as np import numpy as np
# ******************************************************************************************
class Rodrigues:
def __init__(self, vector = np.zeros(3)):
self.vector = vector
def asQuaternion(self):
norm = np.linalg.norm(self.vector)
halfAngle = np.arctan(norm)
return Quaternion(np.cos(halfAngle),np.sin(halfAngle)*self.vector/norm)
def asAngleAxis(self):
norm = np.linalg.norm(self.vector)
halfAngle = np.arctan(norm)
return (2.0*halfAngle,self.vector/norm)
# ****************************************************************************************** # ******************************************************************************************
class Quaternion: class Quaternion:
u""" u"""
@ -178,12 +160,13 @@ class Quaternion:
magnitude = __abs__ magnitude = __abs__
def __eq__(self,other): def __eq__(self,other):
"""Equal at e-8 precision""" """Equal (sufficiently close) to each other"""
return (self-other).magnitude() < 1e-8 or (-self-other).magnitude() < 1e-8 return math.isclose(( self-other).magnitude(),0.0) \
or math.isclose((-self-other).magnitude(),0.0)
def __ne__(self,other): def __ne__(self,other):
"""Not equal at e-8 precision""" """Not equal (sufficiently close) to each other"""
return not self.__eq__(self,other) return not self.__eq__(other)
def __cmp__(self,other): def __cmp__(self,other):
"""Linear ordering""" """Linear ordering"""
@ -193,11 +176,6 @@ class Quaternion:
def magnitude_squared(self): def magnitude_squared(self):
return self.q ** 2 + np.dot(self.p,self.p) return self.q ** 2 + np.dot(self.p,self.p)
def identity(self):
self.q = 1.
self.p = np.zeros(3,dtype=float)
return self
def normalize(self): def normalize(self):
d = self.magnitude() d = self.magnitude()
if d > 0.0: if d > 0.0:
@ -209,13 +187,6 @@ class Quaternion:
self.p = -self.p self.p = -self.p
return self return self
def inverse(self):
d = self.magnitude()
if d > 0.0:
self.conjugate()
self /= d
return self
def homomorph(self): def homomorph(self):
if self.q < 0.0: if self.q < 0.0:
self.q = -self.q self.q = -self.q
@ -228,9 +199,6 @@ class Quaternion:
def conjugated(self): def conjugated(self):
return self.copy().conjugate() return self.copy().conjugate()
def inversed(self):
return self.copy().inverse()
def homomorphed(self): def homomorphed(self):
return self.copy().homomorph() return self.copy().homomorph()
@ -259,27 +227,24 @@ class Quaternion:
def asAngleAxis(self, def asAngleAxis(self,
degrees = False, degrees = False,
flat = False): flat = False):
if self.q > 1.:
self.normalize()
s = math.sqrt(1. - self.q**2) angle = 2.0*math.acos(self.q)
x = 2.*self.q**2 - 1.
y = 2.*self.q * s
angle = math.atan2(y,x) if math.isclose(angle,0.0):
if angle < 0.0: angle = 0.0
angle *= -1. axis = np.array([0.0,0.0,1.0])
s *= -1. elif math.isclose(self.q,0.0):
angle = math.pi
if flat: axis = self.p
return np.hstack((np.degrees(angle) if degrees else angle,
np.array([1.0, 0.0, 0.0] if np.abs(angle) < 1e-6 else self.p / s)))
else: else:
return (np.degrees(angle) if degrees else angle, axis = np.sign(self.q)*self.p/np.linalg.norm(self.p)
np.array([1.0, 0.0, 0.0] if np.abs(angle) < 1e-6 else self.p / s))
angle = np.degrees(angle) if degrees else angle
return np.hstack((angle,axis)) if flat else (angle,axis)
def asRodrigues(self): def asRodrigues(self):
return np.inf*np.ones(3) if self.q == 0.0 else self.p/self.q return np.inf*np.ones(3) if math.isclose(self.q,0.0) else self.p/self.q
def asEulers(self, def asEulers(self,
degrees = False): degrees = False):
@ -290,9 +255,9 @@ class Quaternion:
q12 = self.p[0]**2 + self.p[1]**2 q12 = self.p[0]**2 + self.p[1]**2
chi = np.sqrt(q03*q12) chi = np.sqrt(q03*q12)
if abs(chi) < 1e-10 and abs(q12) < 1e-10: if math.isclose(chi,0.0) and math.isclose(q12,0.0):
eulers = np.array([math.atan2(-2*P*self.q*self.p[2],self.q**2-self.p[2]**2),0,0]) eulers = np.array([math.atan2(-2*P*self.q*self.p[2],self.q**2-self.p[2]**2),0,0])
elif abs(chi) < 1e-10 and abs(q03) < 1e-10: elif math.isclose(chi,0.0) and math.isclose(q03,0.0):
eulers = np.array([math.atan2( 2 *self.p[0]*self.p[1],self.p[0]**2-self.p[1]**2),np.pi,0]) eulers = np.array([math.atan2( 2 *self.p[0]*self.p[1],self.p[0]**2-self.p[1]**2),np.pi,0])
else: else:
eulers = np.array([math.atan2((self.p[0]*self.p[2]-P*self.q*self.p[1])/chi,(-P*self.q*self.p[0]-self.p[1]*self.p[2])/chi), eulers = np.array([math.atan2((self.p[0]*self.p[2]-P*self.q*self.p[1])/chi,(-P*self.q*self.p[0]-self.p[1]*self.p[2])/chi),
@ -456,11 +421,11 @@ class Symmetry:
def __eq__(self, other): def __eq__(self, other):
"""Equal""" """Equal to other"""
return self.lattice == other.lattice return self.lattice == other.lattice
def __neq__(self, other): def __neq__(self, other):
"""Not equal""" """Not equal to other"""
return not self.__eq__(other) return not self.__eq__(other)
def __cmp__(self,other): def __cmp__(self,other):
@ -549,7 +514,7 @@ class Symmetry:
def inFZ(self,R): def inFZ(self,R):
"""Check whether given Rodrigues vector falls into fundamental zone of own symmetry.""" """Check whether given Rodrigues vector falls into fundamental zone of own symmetry."""
if isinstance(R, Quaternion): R = R.asRodrigues() # translate accidentially passed quaternion if isinstance(R, Quaternion): R = R.asRodrigues() # translate accidentally passed quaternion
# fundamental zone in Rodrigues space is point symmetric around origin # fundamental zone in Rodrigues space is point symmetric around origin
R = abs(R) R = abs(R)
if self.lattice == 'cubic': if self.lattice == 'cubic':