def test_is_unitary(self, arr):
     q = GeneralQuaternion(*arr)
     assume(
         q.norm() > DEFAULT_TOLERANCE
     )  # ignore quaternions of norm==0, whose inverse is numerically unstable
     assert q.normalized().is_unitary()
     assert not (2 * q.normalized()).is_unitary()
Exemple #2
0
 def __mul__(self, p):
     if isinstance(p, Quaternion) or isinstance(p, numbers.Number):
         mul = GeneralQuaternion(*self.coordinates) * p
         return Quaternion(*mul.coordinates)
     elif isinstance(p, GeneralQuaternion):
         return GeneralQuaternion(*self.coordinates) * p
     elif isinstance(p, Iterable) and len(
             p) == 3:  # applies quaternion rotation on vector
         return self.matrix.dot(p)
     else:
         raise QuaternionError('cant multiply by %s' % type(p))
Exemple #3
0
    def from_ra_dec_roll(ra, dec, roll):
        '''constructs a quaternion from ra/dec/roll params
        using Tait-Bryan angles XYZ.

        ra stands for right ascencion, and usually lies in [0, 360]
        dec stands for declination, and usually lies in [-90, 90]
        roll stands for rotation/rolling, and usually lies in [0, 360]
        '''
        raq = exp(GeneralQuaternion(0, 0, 0, -np.deg2rad(ra) / 2))
        decq = exp(GeneralQuaternion(0, 0, -np.deg2rad(dec) / 2, 0))
        rollq = exp(GeneralQuaternion(0, -np.deg2rad(roll) / 2, 0, 0))
        q = rollq * decq * raq
        return Quaternion(*q.coordinates)
 def test_inverse(self, arr):
     q = GeneralQuaternion(*arr)
     assume(
         q.norm() > DEFAULT_TOLERANCE
     )  # ignore quaternions of norm==0, whose inverse is numerically unstable
     assert q * q.inverse() == q.inverse() * q == GeneralQuaternion.unit()
     assert q * ~q == ~q * q == GeneralQuaternion.unit()
Exemple #5
0
    def from_rotation_vector(xyz):
        """
        Returns the quaternion corresponding to the rotation xyz.
        Explicitly: rotation occurs along the axis xyz and has angle
        norm(xyz)

        This corresponds to the exponential of the quaternion with
        real part 0 and imaginary part 1/2 * xyz.
        """
        a, b, c = .5 * np.array(xyz)
        q_exp = exp(GeneralQuaternion(0, a, b, c))
        return Quaternion(*q_exp.coordinates)
 def test_arithmetics(self, arr):
     q = GeneralQuaternion(*arr)
     assert q + q == 2 * q == q * 2
     assert q - q == GeneralQuaternion.zero()
     assert q * GeneralQuaternion.zero() == q * 0 == GeneralQuaternion.zero()
     assert q * GeneralQuaternion.unit() == q * 1 == q
     assert GeneralQuaternion.unit() * q == 1 * q == q
     assert -(-q) == q
 def test_log_identity(self):
     assert log(GeneralQuaternion.unit()) == GeneralQuaternion.zero()
 def test_print(self, arr):
     """ make sure all coordinates are printed. """
     q = GeneralQuaternion(*arr)
     for elem in q.coordinates:
         expected_string = '{elem:.6g}'.format(**{'elem': elem})
         assert expected_string in str(q)
 def test_exp_identity(self):
     assert exp(GeneralQuaternion.zero()) == GeneralQuaternion.unit()
 def test_normalized(self, arr):
     q = GeneralQuaternion(*arr)
     assume(q.norm() > DEFAULT_TOLERANCE)  # ignore quaternions of norm==0, whose inverse is numerically unstable
     assert q.normalized().norm() == pytest.approx(1, DEFAULT_TOLERANCE)
 def test_coordinates(self, arr):
     q = GeneralQuaternion(*arr)
     assert q == GeneralQuaternion(*q.coordinates)
 def test_conjugate(self, arr):
     q = GeneralQuaternion(*arr)
     assert (q + q.conjugate()).is_real()
     assert (q * q.conjugate()).is_real()
 def test_distance(self, arr):
     q = GeneralQuaternion(*arr)
     assert q.euclidean_distance(q) == pytest.approx(0)
     assert q.norm() == q.euclidean_distance(GeneralQuaternion.zero()) == q.euclidean_distance(2 * q)
 def test_exp_log(self, arr):
     assume(np.linalg.norm(arr) > DEFAULT_TOLERANCE)
     q = GeneralQuaternion(*arr).normalized()
     assert exp(log(q)) == q
     assert log(exp(q)) == GeneralQuaternion(*q.coordinates)
 def test_exp_norm(self, arr1):
     q1 = GeneralQuaternion(*arr1)
     assert exp(q1).norm() == pytest.approx(np.exp(q1.qr))  # |exp(q)| == exp(real(q)|
 def test_raises(self, arr):
     q = GeneralQuaternion(*arr)
     with pytest.raises(QuaternionError):
         q + 3
 def test_real_imaginary(self, arr):
     q = GeneralQuaternion(*arr)
     i, j, k = q.imaginary
     assert (q.coordinates == [q.real, i, j, k]).all()
 def test_equal(self, arr):
     q = GeneralQuaternion(*arr)
     assert q == q
     assert q == q + GeneralQuaternion(0.9 * DEFAULT_TOLERANCE, 0, 0, 0)
     assert q != q + GeneralQuaternion(1.1 * DEFAULT_TOLERANCE, 0, 0, 0)
 def test_log_identical_both_ways(self, arr):
     assume(np.linalg.norm(arr) > DEFAULT_TOLERANCE)
     q = GeneralQuaternion(*arr)
     assert log(q) == q.log()
 def test_exp_identical_both_ways(self, arr):
     q = GeneralQuaternion(*arr)
     assert exp(q) == q.exp()
 def test_sum_commutative(self, arr1, arr2):
     q1 = GeneralQuaternion(*arr1)
     q2 = GeneralQuaternion(*arr2)
     assert q1 + q2 == q2 + q1
     assert q1 - q2 == - (q2 - q1)
 def test_repr(self):
     gen_quat = GeneralQuaternion(1, 2, 3, 4)
     assert repr(gen_quat) == 'GeneralQuaternion(1, 2, 3, 4)'