fix syntax error regarding several static method

This commit is contained in:
Chen Zhang 2015-08-10 21:08:00 +00:00
parent bceeb0964c
commit 3991813595
1 changed files with 52 additions and 26 deletions

View File

@ -14,9 +14,16 @@
# orientation class, mainly for speed improvement. # # orientation class, mainly for speed improvement. #
###################################################### ######################################################
"""
NOTE
----
The static method in Cython is different from Python, need more
time to figure out details.
"""
import math, random, os import math, random, os
import numpy as np import numpy as np
#cimport numpy as np cimport numpy as np
## ##
@ -67,7 +74,14 @@ cdef class Quaternion:
cdef public double w,x,y,z cdef public double w,x,y,z
def __init__(self, data): def __init__(self, data):
""" copy constructor friendly """ """
@description
------------
copy constructor friendly
@parameters
-----------
data: array
"""
cdef double[4] q cdef double[4] q
if isinstance(data, Quaternion): if isinstance(data, Quaternion):
@ -85,7 +99,12 @@ cdef class Quaternion:
cdef Quaternion(self, double* quatArray): cdef Quaternion(self, double* quatArray):
""" """
@para: quatArray = <w, x, y, z> @description
------------
internal constructor for Quaternion
@parameters
-----------
quatArray: double[4] // <w, x, y, z>
w is the real part, (x, y, z) are the imaginary parts w is the real part, (x, y, z) are the imaginary parts
""" """
if quatArray[0] < 0: if quatArray[0] < 0:
@ -448,16 +467,16 @@ cdef class Quaternion:
return Quaternion(q) return Quaternion(q)
@staticmethod @staticmethod
def fromRodrigues(cls, rodrigues): def fromRodrigues(rodrigues):
if not isinstance(rodrigues, np.ndarray): rodrigues = np.array(rodrigues) if not isinstance(rodrigues, np.ndarray): rodrigues = np.array(rodrigues)
halfangle = math.atan(np.linalg.norm(rodrigues)) halfangle = math.atan(np.linalg.norm(rodrigues))
c = math.cos(halfangle) c = math.cos(halfangle)
w = c w = c
x,y,z = c*rodrigues x,y,z = c*rodrigues
return cls([w,x,y,z]) return Quaternion([w,x,y,z])
@staticmethod @staticmethod
def fromAngleAxis(cls, angle, axis): def fromAngleAxis(angle, axis):
if not isinstance(axis, np.ndarray): axis = np.array(axis) if not isinstance(axis, np.ndarray): axis = np.array(axis)
axis /= np.linalg.norm(axis) axis /= np.linalg.norm(axis)
s = math.sin(angle / 2.0) s = math.sin(angle / 2.0)
@ -465,21 +484,25 @@ cdef class Quaternion:
x = axis[0] * s x = axis[0] * s
y = axis[1] * s y = axis[1] * s
z = axis[2] * s z = axis[2] * s
return cls([w,x,y,z]) return Quaternion([w,x,y,z])
@staticmethod @staticmethod
def fromEulers(cls, eulers, type = 'Bunge'): def fromEulers(eulers, type = 'Bunge'):
cdef double c1,s1,c2,s2,c3,s3 cdef double c1,s1,c2,s2,c3,s3
cdef double[4] q cdef double[4] q
cdef double[3] halfEulers
cdef int i
eulers *= 0.5 # reduce to half angles for i in range(3):
halfEulers[i] = eulers[i] * 0.5 # reduce to half angles
c1 = math.cos(eulers[0])
s1 = math.sin(eulers[0]) c1 = math.cos(halfEulers[0])
c2 = math.cos(eulers[1]) s1 = math.sin(halfEulers[0])
s2 = math.sin(eulers[1]) c2 = math.cos(halfEulers[1])
c3 = math.cos(eulers[2]) s2 = math.sin(halfEulers[1])
s3 = math.sin(eulers[2]) c3 = math.cos(halfEulers[2])
s3 = math.sin(halfEulers[2])
if type.lower() == 'bunge' or type.lower() == 'zxz': if type.lower() == 'bunge' or type.lower() == 'zxz':
q[0] = c1 * c2 * c3 - s1 * c2 * s3 q[0] = c1 * c2 * c3 - s1 * c2 * s3
@ -496,7 +519,7 @@ cdef class Quaternion:
## Modified Method to calculate Quaternion from Orientation Matrix, Source: http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/ ## Modified Method to calculate Quaternion from Orientation Matrix, Source: http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/
@staticmethod @staticmethod
def fromMatrix(cls, m): def fromMatrix(m):
# This is a slow implementation # This is a slow implementation
if m.shape != (3,3) and np.prod(m.shape) == 9: if m.shape != (3,3) and np.prod(m.shape) == 9:
m = m.reshape(3,3) m = m.reshape(3,3)
@ -516,7 +539,7 @@ cdef class Quaternion:
t = m[0,0] - m[1,1] - m[2,2] + 1.0 t = m[0,0] - m[1,1] - m[2,2] + 1.0
s = 2.0*math.sqrt(t) s = 2.0*math.sqrt(t)
return cls( return Quaternion(
[ (m[2,1] - m[1,2])/s, [ (m[2,1] - m[1,2])/s,
s*0.25, s*0.25,
(m[0,1] + m[1,0])/s, (m[0,1] + m[1,0])/s,
@ -527,7 +550,7 @@ cdef class Quaternion:
t = -m[0,0] + m[1,1] - m[2,2] + 1.0 t = -m[0,0] + m[1,1] - m[2,2] + 1.0
s = 2.0*math.sqrt(t) s = 2.0*math.sqrt(t)
return cls( return Quaternion(
[ (m[0,2] - m[2,0])/s, [ (m[0,2] - m[2,0])/s,
(m[0,1] + m[1,0])/s, (m[0,1] + m[1,0])/s,
s*0.25, s*0.25,
@ -538,7 +561,7 @@ cdef class Quaternion:
t = -m[0,0] - m[1,1] + m[2,2] + 1.0 t = -m[0,0] - m[1,1] + m[2,2] + 1.0
s = 2.0*math.sqrt(t) s = 2.0*math.sqrt(t)
return cls( return Quaternion(
[ (m[1,0] - m[0,1])/s, [ (m[1,0] - m[0,1])/s,
(m[2,0] + m[0,2])/s, (m[2,0] + m[0,2])/s,
(m[1,2] + m[2,1])/s, (m[1,2] + m[2,1])/s,
@ -546,7 +569,7 @@ cdef class Quaternion:
]) ])
@staticmethod @staticmethod
def new_interpolate(cls, q1, q2, t): def new_interpolate(q1, q2, t):
# see http://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/20070017872_2007014421.pdf for (another?) way to interpolate quaternions # see http://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/20070017872_2007014421.pdf for (another?) way to interpolate quaternions
assert isinstance(q1, Quaternion) and isinstance(q2, Quaternion) assert isinstance(q1, Quaternion) and isinstance(q2, Quaternion)
@ -835,7 +858,7 @@ cdef class Orientation:
matrix = None, matrix = None,
Eulers = None, Eulers = None,
random = False, # put any integer to have a fixed seed or True for real random random = False, # put any integer to have a fixed seed or True for real random
symmetry = None, symmetry = None
): ):
if random: # produce random orientation if random: # produce random orientation
if isinstance(random, bool ): if isinstance(random, bool ):
@ -843,7 +866,7 @@ cdef class Orientation:
else: else:
self.quaternion = Quaternion.fromRandom(randomSeed=random) self.quaternion = Quaternion.fromRandom(randomSeed=random)
elif isinstance(Eulers, np.ndarray) and Eulers.shape == (3,): # based on given Euler angles elif isinstance(Eulers, np.ndarray) and Eulers.shape == (3,): # based on given Euler angles
self.quaternion = Quaternion.fromEulers(Eulers,'bunge') self.quaternion = Quaternion.fromEulers(Eulers, type='bunge')
elif isinstance(matrix, np.ndarray) : # based on given rotation matrix elif isinstance(matrix, np.ndarray) : # based on given rotation matrix
self.quaternion = Quaternion.fromMatrix(matrix) self.quaternion = Quaternion.fromMatrix(matrix)
elif isinstance(angleAxis, np.ndarray) and angleAxis.shape == (4,): # based on given angle and rotation axis elif isinstance(angleAxis, np.ndarray) and angleAxis.shape == (4,): # based on given angle and rotation axis
@ -946,7 +969,7 @@ cdef class Orientation:
return color return color
@staticmethod @staticmethod
def getAverageOrientation(cls, orientationList): def getAverageOrientation(orientationList):
""" """
RETURN THE AVERAGE ORIENTATION RETURN THE AVERAGE ORIENTATION
ref: F. Landis Markley, Yang Cheng, John Lucas Crassidis, and Yaakov Oshman. ref: F. Landis Markley, Yang Cheng, John Lucas Crassidis, and Yaakov Oshman.
@ -957,6 +980,9 @@ cdef class Orientation:
a = Orientation(Eulers=np.radians([10, 10, 0]), symmetry=3) a = Orientation(Eulers=np.radians([10, 10, 0]), symmetry=3)
b = Orientation(Eulers=np.radians([20, 0, 0]), symmetry=3) b = Orientation(Eulers=np.radians([20, 0, 0]), symmetry=3)
avg = Orientation.getAverageOrientation([a,b]) avg = Orientation.getAverageOrientation([a,b])
NOTE
----
No symmetry information is available for the average orientation.
""" """
if not all(isinstance(item, Orientation) for item in orientationList): if not all(isinstance(item, Orientation) for item in orientationList):
@ -968,7 +994,7 @@ cdef class Orientation:
M += o.quaternion.asM() M += o.quaternion.asM()
eig, vec = np.linalg.eig(M/N) eig, vec = np.linalg.eig(M/N)
return Orientation(quaternion = Quaternion(quatArray = vec.T[eig.argmax()])) return Orientation(quaternion = Quaternion(vec.T[eig.argmax()]))
def related(self, relationModel, direction, targetSymmetry = None): def related(self, relationModel, direction, targetSymmetry = None):