/** * Converts this Quaternion to Euler rotation angles {@code roll}, {@code pitch} and {@code yaw} * in radians. {@link #fromEulerAngles(float, float, float)} performs the inverse operation. The * code was adapted from: http://www.euclideanspace.com/maths/geometry * /rotations/conversions/quaternionToEuler/index.htm. * * <p><b>Attention:</b> This method assumes that this Quaternion is normalized. * * @return the PVector holding the roll (x coordinate of the vector), pitch (y coordinate of the * vector) and yaw angles (z coordinate of the vector). <b>Note:</b> The order of the * rotations that would produce this Quaternion (i.e., as with {@code fromEulerAngles(roll, * pitch, yaw)}) is: y->z->x. * @see #fromEulerAngles(float, float, float) */ public PVector eulerAngles() { float roll, pitch, yaw; float test = x * y + z * w; if (test > 0.499) { // singularity at north pole pitch = 2 * PApplet.atan2(x, w); yaw = PApplet.PI / 2; roll = 0; return new PVector(roll, pitch, yaw); } if (test < -0.499) { // singularity at south pole pitch = -2 * PApplet.atan2(x, w); yaw = -PApplet.PI / 2; roll = 0; return new PVector(roll, pitch, yaw); } float sqx = x * x; float sqy = y * y; float sqz = z * z; pitch = PApplet.atan2(2 * y * w - 2 * x * z, 1 - 2 * sqy - 2 * sqz); yaw = PApplet.asin(2 * test); roll = PApplet.atan2(2 * x * w - 2 * y * z, 1 - 2 * sqx - 2 * sqz); return new PVector(roll, pitch, yaw); }
private final float atan2(float y, float x) { return parent.atan2(y, x); }