def setUp(self): unittest.TestCase.setUp(self) self.u = vectors.Vector3D(1, 2, 3) self.v = vectors.Vector3D([4, 5, 6]) self.w = vectors.Vector3D(1, 0, 0) self.a = vectors.Vector3D(-1, -2, 3)
def axisangle_to_quaternion(*data): """ Convert an axis angle :math:`(\\phi, \\vec{n})` to a quaternion. **Parameters** * ``len(data) == 2``: :math:`(\\phi, \\vec{n})` * ``len(data) == 4``: :math:`(\\phi, n_x, n_y, n_z)` **Equations** * :math:`a = \\cos{\\frac{\\phi}{2}}` * :math:`A_x = n_x \\sin{\\frac{\\phi}{2}}` * :math:`A_y = n_y \\sin{\\frac{\\phi}{2}}` * :math:`A_z = n_z \\sin{\\frac{\\phi}{2}}` **References** Martin Baker (2008) Euclidean Space, http://www.euclideansplace.com :rtype: :class:`quaternions.Quaternion` """ if len(data) == 2: n = vectors.Vector3D(data[1][0], data[1][1], data[1][2]) elif len(data) == 4: n = vectors.Vector3D(data[1], data[2], data[3]) n.normalize() multiplier = sin(0.5 * data[0]) return Quaternion(cos(0.5 * data[0]), n[0] * multiplier, n[1] * multiplier, n[2] * multiplier)
def testalmostequal(self): u = vectors.Vector3D(1, 2, 5) self.assertFalse(vectors.almostequal(self.u, u)) u = vectors.Vector3D(1, 2, 3.00000001) self.assertTrue(vectors.almostequal(self.u, u)) self.assertTrue(vectors.almostequal(u, self.u)) self.assertFalse(vectors.almostequal(self.u, self.x))
def test__mul__(self): if numpy is not None: m1np = numpy.array(self.m1.to_list()) m2np = numpy.array(self.m2.to_list()) # Matrix multiplication mm = self.m1 * self.m2 mmnp = numpy.dot(m1np, m2np) for i in range(3): for j in range(3): self.assertAlmostEqual(mm[i][j], mmnp[i][j]) # Scalar multiplication mm = self.m1 * 4 mmnp = m1np * 4 for i in range(3): for j in range(3): self.assertAlmostEqual(mm[i][j], mmnp[i][j]) # Vector multiplication v1 = vectors.Vector3D(1, 1, 1) v1np = numpy.array([1, 1, 1]) vv = self.m1 * v1 vvnp = numpy.dot(m1np, v1np) for i in range(3): self.assertAlmostEqual(vv[i], vvnp[i])
def testfacepole_goniometricangles(self): # Example 2.20 facepole = vectors.Vector3D(1, 1, 1) phi, rho = calculations.facepole_goniometricangles(facepole, self.L2) phi *= 180 / pi rho *= 180 / pi self.assertAlmostEqual(phi, 62.03, 2) self.assertAlmostEqual(rho, 69.89, 2)
def testzoneaxis_goniometricangles(self): # Example 2.20 zoneaxis = vectors.Vector3D(0, 1, 0) phi, rho = calculations.zoneaxis_goniometricangles(zoneaxis, self.L2) phi *= 180 / pi rho *= 180 / pi self.assertAlmostEqual(phi, -2.919, 2) self.assertAlmostEqual(rho, 93.11, 2)
def __mul__(self, other): """ Multiply * two matrices * one matrix and a scalar. * one matrix and a :class:`vectors.Vector3D` Multiplication of matrices is not commutative (:math:`\\mathrm{A}\\mathrm{B} \\neq \\mathrm{B}\\mathrm{A}`) :rtype: :class:`matrices.Matrix3D` """ # Matrix times matrix if isinstance(self, Matrix3D) and isinstance(other, Matrix3D): # Check type to set correct object for the output. if type(self) != type(other): m = Matrix3D() else: m = copy.deepcopy(self) m.clear() for i in range(3): for j in range(3): for k in range(3): m[i][j] += self._m[i][k] * other._m[k][j] return m # Matrix times Vector elif isinstance(other, vectors.Vector3D): v = vectors.Vector3D(0.0, 0.0, 0.0) for i in range(3): for j in range(3): v[i] += self._m[i][j] * other[j] return v # Matrix * scalar elif isinstance(other, int) or isinstance(other, float): # Check type to set correct object for the output. # Only a multiplication by one can keep the type of the objet intact. if other == 1.0: return self else: m = Matrix3D() for i in range(3): for j in range(3): m[i][j] = other * self._m[i][j] return m # Incorrect arguments else: raise TypeError, "Incorrect multiplier type"
def __init__(self, *data): """ By definition, a Quaternion is a real scalar number (:math:`a`) and a vector (:math:`\\vec{A}`): :math:`\\mathcal{A} = \\llbracket a, \\vec{A} \\rrbracket`. **Parameters** ============= =============== ================== ``len(data)`` data Description ============= =============== ================== 0 [0,0,0,0] Null Quaternion 1 [a,0,0,0] Real Quaternion 2 [a, A] Quaternion 3 [0, Ax, Ay, Az] Pure Quaternion 4 [a, Ax, Ay, Az] Quaternion ============= =============== ================== **References** Altmann, Simon (1986) Rotations, Quaternions, and Double Groups .. note:: The Quaternion is always converted to a positive Quaternion (see :func:`quaternions.positive`) since for rotation :math:`q = -q`. """ if len(data) == 0: self._a = 0 self._A = vectors.Vector3D(0, 0, 0) elif len(data) == 1: self._a = data[0] self._A = vectors.Vector3D(0, 0, 0) elif len(data) == 2: self._a = data[0] self._A = vectors.Vector3D(data[1][0], data[1][1], data[1][2]) elif len(data) == 3: self._a = 0 self._A = vectors.Vector3D(data[0], data[1], data[2]) elif len(data) == 4: self._a = data[0] self._A = vectors.Vector3D(data[1], data[2], data[3]) # Convert the Quaternion to a positive Quaternion since q=-q self.positive()
def is_identity(self): """ Returns *True* if this :class:`SymOp` is a identity symmetry operation (no rotation, no translation), otherwise returns *False*. :rtype: :class:`bool` """ if matrices.almostequal(self.r, matrices.IdentityMatrix3D) and \ vectors.almostequal(self.t, vectors.Vector3D()): return True
def testso3matrix_to_quaternion(self): # Verified with Martin Baker (2008) Quaternion to AxisAngle, \url{http://www.euclideansplace.com} # Test calculation m = matrices.SO3Matrix([[1, 0, 0], [0, 0, -1], [0, 1, 0]]) q = quaternions.so3matrix_to_quaternion(m) expected_q = quaternions.Quaternion( sqrt(2) / 2.0, -sqrt(2) / 2.0, 0, 0) self.assertTrue(quaternions.almostequal(q, expected_q)) # Test back-conversion q1 = quaternions.so3matrix_to_quaternion(m) mq = q1.to_so3matrix() self.assertTrue(matrices.almostequal(m, mq)) # Random test for _i in range(REPETITIONS): n = [] for _j in range(2): x = random.random() * (-1)**(int(random.random() * 10)) z = random.random() * (-1)**(int(random.random() * 10)) y = random.random() * (-1)**(int(random.random() * 10)) n.append(vectors.normalize(vectors.Vector3D(x, y, z))) eP1 = vectors.normalize(n[0]) eP2 = vectors.cross(n[0], n[1]) eP2.normalize() eP3 = vectors.normalize(vectors.cross(eP1, eP2)) m = matrices.SO3Matrix([[eP1[0], eP2[0], eP3[0]], [eP1[1], eP2[1], eP3[1]], [eP1[2], eP2[2], eP3[2]]]) q = quaternions.so3matrix_to_quaternion(m) mq = q.to_so3matrix() self.assertTrue(matrices.almostequal(m, mq))
def testget_vector(self): expected_vector = vectors.Vector3D(-2, 3, 4) self.assertEqual(self.q1.get_vector(), expected_vector)