Vector3是一个用于表示三维空间中向量的类,常用于计算机图形学、物理模拟和游戏开发等领域。它通常包含三个分量:x、y和z。以下是一些基本操作和用法:
Vector3 有三个属性六十九个方法
Vector3( x : Float, y : Float, z : Float ) x - 向量的x值,默认为0。 y - 向量的y值,默认为0。 z - 向量的z值,默认为0。 创建一个新的Vector3。
属性
- isVector3 : Boolean 查看是否是三维向量
- x : Float x 座标
- y : Float y 座标
- z : Float z 座标
方法
- add ( v : Vector3 ) : this 将传入的向量v和这个向量相加。
- addScalar ( s : Float ) : this 将传入的标量s和这个向量的x值、y值以及z值相加。
- addScaledVector ( v : Vector3, s : Float ) : this 将所传入的v与s相乘所得的乘积和这个向量相加。
// 创建一个 Vector3 对象
const vectorA = new THREE.Vector3(1, 2, 3);
// 创建另一个 Vector3 对象
const vectorB = new THREE.Vector3(4, 5, 6);
// 缩放因子
const scale = 2;
// 使用 addScaledVector 方法
vectorA.addScaledVector(vectorB, scale);
console.log(vectorA); // 输出: Vector3(9, 12, 15)
- addVectors ( a : Vector3, b : Vector3 ) : this 将该向量设置为a + b。
- applyAxisAngle ( axis : Vector3, angle : Float ) : this applyAxisAngle 是 THREE.Vector3 类的一个方法,用于将当前向量围绕指定的轴进行旋转。这个方法使用了旋转轴和旋转角度(以弧度为单位)。
const vector = new THREE.Vector3(1, 0, 0); // 原始向量在 x 轴
// 定义旋转轴(这里是 y 轴)
const axis = new THREE.Vector3(0, 1, 0); // y 轴
axis.normalize(); // 确保轴是单位向量
// 定义旋转角度(例如,90度,转换为弧度)
const angle = Math.PI / 2; // 90 degrees in radians
// 应用轴角旋转
vector.applyAxisAngle(axis, angle);
// 因为 2.220446049250313e-16 的绝对值非常小,接近于零,通常在数值计算中,这个值可以被视作 0。
console.log(vector); // 输出旋转后的向量 { "x": 2.220446049250313e-16, "y": 0, "z": -1 }
- applyEuler ( euler : Euler ) : this 在 Three.js 中,Vector3.applyEuler() 方法用于将给定的 Euler 旋转应用到一个 Vector3 向量上。它改变向量的方向,而不会改变其长度。这在三维空间中非常有用,尤其是当你需要对一个向量进行旋转时。是围绕 原点 (0, 0, 0) 进行旋转的
// 创建一个 Vector3 对象
const vector = new THREE.Vector3(1, 0, 0);
// 创建一个 Euler 对象(旋转角度),单位为弧度
const euler = new THREE.Euler(Math.PI / 2, 0, 0);
// 将 Euler 旋转应用到向量
vector.applyEuler(euler);
// 输出旋转后的向量
console.log(vector);
- applyMatrix3 ( m : Matrix3 ) : this Vector3.applyMatrix3() 是 Three.js 中 Vector3 类的一个方法,它将一个 Matrix3(3x3 矩阵)应用到当前的 Vector3 向量上。这种操作可以用来执行向量的各种线性变换,如缩放、旋转、剪切等。
// 创建一个 Vector3 对象
const vector = new THREE.Vector3(1, 2, 3);
// 创建一个 3x3 矩阵
const matrix = new THREE.Matrix3();
// 为矩阵设置缩放和旋转的值
matrix.set(
2, 0, 0, // x 方向缩放 2 倍
0, 0, 1, // y 轴变换(90 度旋转)
0, -1, 0 // z 轴变换
);
// 将矩阵应用到向量上
vector.applyMatrix3(matrix);
console.log(vector); // 输出变换后的向量 { "x": 2, "y": 3, "z": -2 }
- applyMatrix4 ( m : Matrix4 ) : this Vector3.applyMatrix4() 是 Three.js 中 Vector3 类的一个方法,它将一个 4x4 矩阵 Matrix4 作用于当前的 Vector3 向量。这个方法允许你对向量进行各种线性变换(如缩放、旋转、平移等),并且可以进行齐次坐标的操作(即将 3D 空间中的向量扩展到 4D 空间,以支持平移等仿射变换)。
// 创建一个 Vector3 对象
const vector = new THREE.Vector3(1, 1, 1);
// 创建一个 4x4 矩阵
const matrix = new THREE.Matrix4();
// 为矩阵设置旋转和平移值
matrix.makeRotationX(Math.PI / 4); // 绕 X 轴旋转 45 度
matrix.setPosition(2, 3, 4); // 设置平移
// 将矩阵应用到向量上
vector.applyMatrix4(matrix);
console.log(vector); // 输出变换后的向量 { "x": 3, "y": 3, "z": 5.414213562373095 }
- applyNormalMatrix ( m : Matrix3 ) : this 是 THREE.Vector3 类的方法,用于将一个法向量应用于 3x3 矩阵 Matrix3。通常在 3D 图形渲染中,法向量用于计算光照、反射等效果。当几何体发生旋转、缩放、或非均匀变换时,法向量也需要做相应的调整才能正确地与光照等效果匹配。applyNormalMatrix 用来处理这种变换,确保法向量正确地响应几何体的变化。
// 创建一个法线向量
const normal = new THREE.Vector3(1, 0, 0);
// 创建一个 3x3 矩阵(用于缩放)
const matrix = new THREE.Matrix3();
matrix.set(
2, 0, 0, // x 轴缩放 2 倍
0, 1, 0, // y 轴缩放保持不变
0, 0, 3 // z 轴缩放 3 倍
);
// 计算逆矩阵并转置,作为法线矩阵
const normalMatrix = new THREE.Matrix3().getNormalMatrix(new THREE.Matrix4().set(
2, 0, 0, 0,
0, 1, 0, 0,
0, 0, 3, 0,
0, 0, 0, 1
));
// 将法线矩阵应用到法线向量上
normal.applyMatrix3(normalMatrix);
// 输出变换后的法线向量
console.log('变换后的法线:', normal); // { "x": 0.5, "y": 0, "z": 0 }
// 如果需要归一化法线
normal.normalize();
console.log('归一化后的法线:', normal); // { "x": 1, "y": 0, "z": 0 }
- applyQuaternion ( quaternion : Quaternion ) : this Vector3.applyQuaternion() 是 Three.js 中 Vector3 类的一个方法,用于将四元数 Quaternion 作用到当前的 Vector3 向量上。四元数常用于 3D 空间中的旋转变换,因为它们能够避免欧拉角旋转中的万向节锁问题,并且在处理连续旋转时更加稳定。
**绕 X 轴旋转**:叫做“俯仰”(pitch),可以让物体前后“点头”。
**绕 Y 轴旋转**:叫做“偏航”(yaw),可以让物体左右“摆头”。
**绕 Z 轴旋转**:叫做“翻滚”(roll),可以让物体左右“侧倾”。
// 创建一个 Vector3 对象
const vector = new THREE.Vector3(1, 0, 0); // 初始向量指向 X 轴
// 创建一个 Quaternion(绕 Z 轴旋转 90 度)
const quaternion = new THREE.Quaternion();
quaternion.setFromAxisAngle(new THREE.Vector3(0, 0, 1), Math.PI / 2); // Z 轴旋转 90 度
// 将四元数应用到向量上
vector.applyQuaternion(quaternion);
console.log(vector); // 输出旋转后的向量 { "x": 2.220446049250313e-16, "y": 1, "z": 0 }
- angleTo ( v : Vector3 ) : Float 以弧度返回该向量与向量v之间的角度。以中心点0,0,0 计算
- ceil () : this 将该向量x分量、 y分量以及z分量向上取整为最接近的整数。
- clamp ( min : Vector3, max : Vector3 ) : this min - 在限制范围内,x值、y值和z的最小值。 max - 在限制范围内,x值、y值和z的最大值。 如果该向量的x值、y值或z值大于限制范围内最大x值、y值或z值,则该值将会被所对应的值取代。 如果该向量的x值、y值或z值小于限制范围内最小x值、y值或z值,则该值将会被所对应的值取代。
- clampLength ( min : Float, max : Float ) : this min - 长度将被限制为的最小值 max - 长度将被限制为的最大值 如果向量长度大于最大值,则它将会被最大值所取代。 如果向量长度小于最小值,则它将会被最小值所取代。
// 创建一个 Vector3 对象
const vector = new THREE.Vector3(3, 4, 0); // 长度为 5
// 限制向量的长度在 2 到 4 之间
vector.clampLength(2, 4);
console.log(vector.length(), vector); // 输出的长度将为 4 { "x": 2.4000000000000004, "y": 3.2, "z": 0 }
- clampScalar ( min : Float, max : Float ) : this min - 分量将被限制为的最小值 max - 分量将被限制为的最大值 如果该向量的x值、y值或z值大于最大值,则它们将被最大值所取代。 如果该向量的x值、y值或z值小于最小值,则它们将被最小值所取代。
- clone () : Vector3 返回一个新的Vector3,其具有和当前这个向量相同的x、y和z。
- copy ( v : Vector3 ) : this 将所传入Vector3的x、y和z属性复制给这一Vector3。
- cross ( v : Vector3 ) : this 是 Three.js 中
Vector3类的一个方法,用于计算当前向量与另一个向量 v 的叉积。叉积是一个向量运算,它的结果是一个新的向量,该向量垂直于这两个输入向量。
// 创建两个 Vector3 对象
const vectorA = new THREE.Vector3(1, 0, 0); // 向量 A
const vectorB = new THREE.Vector3(0, 1, 0); // 向量 B
// 计算叉积
const crossProduct = vectorA.cross(vectorB);
console.log(crossProduct); // 输出: Vector3 { x: 0, y: 0, z: 1 }
// 示例2
// 创建两个向量 A 和 B
const vectorA = new THREE.Vector3(2, 0, 0); // 向量 A,长度为 2
const vectorB = new THREE.Vector3(0, 1, 0); // 向量 B,长度为 1,垂直于 A
// 计算叉积 C = A × B
const crossProduct = vectorA.cross(vectorB);
console.log(crossProduct); // 输出: Vector3 { x: 0, y: 0, z: 2 }
console.log(crossProduct.length()); // 输出: 2
- crossVectors ( a : Vector3, b : Vector3 ) : this 将该向量设置为传入的a与b的叉积(cross product)。
- distanceTo ( v : Vector3 ) : Float 计算该向量到所传入的v间的距离。
// 创建两个 Vector3 对象
const vectorA = new THREE.Vector3(1, 2, 3); // 向量 A
const vectorB = new THREE.Vector3(4, 5, 6); // 向量 B
// 计算向量 A 到向量 B 的距离
const distance = vectorA.distanceTo(vectorB);
console.log(distance); // 输出: 5.196152422706632
- manhattanDistanceTo ( v : Vector3 ) : Float 在 Three.js 中,manhattanDistanceTo 方法用于计算当前向量与另一个向量之间的曼哈顿距离(也称为城市街区距离)。曼哈顿距离是计算两个点之间的距离时,不考虑对角线的方式,只沿着坐标轴进行移动。
// 创建两个 Vector3 对象
const vectorA = new THREE.Vector3(1, 2, 3); // 向量 A
const vectorB = new THREE.Vector3(4, 5, 6); // 向量 B
// 计算向量 A 到向量 B 的曼哈顿距离
const manhattanDistance = vectorA.manhattanDistanceTo(vectorB);
console.log(manhattanDistance); // 输出: 9 计算方式 4-1 = x 5-2 = y 6-3 = z
- distanceToSquared ( v : Vector3 ) : Float 在 Three.js 中,distanceToSquared 方法用于计算当前向量与另一个向量之间距离的平方。这种方法在需要比较距离而不需要实际计算距离时非常有用,因为它可以避免开方运算,提高性能。v表示B this 表示 A
- divide ( v : Vector3 ) : this 在 Three.js 中,divide 方法用于将当前向量与另一个向量的每个分量相除。这个操作通常用于实现向量的分量逐一相除,而不是简单的缩放。该方法返回对当前向量的修改,并允许链式调用。
// 创建两个 Vector3 对象
const vectorA = new THREE.Vector3(6, 8, 10); // 向量 A
const vectorB = new THREE.Vector3(2, 4, 5); // 向量 B
// 将向量 A 除以向量 B
vectorA.divide(vectorB);
console.log(vectorA); // 输出: Vector3 { x: 3, y: 2, z: 2 }
- divideScalar ( s : Float ) : this 将该向量除以标量s。
- dot ( v : Vector3 ) : Float 在 Three.js 中,dot 方法用于计算当前向量与另一个向量之间的点积(内积)。点积是两个向量的乘积,结果是一个标量值,表示这两个向量在相同方向上的投影的乘积。点积的结果与向量之间的角度有关。
- equals ( v : Vector3 ) : Boolean 检查该向量和v的严格相等性。
- floor () : this 向量的分量向下取整为最接近的整数值。
- fromArray ( array : Array, offset : Integer ) : this array - 来源矩阵。 offset - (可选)在数组中的元素偏移量,默认值为0。 设置向量中的x值为array[ offset + 0 ],y值为array[ offset + 1 ], z值为array[ offset + 2 ]。
- fromBufferAttribute ( attribute : BufferAttribute, index : Integer ) : this attribute - 来源的attribute。 index - 在attribute中的索引。 从attribute中设置向量的x值、y值和z值。
- getComponent ( index : Integer ) : Float index - 0, 1 or 2. 如果index值为0返回x值。 如果index值为1返回y值。 如果index值为2返回z值。
- length () : Float 计算从(0, 0, 0) 到 (x, y, z)的欧几里得长度 (Euclidean length,即直线长度)
- manhattanLength () : Float 在 Three.js 中,manhattanLength 方法用于计算当前向量的曼哈顿长度(也称为城市街区距离或绝对距离)。曼哈顿长度是通过计算向量各个分量的绝对值之和来得出的,表示从一个点到另一个点沿着坐标轴的总移动距离。
// 创建一个 Vector3 对象
const vector = new THREE.Vector3(3, -4, 5);
// 计算曼哈顿长度
const manhattanLength = vector.manhattanLength();
console.log(manhattanLength); // 输出: 12
- lengthSq () : Float 计算从(0, 0, 0)到(x, y, z)的欧几里得长度 (Euclidean length,即直线长度)的平方。 如果你正在比较向量的长度,应当比较的是长度的平方,因为它的计算效率更高一些。
- lerp ( v : Vector3, alpha : Float ) : this v - 朝着进行插值的Vector3。 alpha - 插值因数,其范围通常在[0, 1]闭区间。 在该向量与传入的向量v之间的线性插值,alpha是沿着线的长度的百分比 —— alpha = 0 时表示的是当前向量,alpha = 1 时表示的是所传入的向量v。
- lerpVectors ( v1 : Vector3, v2 : Vector3, alpha : Float ) : thisv1 - 起始的Vector3。 v2 - 朝着进行插值的Vector3。 alpha - 插值因数,其范围通常在[0, 1]闭区间。 将此向量设置为在v1和v2之间进行线性插值的向量, 其中alpha为两个向量之间连线的长度的百分比 —— alpha = 0 时表示的是v1,alpha = 1 时表示的是v2。
- max ( v : Vector3 ) : this 如果该向量的x值、y值或z值小于所传入v的x值、y值或z值, 则将该值替换为对应的最大值。
- min ( v : Vector3 ) : this 如果该向量的x值、y值或z值大于所传入v的x值、y值或z值, 则将该值替换为对应的最小值。
- multiply ( v : Vector3 ) : this 在 Three.js 中,multiply 方法用于将当前向量与另一个向量进行分量乘法运算。此操作会逐个分量相乘,并返回对当前向量的修改,允许链式调用。
- multiplyScalar ( s : Float ) : this 将该向量与所传入的标量s进行相乘。
- multiplyVectors ( a : Vector3, b : Vector3 ) : this 按照分量顺序,将该向量设置为和a * b相等。
- negate () : this 向量取反,即: x = -x, y = -y , z = -z。
- normalize () : this 将该向量转换为单位向量(unit vector), 也就是说,将该向量的方向设置为和原向量相同,但是其长度(length)为1。
// 创建一个 Vector3 对象
const vector = new THREE.Vector3(3, 4, 0); // 向量的坐标为 (3, 4, 0)
// 归一化向量
vector.normalize();
console.log(vector); // 输出: Vector3 { x: 0.6, y: 0.8, z: 0 }
console.log(vector.length()); // 输出: 1
- project ( camera : Camera ) : this 在 Three.js 中,project 方法的作用主要是将三维空间中的点转换为屏幕空间的二维坐标。这对于很多 3D 应用场景是非常重要的。
// 将3d座标转换为2d座标
// 假设有一个三维空间中的点
const vector = new THREE.Vector3(10, 20, 30);
// 使用相机投影该点到 2D 空间
vector.project(camera);
console.log('2D NDC 到屏幕坐标:', JSON.stringify(vector)); // 2D NDC 到屏幕坐标: {"x":-0.43440845761373525,"y":2.6064507456824115,"z":1.006867353402007}
// 将归一化设备坐标 (NDC) 转换为屏幕坐标
const screenX = (vector.x + 1) / 2 * window.innerWidth;
const screenY = -(vector.y - 1) / 2 * window.innerHeight;
console.log('2D 屏幕坐标:', screenX, screenY); // 2D 屏幕坐标: 414.0130090267458 -316.4707968994351
// 将2d座标转换为3d座标
// 创建一个平面,用于投射点击事件
const planeGeometry = new THREE.PlaneGeometry(100, 100);
const planeMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00, side: THREE.DoubleSide });
const plane = new THREE.Mesh(planeGeometry, planeMaterial);
// 旋转平面
plane.rotation.x = Math.PI / 4; // 绕 X 轴旋转 45 度
plane.rotation.y = Math.PI / 4; // 绕 Y 轴旋转 45 度
scene.add(plane);
// 创建 Raycaster 和一个 Vector2 来存储鼠标的 2D 屏幕坐标
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
// 处理鼠标点击事件
function onMouseClick(event) {
// 将鼠标屏幕坐标转换为归一化设备坐标 (NDC)
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
// 使用相机和鼠标坐标来更新射线投射
raycaster.setFromCamera(mouse, camera);
// 计算射线与平面的交点
const intersects = raycaster.intersectObject(plane);
if (intersects.length > 0) {
console.log('3D 坐标:', intersects[0].point); // { "x": 11.903928909641753, "y": 31.26228769964039, "z": 14.427589990099856 }
}
}
// 监听鼠标点击事件
window.addEventListener('click', onMouseClick, false);
- projectOnPlane ( planeNormal : Vector3 ) : this 在 Three.js 中,projectOnPlane 方法用于将一个三维向量投影到由给定法线定义的平面上。这个方法通常用于处理物体与平面之间的交互,尤其在物理模拟、碰撞检测和动画等场景中非常有用。
// 创建一个 Vector3 对象
const vector = new THREE.Vector3(3, 4, 5); // 原始向量
// 定义一个法向量,表示平面
const planeNormal = new THREE.Vector3(0, 1, 0); // Y 轴法向量,表示水平面
// 投影向量到平面
vector.projectOnPlane(planeNormal);
console.log('Projected Vector:', vector.x, vector.y, vector.z); // 输出投影后的向量 3,0,5
// 示例 2
// 创建一个 Vector3 对象
const vector = new THREE.Vector3(3, 4, 5); // 原始向量
// 定义一个法向量,表示平面(这里选择一个任意法向量)
const planeNormal = new THREE.Vector3(1, 1, 0).normalize(); // 正规化,确保长度为1
// 投影向量到平面
vector.projectOnPlane(planeNormal);
console.log('Projected Vector:', vector.x, vector.y, vector.z); // 输出投影后的向量 Projected Vector: -0.49999999999999956 0.5000000000000004 5