在Three.js中,THREE.Vector3
是一个非常重要的类,用于表示三维空间中的点或向量。它提供了丰富的功能来操作三维坐标和向量,如平移、旋转、缩放、计算距离、法线等。掌握 Vector3
类的使用对于处理三维图形和动画非常重要。
主要用途
- 表示位置:用作物体的位置。
- 表示方向:用作方向向量,例如光线的方向或相机的朝向。
- 数学运算:进行各种向量运算,如加法、减法、点积、叉积等。
基本用法
创建 Vector3 实例
const vector = new THREE.Vector3(x, y, z);
x
,y
,z
:向量的三个分量,默认值为0。
访问和修改属性
你可以直接访问和修改 Vector3
对象的 x
, y
, z
属性:
vector.x = 1;
vector.y = 2;
vector.z = 3;
console.log(vector.x); // 输出 1
console.log(vector.y); // 输出 2
console.log(vector.z); // 输出 3
常用方法
向量运算
-
加法(add)
const v1 = new THREE.Vector3(1, 2, 3); const v2 = new THREE.Vector3(4, 5, 6); v1.add(v2); // v1 现在是 (5, 7, 9)
-
减法(sub)
const v1 = new THREE.Vector3(5, 7, 9); const v2 = new THREE.Vector3(4, 5, 6); v1.sub(v2); // v1 现在是 (1, 2, 3)
-
乘法(multiplyScalar)
const v = new THREE.Vector3(1, 2, 3); v.multiplyScalar(2); // v 现在是 (2, 4, 6)
-
点积(dot)
const v1 = new THREE.Vector3(1, 2, 3); const v2 = new THREE.Vector3(4, 5, 6); const dotProduct = v1.dot(v2); // 结果是 1*4 + 2*5 + 3*6 = 32
-
叉积(cross)
const v1 = new THREE.Vector3(1, 2, 3); const v2 = new THREE.Vector3(4, 5, 6); v1.cross(v2); // v1 现在是 (-3, 6, -3)
其他常用方法
-
归一化(normalize)
将向量转换为单位向量(长度为1):
const v = new THREE.Vector3(1, 2, 3); v.normalize(); // v 现在是一个单位向量
-
计算长度(length)
返回向量的欧几里得长度:
const v = new THREE.Vector3(1, 2, 3); const length = v.length(); // 长度为 sqrt(1^2 + 2^2 + 3^2) ≈ 3.74
-
计算与另一个向量的距离(distanceTo)
const v1 = new THREE.Vector3(1, 2, 3); const v2 = new THREE.Vector3(4, 5, 6); const distance = v1.distanceTo(v2); // 距离为 sqrt((4-1)^2 + (5-2)^2 + (6-3)^2) ≈ 5.196
-
克隆向量(clone)
创建当前向量的一个副本:
const v1 = new THREE.Vector3(1, 2, 3); const v2 = v1.clone(); // v2 现在是 (1, 2, 3)
-
设置向量的值(set)
修改向量的 x, y, z 值:
const v = new THREE.Vector3(); v.set(1, 2, 3); // v 现在是 (1, 2, 3)
示例代码
以下是一个完整的示例,展示如何使用 THREE.Vector3
进行各种操作:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Three.js Vector3 Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body { margin: 0; }
canvas { display: block; }
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r152/three.min.js"></script>
<script>
let scene, camera, renderer;
init();
animate();
function init() {
// 创建场景
scene = new THREE.Scene();
// 创建相机
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 10;
// 创建渲染器
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 创建几何体和材质
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
// 使用 Vector3 设置立方体的位置
const position = new THREE.Vector3(2, 2, 0);
cube.position.copy(position);
scene.add(cube);
// 添加一些其他几何体作为参考
const sphereGeometry = new THREE.SphereGeometry(0.5, 32, 32);
const sphereMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
const spherePosition = new THREE.Vector3(-2, -2, 0);
sphere.position.copy(spherePosition);
scene.add(sphere);
// 监听窗口调整大小事件
window.addEventListener('resize', onWindowResize, false);
// 执行一些 Vector3 操作并打印结果
const v1 = new THREE.Vector3(1, 2, 3);
const v2 = new THREE.Vector3(4, 5, 6);
console.log("v1:", v1);
console.log("v2:", v2);
v1.add(v2);
console.log("v1 after adding v2:", v1);
v1.sub(v2);
console.log("v1 after subtracting v2:", v1);
v1.multiplyScalar(2);
console.log("v1 after multiplying by scalar 2:", v1);
const dotProduct = v1.dot(v2);
console.log("Dot product of v1 and v2:", dotProduct);
v1.cross(v2);
console.log("v1 after cross product with v2:", v1);
v1.normalize();
console.log("Normalized v1:", v1);
const length = v1.length();
console.log("Length of v1:", length);
const distance = v1.distanceTo(v2);
console.log("Distance between v1 and v2:", distance);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
// 旋转几何体(可选)
scene.children[0].rotation.x += 0.01;
scene.children[0].rotation.y += 0.01;
renderer.render(scene, camera);
}
</script>
</body>
</html>
详细解释
初始化部分
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 10;
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
- 创建场景、相机和渲染器,并将其添加到页面中。
创建几何体并使用 Vector3 设置位置
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
const position = new THREE.Vector3(2, 2, 0);
cube.position.copy(position);
scene.add(cube);
- 创建一个立方体,并使用
Vector3
设置其位置。 - 将立方体添加到场景中。
执行一些 Vector3 操作并打印结果
const v1 = new THREE.Vector3(1, 2, 3);
const v2 = new THREE.Vector3(4, 5, 6);
console.log("v1:", v1);
console.log("v2:", v2);
v1.add(v2);
console.log("v1 after adding v2:", v1);
v1.sub(v2);
console.log("v1 after subtracting v2:", v1);
v1.multiplyScalar(2);
console.log("v1 after multiplying by scalar 2:", v1);
const dotProduct = v1.dot(v2);
console.log("Dot product of v1 and v2:", dotProduct);
v1.cross(v2);
console.log("v1 after cross product with v2:", v1);
v1.normalize();
console.log("Normalized v1:", v1);
const length = v1.length();
console.log("Length of v1:", length);
const distance = v1.distanceTo(v2);
console.log("Distance between v1 and v2:", distance);
- 创建两个
Vector3
实例v1
和v2
。 - 执行一系列向量操作,并将结果打印到控制台。
动画循环
function animate() {
requestAnimationFrame(animate);
// 旋转几何体(可选)
scene.children[0].rotation.x += 0.01;
scene.children[0].rotation.y += 0.01;
renderer.render(scene, camera);
}
- 在每一帧中更新几何体的旋转角度(可选)。
- 调用
renderer.render
渲染当前帧。
总结
THREE.Vector3
提供了丰富的功能来处理三维向量和点,包括基本的数学运算和更复杂的操作,如归一化、点积、叉积等。通过这些操作,你可以方便地处理三维空间中的位置和方向问题。希望这个示例和解释能帮助你更好地理解和使用 THREE.Vector3
类。
前端工程师、程序员
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
2018-03-05 centos 支持安装libsodium