Appearance
四元数、欧拉角
欧拉角 Euler
创建欧拉角表示特定旋转角度
js
const Euler = new THREE.Euler();
Euler.x = Math.PI / 3; //绕x轴旋转60度
Euler.y = Math.PI / 3; //绕y轴旋转60度
Euler.z = Math.PI / 3; //绕z轴旋转60度
改变物体角度
threejs 模型对象都包含rotation
属性,.rotation
的值其实就是欧拉角对象Euler
直接修改
.rotation
js// 物体fly绕x轴旋转60度 fly.rotation.x = Math.PI / 3;
copy
Euler
jsconst Euler = new THREE.Euler(); Euler.x = Math.PI / 3; // 复制欧拉角的值,赋值给物体的.rotation属性 fly.rotation.copy(Euler);
物体旋转顺序.order
物体先后绕 x、y、z 轴旋转,旋转的顺序不同,物体的姿态角度也可能不同。
直接修改
.rotation
js// 直接修改fly.rotation fly.rotation.order = "YXZ"; fly.rotation.x = Math.PI / 3; fly.rotation.y = Math.PI / 3;
欧拉赋值
jsconst Euler = new THREE.Euler(); Euler.x = Math.PI / 3; Euler.y = Math.PI / 3; //先绕Y轴旋转,在绕X、Z轴旋转 Euler.order = "YXZ"; fly.rotation.copy(Euler);
四元数 Quaternion
四元数Quaternion
和欧拉角Euler
一样, 用来计算或表示物体在 3D 空间中的旋转姿态角度
实例化Quaternion
js
const quaternion = new THREE.Quaternion();
四元数方法.setFromAxisAngle()
生成一个四元数,绕任意轴,旋转任意角度
js
const quaternion = new THREE.Quaternion();
// 旋转轴new THREE.Vector3(0,0,1)
// 旋转角度Math.PI/2
// 绕z轴旋转90度
quaternion.setFromAxisAngle(new THREE.Vector3(0, 0, 1), Math.PI / 2);
四元数旋转坐标
通过.applyQuaternion(quaternion)
对坐标点进行旋转
js
const quaternion = new THREE.Quaternion();
// 绕z轴旋转90度
quaternion.setFromAxisAngle(new THREE.Vector3(0, 0, 1), Math.PI / 2);
// 通过四元数旋转A点:把A点绕z轴旋转90度生成一个新的坐标点B
const B = A.clone().applyQuaternion(quaternion);
四元数表示物体姿态
Three.js 模型对象都有一个属性.quaternion
, 可以通过物体.quaternion
属性改变物体的姿态角度
js
const quaternion = new THREE.Quaternion();
quaternion.setFromAxisAngle(new THREE.Vector3(1, 0, 0), Math.PI / 2);
//quaternion表示旋转角度复制给物体.quaternion
fly.quaternion.copy(quaternion);
模型属性.rotation
(角度)和.quaternion
(四元数)
二者都是用来表示物体姿态角度, 一个改变,另一个也会同步改变。
四元数乘法运算.multiply()
在物体原有角度姿态上进行旋转
js
// 在物体原来姿态基础上,进行旋转
const q1 = new THREE.Quaternion();
q1.setFromAxisAngle(new THREE.Vector3(1, 0, 0), Math.PI / 2);
fly.quaternion.multiply(q1);
// 在物体上次旋转基础上,进行旋转
const q2 = new THREE.Quaternion();
q2.setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI / 2);
fly.quaternion.multiply(q2);
效果同上:
js
const q1 = new THREE.Quaternion();
q1.setFromAxisAngle(new THREE.Vector3(1, 0, 0), Math.PI / 2);
const q2 = new THREE.Quaternion();
q2.setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI / 2);
const newQ = q1.clone().multiply(q2);
fly.quaternion.multiply(newQ);
注意
不满足交换律,执行顺序不同将影响物体最终姿态角度
与.copy
区别
A.multiply(B)
表示 A 乘以 B,结果赋值给 A,在 A 的基础上旋转 B。
A.copy(B)
表示用 B 的值替换 A 的值,A 表示的旋转会被 B 替换。
四元数表示两个向量旋转
一个向量向另外一个向量旋转,这个过程可以用一个四元数表示
js
//飞机初始姿态飞行方向a
const a = new THREE.Vector3(0, 0, -1);
// 飞机姿态绕自身坐标原点旋转到b指向的方向
const b = new THREE.Vector3(-1, -1, -1).normalize();
// a旋转到b构成的四元数
const quaternion = new THREE.Quaternion();
//注意两个参数的顺序
quaternion.setFromUnitVectors(a, b);
// quaternion表示的是变化过程,在原来基础上乘以quaternion即可
fly.quaternion.multiply(quaternion);