BufferGeometry
Object3D
Raycaster
Camera
CubeCamera
PerspectiveCamera
OrthographicCamera
StereoCamera
Clock
Curve
CurvePath
Path
Shape
ShapePath
ArrowHelper
AxesHelper
BoxHelper
Box3Helper
CameraHelper
DirectionalLightHelper
GridHelper
PolarGridHelper
HemisphereLightHelper
PlaneHelper
PointLightHelper
SkeletonHelper
SpotLightHelper
Light
PointLight
RectAreaLight
SpotLight
DirectionalLight
HemisphereLight
LightShadow
PointLightShadow
AnimationLoader
AudioLoader
BufferGeometryLoader
CompressedTextureLoader
CubeTextureLoader
DataTextureLoader
FileLoader
ImageBitmapLoader
ImageLoader
Loader
LoaderUtils
MaterialLoader
ObjectLoader
TextureLoader
LoadingManager
Material
Box2
Box3
Color
Cylindrical
Euler
Frustum
Interpolant
Line3
MathUtils
Matrix3
Matrix4
Plane
Quaternion
AnimationAction
AnimationClip
AnimationMixer
AnimationObjectGroup
AnimationUtils
keyframeTrack
PropertyBinding
PropertyMixer
BooleanKeyframeTrack
QuaternionKeyframeTrack
StringKeyframeTrack
Audio
AudioAnalyser
AudioContext
AudioListener
PositionalAudio

MathUtils.setQuaternionFromProperEuler()

该函数是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);

参考