首页 > 其他分享 >Three.js 数学工具:构建精确3D世界的基石

Three.js 数学工具:构建精确3D世界的基石

时间:2025-01-09 14:32:44浏览次数:3  
标签:const Vector3 THREE Three new js 3D

文章目录


前言

在创建复杂的3D图形和动画时,数学扮演着不可或缺的角色。Three.js 提供了一套强大且易于使用的数学工具库,这些工具帮助开发者处理从基本的几何变换到高级物理模拟的各种任务。本文将深入探讨 Three.js 中提供的数学工具,并通过具体的代码示例来说明如何利用它们为你的项目增添精度与灵活性。


一、向量(Vectors)

向量是表示位置、方向或速度等概念的基础数据结构。Three.js 支持多种类型的向量,包括 Vector2, Vector3Vector4,分别用于二维、三维和四维空间中的计算。

创建和操作向量

// 创建一个三维向量
const vector = new THREE.Vector3(1, 0, 0);

// 执行基本运算
vector.add(new THREE.Vector3(0, 1, 0)); // 加法
vector.sub(new THREE.Vector3(0, 1, 0)); // 减法
vector.multiplyScalar(2);               // 标量乘法
vector.normalize();                     // 归一化

// 计算两个向量之间的角度
const angle = vector.angleTo(new THREE.Vector3(0, 1, 0));

// 计算点积和叉积
const dotProduct = vector.dot(new THREE.Vector3(0, 1, 0));
const crossProduct = vector.cross(new THREE.Vector3(0, 1, 0));

// 应用到对象的位置或旋转
object.position.copy(vector);
object.quaternion.setFromUnitVectors(object.up, vector);

二、矩阵(Matrices)

矩阵用于描述物体的空间变换,如平移、旋转和缩放。Three.js 提供了 Matrix4 类来进行这些操作,并支持矩阵之间的乘法以组合多个变换。

应用矩阵变换

// 创建一个四元数并应用旋转
const quaternion = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI / 4);
const matrix = new THREE.Matrix4();
matrix.makeRotationFromQuaternion(quaternion);

// 将矩阵应用于对象
object.applyMatrix4(matrix);

// 组合平移、旋转和缩放
const translateMatrix = new THREE.Matrix4().makeTranslation(1, 0, 0);
const rotationMatrix = new THREE.Matrix4().makeRotationX(Math.PI / 4);
const scaleMatrix = new THREE.Matrix4().makeScale(2, 1, 1);

// 组合所有变换
const combinedMatrix = new THREE.Matrix4();
combinedMatrix.multiplyMatrices(translateMatrix, rotationMatrix);
combinedMatrix.multiply(scaleMatrix);

// 应用组合后的矩阵
object.applyMatrix4(combinedMatrix);

三、四元数(Quaternions)

四元数是一种高效的旋转表示方法,避免了万向锁问题。Three.js 的 Quaternion 类提供了简单易用的接口来管理旋转。

使用四元数进行旋转

// 创建一个四元数并设置旋转角度
const quaternion = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI / 4);

// 应用旋转到对象
object.quaternion.copy(quaternion);

// 插值两个四元数之间的旋转
const targetQuaternion = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI / 2);
quaternion.slerp(targetQuaternion, 0.5); // 线性插值

// 更新对象的旋转
object.quaternion.copy(quaternion);

四、欧拉角(Euler Angles)

欧拉角提供了一种直观的方式来指定旋转顺序,尽管它容易导致万向锁的问题。Three.js 的 Euler 类允许你定义绕 X、Y 和 Z 轴的旋转角度。

使用欧拉角进行旋转

// 创建一个欧拉角实例
const euler = new THREE.Euler(Math.PI / 4, 0, 0, 'XYZ');

// 应用到对象的旋转属性
object.rotation.setFromEuler(euler);

// 修改欧拉角的值
euler.x += Math.PI / 8;
object.rotation.setFromEuler(euler);

// 注意:避免直接修改 rotation 属性,因为这可能导致不一致的状态

五、颜色(Colors)

颜色不仅是视觉效果的重要组成部分,而且在材质和光照中也起着关键作用。Three.js 的 Color 类简化了颜色的创建和操作。

创建和操作颜色

// 创建一个颜色实例
const color = new THREE.Color(0xff0000); // 红色

// 修改颜色值
color.setRGB(0, 1, 0); // 变为绿色
color.setHSL(0.5, 1, 0.5); // 使用 HSL 设置颜色

// 应用到材质
material.color.copy(color);

// 获取颜色的十六进制表示
console.log(`颜色的十六进制表示: ${color.getHexString()}`);

// 设置颜色的透明度
material.opacity = 0.5;
material.transparent = true; // 必须开启透明度

六、几何体生成器(Geometry Generators)

Three.js 提供了一系列内置的几何体生成器,如 BoxGeometry, SphereGeometry 等,用于快速创建常见形状。此外,还可以通过自定义顶点和面来构建复杂的几何体。

创建几何体

// 创建一个立方体几何体
const geometry = new THREE.BoxGeometry(1, 1, 1);

// 创建一个球体几何体
const sphereGeometry = new THREE.SphereGeometry(0.5, 32, 32);

// 自定义几何体
const customGeometry = new THREE.Geometry();
customGeometry.vertices.push(
    new THREE.Vector3(-1, -1, 0),
    new THREE.Vector3(1, -1, 0),
    new THREE.Vector3(0, 1, 0)
);
customGeometry.faces.push(new THREE.Face3(0, 1, 2));

// 创建网格并添加到场景
const mesh = new THREE.Mesh(customGeometry, material);
scene.add(mesh);

七、随机数生成(Random Number Generation)

虽然 Three.js 没有直接提供随机数生成函数,但可以结合 JavaScript 的 Math.random() 来实现这一功能,这对于创建程序化内容非常有用。

生成随机数

// 生成介于 min 和 max 之间的随机浮点数
function getRandomFloat(min, max) {
    return (max - min) * Math.random() + min;
}

// 示例:生成随机位置的球体
for (let i = 0; i < 100; i++) {
    const sphere = new THREE.Mesh(
        new THREE.SphereGeometry(0.1, 16, 16),
        new THREE.MeshBasicMaterial({ color: 0xffffff * Math.random() })
    );
    sphere.position.set(
        getRandomFloat(-5, 5),
        getRandomFloat(-5, 5),
        getRandomFloat(-5, 5)
    );
    scene.add(sphere);
}

八、时间和动画(Time and Animation)

时间管理对于创建流畅的动画至关重要。Three.js 提供了 Clock 类来跟踪时间,并结合 requestAnimationFrame 实现平滑的动画更新。

管理时间和动画

// 创建一个时钟实例
const clock = new THREE.Clock();

// 在动画循环中获取经过的时间
function animate() {
    requestAnimationFrame(animate);

    const delta = clock.getDelta(); // 获取上一帧到当前帧的时间差
    object.rotation.x += delta * 0.1; // 根据时间调整旋转速度

    renderer.render(scene, camera);
}
animate();

// 使用 Tween.js 进行补间动画
import { Tween } from '@tweenjs/tween.js';

new Tween(object.position)
    .to({ x: 5 }, 1000) // 目标位置和持续时间
    .start();

九、光线追踪与碰撞检测(Ray Tracing and Collision Detection)

光线追踪用于模拟光的行为,而碰撞检测则用于确定物体是否相交。Three.js 提供了 Raycaster 类来实现这两种功能。

// 创建 Raycaster 和鼠标位置变量
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();

// 监听鼠标点击事件
window.addEventListener('click', (event) => {
    // 将鼠标位置标准化为设备坐标 (-1 到 +1)
    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

    // 更新 Raycaster 的方向向量
    raycaster.setFromCamera(mouse, camera);

    // 检查交点
    const intersects = raycaster.intersectObjects(scene.children);
    if (intersects.length > 0) {
        console.log('点击的对象:', intersects[0].object);
    }
});

// 碰撞检测
function checkCollisions(objectA, objectB) {
    const distance = objectA.position.distanceTo(objectB.position);
    return distance < (objectA.geometry.boundingSphere.radius + objectB.geometry.boundingSphere.radius);
}

十、曲线与路径(Curves and Paths)

曲线和路径用于定义物体的运动轨迹或其他复杂形状。Three.js 提供了多种曲线类型,如 LineCurve3, CubicBezierCurve3SplineCurve

创建和使用曲线

// 创建一条贝塞尔曲线
const curve = new THREE.CubicBezierCurve3(
    new THREE.Vector3(-1, 0, 0),
    new THREE.Vector3(-0.5, 1, 0),
    new THREE.Vector3(0.5, 1, 0),
    new THREE.Vector3(1, 0, 0)
);

// 获取曲线上某一点的位置
const point = curve.getPoint(0.5);

// 创建路径并添加到场景
const path = new THREE.Path(curve.getPoints(50));
const geometry = path.createPointsGeometry();
const material = new THREE.LineBasicMaterial({ color: 0x0000ff });
const line = new THREE.Line(geometry, material);
scene.add(line);

十一、数学常量与实用函数(Math Constants and Utility Functions)

Three.js 提供了一些常用的数学常量和实用函数,如 MathUtils,方便进行各种数学运算。

使用数学常量和实用函数

// 使用 PI 常量
const pi = Math.PI;

// 使用 MathUtils 中的方法
const radians = THREE.MathUtils.degToRad(90); // 将度数转换为弧度
const degrees = THREE.MathUtils.radToDeg(radians); // 将弧度转换为度数

// 计算两点间的距离
const distance = THREE.MathUtils.euclideanModulo(pointA.x - pointB.x, 10);

结语

Three.js 的数学工具不仅限于上述几种方式,还包括更多高级特性,如光线追踪、碰撞检测等。掌握这些数学工具,可以帮助你在创建3D内容时提供更加精确和灵活的操作。无论你是希望构建一个教育性的演示文稿,还是开发一款复杂的游戏,Three.js 的数学能力都能为你提供强有力的支持。

标签:const,Vector3,THREE,Three,new,js,3D
From: https://blog.csdn.net/chaosweet/article/details/145032304

相关文章

  • 80个Three.js 3D模型资源
    Three.js3D模型资源”涵盖了在WebGL和JavaScript环境下使用three.js库进行3D建模和渲染的基础知识。Three.js是目前最流行的JavaScript库之一,用于创建和展示交互式的3D图形。它允许开发者在浏览器中直接构建复杂的三维场景,无需深入学习底层的WebGLAPI。Party1让我们了解......
  • 前端必知必会-Node.js 模块
    文章目录Node.js模块什么是Node.js中的模块?内置模块包含模块创建您自己的模块包含您自己的模块总结Node.js模块什么是Node.js中的模块?将模块视为与JavaScript库相同。您想要包含在应用程序中的一组函数。内置模块Node.js有一组内置模块,您无需进一步安......
  • 前端必知必会-Node.js HTTP 模块
    文章目录Node.jsHTTP模块内置HTTP模块Node.js作为Web服务器添加HTTP标头读取查询字符串拆分查询字符串总结Node.jsHTTP模块内置HTTP模块Node.js有一个名为HTTP的内置模块,它允许Node.js通过超文本传输​​协议(HTTP)传输数据。要包含HTTP模......
  • 前端必知必会-Node.js File System模块
    文章目录Node.js文件系统模块Node.js作为文件服务器创建文件更新文件删除文件重命名文件上传文件总结Node.js文件系统模块Node.js作为文件服务器Node.js文件系统模块允许您使用计算机上的文件系统。要包含文件系统模块,请使用require()方法:``jsvarfs=......
  • JS将docx转为html代码--Vue3(简易版)
    这两天突然接了一个把节气文章转成html页面的需求,本来只是需要多按几下ctrl+c,ctrl+v能解决的事,但是想想后续一年24个节气,就做个自动转换的工具吧。由于做软件还涉及到其他语言和配置环境,所以还是选择了web。首先创建一个vue3项目,我用的vite搭建的,不会的请自行移步到vite官网。......
  • (免费源码)计算机毕业设计必学必看 万套实战教程 java、python、php、node.js、c#、APP
    摘 要随着互联网时代的到来,同时计算机网络技术高速发展,网络管理运用也变得越来越广泛。因此,建立一个B/S结构的中医病案管理系统,会使;中医病案管理系统的管理工作系统化、规范化,也会提高平台形象,提高管理效率。本系统是针对目前中医病案管理系统的实际需求,从实际工作出发,对过......
  • (免费源码)计算机毕业设计必学必看 万套实战教程 java、python、php、node.js、c#、APP
    摘 要随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,志愿服务管理小程序被用户普遍使用,方便用户能够可以随时进行在线查看志愿服务管理的数据信息管理,特开发了志愿服务管理......
  • Vue.js 表单
    本帖主要学习Vue.js表单上的应用。可以用v-model指令在表单控件元素上创建双向数据绑定。v-model会根据控件类型自动选取正确的方法来更新元素。<!DOCTYPEhtml><html><head><metacharset="utf-8"><title>Vue测试实例</title><scriptsrc="https://cdn.staticfi......
  • Vue.js 自定义指令
    除了默认设置的核心指令(v-model和v-show),Vue也允许注册自定义指令。下面我们注册一个全局指令v-focus,该指令的功能是在页面加载时,元素获得焦点:<!DOCTYPEhtml><html><head><metacharset="utf-8"><title>Vue测试实例</title><scriptsrc="https://cdn.stati......
  • python+django/flask的社区汽车共享平台java+nodejs+php-计算机毕业设计
    目录技术栈和环境说明具体实现截图预期达到的目标系统设计详细视频演示技术路线解决的思路性能/安全/负载方面可行性分析论证python-flask核心代码部分展示python-django核心代码部分展示研究方法感恩大学老师和同学源码获取技术栈和环境说明本系统以Python开发语言......