static char * test_quaternion_axis_anglev3() { quaternion q, q1; float c; float s; float angle = HYP_TAU / 4.0f; vector3 axis; quaternion_set_from_axis_anglev3(&q, HYP_VECTOR3_UNIT_X, angle); vector3_set(&axis, HYP_VECTOR3_UNIT_X); c = HYP_COS(angle / 2.0f); s = HYP_SIN(angle / 2.0f); q1.x = axis.x * s; q1.y = axis.y * s; q1.z = axis.z * s; q1.w = c; quaternion_normalize(&q1); test_assert(quaternion_equals(&q, &q1)); return 0; }
/** [quaternion conjugate example] */ static char * test_quaternion_conjugate() { quaternion qA; quaternion qB; quaternion_set_from_axis_anglef3(&qA, 1.0f, 1.0f, 1.0f, HYP_TAU / 4.0f); quaternion_set_from_axis_anglef3(&qB, -1.0f, -1.0f, -1.0f, HYP_TAU / 4.0f); quaternion_conjugate(&qB); test_assert(quaternion_equals(&qA, &qB)); return 0; }
static char * test_quaternion_multiply() { quaternion qA, qB; quaternion_set_from_axis_anglev3(&qA, HYP_VECTOR3_UNIT_X, HYP_TAU / 8.0f); quaternion_set_from_axis_anglev3(&qB, HYP_VECTOR3_UNIT_X, HYP_TAU / 4.0f); /* qA squared */ quaternion_multiply(&qA, &qA); test_assert(quaternion_equals(&qA, &qB)); return 0; }
/** [quaternion inverse example] */ static char * test_quaternion_inverse() { quaternion qA; quaternion qInverse; quaternion qIdentity; quaternion_set_from_axis_anglef3(&qA, 1.0f, 1.0f, 1.0f, HYP_TAU / 4.0f); quaternion_set(&qInverse, &qA); quaternion_inverse(&qInverse); quaternion_multiply(&qA, &qInverse); quaternion_normalize(&qA); quaternion_identity(&qIdentity); test_assert(quaternion_equals(&qA, &qIdentity)); return 0; }
static char * test_quaternion_multiply_identity() { quaternion qA, qB, q; qA.x = 1; qA.y = 2; qA.z = 3; qA.w = 4; quaternion_identity(&qB); quaternion_set(&q, &qA); quaternion_multiply(&q, &qB); test_assert(quaternion_equals(&q, &qA)); return 0; }
static char *test_quaternion_get_eulers_create_quaternion_ZYX_aa(void) { struct quaternion q1, q2; HYP_FLOAT anglex, angley, anglez; /* making the original quaternion out of an arbitrary axis angle */ quaternion_set_from_axis_anglef3(&q1, 0.4f, 0.232f, 0.543f, HYP_TAU / 1.45f); /* get the angles */ quaternion_get_euler_anglesf3_ZYX_EXP(&q1, &anglex, &angley, &anglez); /* compose new quaternions with the eulers */ quaternion_set_from_euler_anglesf3_ZYX_EXP(&q2, anglex, angley, anglez); /* same */ test_assert(quaternion_equals(&q1, &q2)); return 0; }
static char *test_quaternion_get_eulers_create_quaternion_ZYX(void) { struct quaternion q1, q2; HYP_FLOAT anglex, angley, anglez; /* make a quaternion out of some arbitrary euler angles */ quaternion_set_from_euler_anglesf3_ZYX_EXP(&q1, 0.8f, 0.8f, 0.8f); /* get the angles */ quaternion_get_euler_anglesf3_ZYX_EXP(&q1, &anglex, &angley, &anglez); /* compose new quaternions with the eulers */ quaternion_set_from_euler_anglesf3_ZYX_EXP(&q2, anglex, angley, anglez); /* same */ test_assert(quaternion_equals(&q1, &q2)); return 0; }
static char * test_quaternion_slerp() { quaternion q, q1, q2, q3; float angle; angle = HYP_TAU / 4.0f; quaternion_set_from_axis_anglev3(&q1, HYP_VECTOR3_UNIT_X, angle); quaternion_set_from_axis_anglev3(&q2, HYP_VECTOR3_UNIT_X, angle * 1.1f); quaternion_set_from_axis_anglev3(&q3, HYP_VECTOR3_UNIT_X, angle * 1.2f); /* half-way */ quaternion_slerp(&q1, &q3, 0.5f, &q); test_assert(quaternion_equals(&q, &q2)); /* none */ quaternion_slerp(&q1, &q3, 0.0f, &q); test_assert(quaternion_equals(&q, &q1)); /* all the way */ quaternion_slerp(&q1, &q3, 1.0f, &q); test_assert(quaternion_equals(&q, &q3)); /* swap order half-way */ quaternion_slerp(&q3, &q1, 0.5f, &q); test_assert(quaternion_equals(&q, &q2)); /* swap order none */ quaternion_slerp(&q3, &q1, 0.0f, &q); test_assert(quaternion_equals(&q, &q3)); /* swap order all the way */ quaternion_slerp(&q3, &q1, 1.0f, &q); test_assert(quaternion_equals(&q, &q1)); /* go reverse around the sphere */ quaternion_set_from_axis_anglev3(&q1, HYP_VECTOR3_UNIT_X, angle); quaternion_set_from_axis_anglev3(&q2, HYP_VECTOR3_UNIT_X, angle * 0.9f); quaternion_set_from_axis_anglev3(&q3, HYP_VECTOR3_UNIT_X, angle * 0.8f); /* go reverse half-way */ quaternion_slerp(&q1, &q3, 0.5f, &q); test_assert(quaternion_equals(&q, &q2)); /* go reverse none */ quaternion_slerp(&q1, &q3, 0.0f, &q); test_assert(quaternion_equals(&q, &q1)); /* go reverse all the way */ quaternion_slerp(&q1, &q3, 1.0f, &q); test_assert(quaternion_equals(&q, &q3)); /* swap order reverse half-way */ quaternion_slerp(&q3, &q1, 0.5f, &q); test_assert(quaternion_equals(&q, &q2)); /* swap order reverse none */ quaternion_slerp(&q3, &q1, 0.0f, &q); test_assert(quaternion_equals(&q, &q3)); /* swap order reverse all the way */ quaternion_slerp(&q3, &q1, 1.0f, &q); test_assert(quaternion_equals(&q, &q1)); return 0; }