From 94839960b9074bff28f59e0d02fe1d53030865b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ne=C4=8Dada?= Date: Mon, 25 Feb 2019 11:45:46 +0200 Subject: [PATCH] Additional functionality and checks to qpms.irot3 and qpms.cquat. Former-commit-id: 46b74df1c507ddf876f036ac5e8b09dedcd19c42 --- qpms/qpms_c.pyx | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/qpms/qpms_c.pyx b/qpms/qpms_c.pyx index 3499ceb..c117a12 100644 --- a/qpms/qpms_c.pyx +++ b/qpms/qpms_c.pyx @@ -654,6 +654,11 @@ cdef class cquat: p.ck = z self.q = qpms_quat_2c_from_4d(p) + def copy(self): + res = cquat(0,0,0,0) + res.q = self.q + return res + def __repr__(self): # TODO make this look like a quaternion with i,j,k return repr(self.r) @@ -707,6 +712,12 @@ cdef class cquat: res.q = qpms_quat_normalise(self.q) return res + def isclose(cquat self, cquat other, rtol=1e-5, atol=1e-8): + ''' + Checks whether two quaternions are "almost equal". + ''' + return abs(self - other) <= (atol + rtol * abs(other)) + property c: ''' Quaternion representation as two complex numbers @@ -754,12 +765,22 @@ cdef class irot3: ''' cdef qpms_irot3_t qd - def __cinit__(self, cquat q, short det): # TODO implement a constructor with no arguments + def __cinit__(self, cquat q, short det): + # TODO implement a constructor with + # - no arguments (returns identity) + # - irot3 as argument (makes a copy) + # - cquat as argument (returns a corresponding proper rotation) + # - tuple as argument ...? if (det != 1 and det != -1): raise ValueError("Improper rotation determinant has to be 1 or -1") self.qd.rot = q.normalise().q self.qd.det = det + def copy(self): + res = irot3(cquat(1,0,0,0),1) + res.qd = self.qd + return res + property rot: ''' The proper rotation part of the irot3 type. @@ -798,10 +819,22 @@ cdef class irot3: res.qd = qpms_irot3_mult(self.qd, other.qd) return res - def __pow__(irot3 self, int n, _): + def __pow__(irot3 self, n, _): + cdef int nint + if (n % 1 == 0): + nint = n + else: + raise ValueError("The exponent of an irot3 has to have an integer value.") res = irot3(cquat(1,0,0,0), 1) res.qd = qpms_irot3_pow(self.qd, n) return res - + def isclose(irot3 self, irot3 other, rtol=1e-5, atol=1e-8): + ''' + Checks whether two (improper) rotations are "almost equal". + Returns always False if the determinants are different. + ''' + if self.det != other.det: + return False + return self.rot.isclose(other.rot, rtol=rtol, atol=atol)