该函数是three.js中的MathUtils类中的一个静态方法,用于将给定的三个欧拉角转换为四元数形式。
MathUtils.setQuaternionFromProperEuler(euler, quaternion);
euler
:THREE.Euler对象,包含三个欧拉角,单位是弧度。quaternion
:THREE.Quaternion对象,将转换后的四元数存储到该对象中。无返回值,转换后的四元数存储在给定的quaternion
中。
欧拉角是一种描述物体旋转状态的方法,但是在进行旋转计算时,使用欧拉角会遇到奇异性问题(gimbal lock),因此需要转换成四元数进行计算。该函数将给定的欧拉角转换成四元数形式,并将结果存储在给定的quaternion
对象中。
该函数采用的是Proper Euler Angle(合适的欧拉角)的旋转顺序,也称为zyx顺序,即先绕Z轴旋转,再绕Y轴旋转,最后绕X轴旋转。因此,给定的欧拉角顺序应为(z,y,x)。
转换过程如下:
首先,将欧拉角转换成旋转矩阵:
const c1 = Math.cos(euler.x / 2);
const c2 = Math.cos(euler.y / 2);
const c3 = Math.cos(euler.z / 2);
const s1 = Math.sin(euler.x / 2);
const s2 = Math.sin(euler.y / 2);
const s3 = Math.sin(euler.z / 2);
const m00 = c1 * c2 * c3 - s1 * s2 * s3;
const m01 = s1 * c2 * c3 + c1 * s2 * s3;
const m02 = c1 * s2 * c3 - s1 * c2 * s3;
const m10 = s1 * c2 * c3 + c1 * s2 * s3;
const m11 = c1 * c2 * c3 - s1 * s2 * s3;
const m12 = c1 * s2 * s3 + s1 * c2 * c3;
const m20 = c1 * s2 * c3 + s1 * c2 * s3;
const m21 = s1 * s2 * c3 - c1 * c2 * s3;
const m22 = c1 * c2 * c3 + s1 * s2 * s3;
然后,将旋转矩阵转换成四元数形式:
const tr = m00 + m11 + m22;
if (tr >= 0) {
const s = Math.sqrt(tr + 1);
quaternion.w = s / 2;
s = 0.5 / s;
quaternion.x = (m21 - m12) * s;
quaternion.y = (m02 - m20) * s;
quaternion.z = (m10 - m01) * s;
} else if ((m00 > m11) && (m00 > m22)) {
const s = Math.sqrt(1 + m00 - m11 - m22);
quaternion.x = s / 2;
s = 0.5 / s;
quaternion.y = (m10 + m01) * s;
quaternion.z = (m02 + m20) * s;
quaternion.w = (m21 - m12) * s;
} else if (m11 > m22) {
const s = Math.sqrt(1 + m11 - m00 - m22);
quaternion.y = s / 2;
s = 0.5 / s;
quaternion.x = (m10 + m01) * s;
quaternion.z = (m21 + m12) * s;
quaternion.w = (m02 - m20) * s;
} else {
const s = Math.sqrt(1 + m22 - m00 - m11);
quaternion.z = s / 2;
s = 0.5 / s;
quaternion.x = (m02 + m20) * s;
quaternion.y = (m21 + m12) * s;
quaternion.w = (m10 - m01) * s;
}
最后,将得到的四元数存储在给定的quaternion
对象中。
const euler = new THREE.Euler(Math.PI / 4, Math.PI / 3, -Math.PI / 6);
const quaternion = new THREE.Quaternion();
MathUtils.setQuaternionFromProperEuler(euler, quaternion);