示例#1
0
    def update(self, x, z):
        rotation_x = quaternion.Quaternion(
            quaternion.create_from_eulers([x, 0, 0]))
        rotation_z = self.rotation_x.conjugate.cross(
            quaternion.Quaternion(quaternion.create_from_eulers([0, 0, z])))
        self.rotation_x = self.rotation_x.cross(rotation_x)

        self.matrix = numpy.matmul(
            self.matrix,
            matrix44.create_from_quaternion(rotation_z.cross(self.rotation_x)))
        self.inverse_matrix = numpy.linalg.inv(self.matrix)
示例#2
0
    def test_exp(self):
        source = np.array([0, 0, 0, 1.0])
        result = quaternion.exp(source)
        expected = np.array([0, 0, 0, np.exp(1)])
        np.testing.assert_almost_equal(result, expected)

        source = quaternion.create_from_eulers([np.pi, 0, 0])
        result = quaternion.exp(source)
        expected = np.array([0.84147098, 0, 0, 0.54030231])
        np.testing.assert_almost_equal(result, expected)

        # Tests from the boost::math::quaternion
        source = np.array([4 * np.arctan(1), 0, 0, 0])
        result = quaternion.exp(source) + [0, 0, 0, 1.0]
        result = np.linalg.norm(result)
        expected = 2 * np.finfo(result.dtype).eps
        np.testing.assert_almost_equal(result, expected)

        source = np.array([0, 4 * np.arctan(1), 0, 0])
        result = quaternion.exp(source) + [0, 0, 0, 1.0]
        result = np.linalg.norm(result)
        expected = 2 * np.finfo(result.dtype).eps
        np.testing.assert_almost_equal(result, expected)

        source = np.array([0, 0, 4 * np.arctan(1), 0])
        result = quaternion.exp(source) + [0, 0, 0, 1.0]
        result = np.linalg.norm(result)
        expected = 2 * np.finfo(result.dtype).eps
        np.testing.assert_almost_equal(result, expected)
示例#3
0
    def test_exp(self):
        source = np.array([0, 0, 0, 1.0])
        result = quaternion.exp(source)
        expected = np.array([0, 0, 0, np.exp(1)])
        np.testing.assert_almost_equal(result, expected)

        source = quaternion.create_from_eulers([np.pi, 0, 0])
        result = quaternion.exp(source)
        expected = np.array([0.84147098, 0, 0, 0.54030231])
        np.testing.assert_almost_equal(result, expected)

        # Tests from the boost::math::quaternion
        source = np.array([4 * np.arctan(1), 0, 0, 0])
        result = quaternion.exp(source) + [0, 0, 0, 1.0]
        result = np.linalg.norm(result)
        expected = 2 * np.finfo(result.dtype).eps
        np.testing.assert_almost_equal(result, expected)

        source = np.array([0, 4 * np.arctan(1), 0, 0])
        result = quaternion.exp(source) + [0, 0, 0, 1.0]
        result = np.linalg.norm(result)
        expected = 2 * np.finfo(result.dtype).eps
        np.testing.assert_almost_equal(result, expected)

        source = np.array([0, 0, 4 * np.arctan(1), 0])
        result = quaternion.exp(source) + [0, 0, 0, 1.0]
        result = np.linalg.norm(result)
        expected = 2 * np.finfo(result.dtype).eps
        np.testing.assert_almost_equal(result, expected)
示例#4
0
def octasphere(ndivisions: int):
    """Creates a unit sphere using octagon subdivision.

    Creates a unit sphere using octagon subdivision. Modified slightly from the original code
    by Philip Rideout (https://prideout.net/blog/octasphere).
    """

    n = 2**ndivisions + 1
    num_verts = n * (n + 1) // 2
    verts = empty((num_verts, 3))
    j = 0
    for i in range(n):
        theta = pi * 0.5 * i / (n - 1)
        point_a = [0, sin(theta), cos(theta)]
        point_b = [cos(theta), sin(theta), 0]
        num_segments = n - 1 - i
        j = compute_geodesic(verts, j, point_a, point_b, num_segments)
    assert len(verts) == num_verts

    num_faces = (n - 2) * (n - 1) + n - 1
    faces = empty((num_faces, 3), dtype='int')
    f, j0 = 0, 0
    for col_index in range(n - 1):
        col_height = n - 1 - col_index
        j1 = j0 + 1
        j2 = j0 + col_height + 1
        j3 = j0 + col_height + 2
        for row in range(col_height - 1):
            faces[f + 0] = [j0 + row, j1 + row, j2 + row]
            faces[f + 1] = [j2 + row, j1 + row, j3 + row]
            f = f + 2
        row = col_height - 1
        faces[f] = [j0 + row, j1 + row, j2 + row]
        f = f + 1
        j0 = j2

    euler_angles = array([
        [0, 0, 0],
        [0, 1, 0],
        [0, 2, 0],
        [0, 3, 0],
        [1, 0, 0],
        [1, 0, 1],
        [1, 0, 2],
        [1, 0, 3],
    ]) * pi * 0.5
    quats = (quaternion.create_from_eulers(e) for e in euler_angles)

    offset, combined_verts, combined_faces = 0, [], []
    for quat in quats:
        rotated_verts = [quaternion.apply_to_vector(quat, v) for v in verts]
        rotated_faces = faces + offset
        combined_verts.append(rotated_verts)
        combined_faces.append(rotated_faces)
        offset = offset + len(verts)

    return vstack(combined_verts), vstack(combined_faces)
示例#5
0
 def test_create_from_eulers(self):
     result = quaternion.create_from_eulers([1.0, 2.0, 3.0])
     np.testing.assert_almost_equal(
         result, [0.7549338, -0.2061492, 0.5015091, -0.3688714], decimal=5)
     self.assertTrue(result.dtype == np.float)
示例#6
0
 def test_create_from_eulers_identity(self):
     result = quaternion.create_from_eulers([0., 0., 0.])
     np.testing.assert_equal(result, [0., 0., 0., 1.])
     self.assertTrue(result.dtype == np.float)
示例#7
0
 def test_create_from_eulers(self):
     result = quaternion.create_from_eulers([1.0, 2.0, 3.0])
     np.testing.assert_almost_equal(result, [0.7549338, -0.2061492, 0.5015091, -0.3688714], decimal=5)
     self.assertTrue(result.dtype == np.float)
示例#8
0
 def test_create_from_eulers_identity(self):
     result = quaternion.create_from_eulers([0., 0., 0.])
     np.testing.assert_equal(result, [0., 0., 0., 1.])
     self.assertTrue(result.dtype == np.float)