/** * 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); } }
/** * graphene_quaternion_to_angles: * @q: a #graphene_quaternion_t * @deg_x: (out) (optional): return location for the rotation angle on * the X axis (yaw), in degress * @deg_y: (out) (optional): return location for the rotation angle on * the Y axis (pitch), in degrees * @deg_z: (out) (optional): return location for the rotation angle on * the Z axis (roll), in degrees * * Converts a #graphene_quaternion_t to its corresponding rotations * on the [Euler angles](http://en.wikipedia.org/wiki/Euler_angles) * on each axis. * * Since: 1.2 */ void graphene_quaternion_to_angles (const graphene_quaternion_t *q, float *deg_x, float *deg_y, float *deg_z) { graphene_vec4_t v; graphene_vec4_t sq; float qx, qy, qz, qw, sqx, sqy, sqz, sqw; graphene_quaternion_to_vec4 (q, &v); graphene_vec4_multiply (&v, &v, &sq); qx = graphene_vec4_get_x (&v); qy = graphene_vec4_get_y (&v); qz = graphene_vec4_get_z (&v); qw = graphene_vec4_get_w (&v); sqx = graphene_vec4_get_x (&sq); sqy = graphene_vec4_get_y (&sq); sqz = graphene_vec4_get_z (&sq); sqw = graphene_vec4_get_w (&sq); if (deg_x != NULL) { float res = atan2f (2 * (qx * qw - qy * qz), (sqw - sqx - sqy + sqz)); *deg_x = GRAPHENE_RAD_TO_DEG (res); } if (deg_y != NULL) { float res = asinf (CLAMP (2 * ( qx * qz + qy * qw), -1, 1)); *deg_y = GRAPHENE_RAD_TO_DEG (res); } if (deg_z != NULL) { float res = atan2f (2 * (qz * qw - qx * qy), (sqw + sqx - sqy - sqz)); *deg_z = GRAPHENE_RAD_TO_DEG (res); } }
/** * graphene_euler_get_z: * @e: a #graphene_euler_t * * Retrieves the rotation angle on the Z axis, in degrees. * * Returns: the rotation angle * * Since: 1.2 */ float graphene_euler_get_z (const graphene_euler_t *e) { return GRAPHENE_RAD_TO_DEG (graphene_vec3_get_z (&e->angles)); }