/** * graphene_quaternion_to_angle_vec3: * @q: a #graphene_quaternion_t * @angle: (out): return location for the angle, in degrees * @axis: (out caller-allocates): return location for the rotation axis * * Converts a quaternion into an @angle, @axis pair. * * Since: 1.0 */ void graphene_quaternion_to_angle_vec3 (const graphene_quaternion_t *q, float *angle, graphene_vec3_t *axis) { graphene_quaternion_t q_n; float cos_a; graphene_quaternion_normalize (q, &q_n); cos_a = q_n.w; if (angle != NULL) *angle = GRAPHENE_RAD_TO_DEG (acosf (cos_a) * 2.f); if (axis != NULL) { float sin_a = sqrtf (1.f - cos_a * cos_a); if (fabsf (sin_a) < 0.00005) sin_a = 1.f; graphene_vec3_init (axis, q_n.x / sin_a, q_n.y / sin_a, q_n.z / sin_a); } }
static void quaternion_operators_normalize (mutest_spec_t *spec) { graphene_quaternion_t q1, q2; graphene_vec4_t v1, v2; graphene_quaternion_init (&q1, 1.f, 2.f, 3.f, 4.f); graphene_quaternion_normalize (&q1, &q2); graphene_vec4_init (&v1, 1.f, 2.f, 3.f, 4.f); graphene_vec4_normalize (&v1, &v1); graphene_quaternion_to_vec4 (&q2, &v2); mutest_expect ("normalizing a quaternion is the same as normalizing the equivalent vec4", mutest_bool_value (graphene_vec4_near (&v1, &v2, 0.00001f)), mutest_to_be_true, NULL); }