当前位置: 首页 > news >正文

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

文章目录

    • 前言
    • 一、向量(Vectors)
    • 二、矩阵(Matrices)
    • 三、四元数(Quaternions)
    • 四、欧拉角(Euler Angles)
    • 五、颜色(Colors)
    • 六、几何体生成器(Geometry Generators)
    • 七、随机数生成(Random Number Generation)
    • 八、时间和动画(Time and Animation)
    • 九、光线追踪与碰撞检测(Ray Tracing and Collision Detection)
    • 十、曲线与路径(Curves and Paths)
    • 十一、数学常量与实用函数(Math Constants and Utility Functions)
    • 结语


前言

在创建复杂的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 的数学能力都能为你提供强有力的支持。

相关文章:

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

文章目录 前言一、向量&#xff08;Vectors&#xff09;二、矩阵&#xff08;Matrices&#xff09;三、四元数&#xff08;Quaternions&#xff09;四、欧拉角&#xff08;Euler Angles&#xff09;五、颜色&#xff08;Colors&#xff09;六、几何体生成器&#xff08;Geometr…...

如何明智地提问

如何明智地提问的重要总结&#xff0c;让我为主要观点添加一些具体的实践建议&#xff1a; 提问前的准备工作 尝试在 Google、Stack Overflow 等平台搜索相似问题阅读相关文档和错误日志尝试自己调试和排查问题记录下已尝试过的解决方案 选择合适的提问平台 Stack Overflow…...

Microsoft Sql Server 2019 函数理解

说到函数&#xff0c;首先和存储过程作个比较吧&#xff0c;两者有一个共同点都是预编译优化后存储在磁盘中&#xff0c;所以效率 要比T-SQL高一点点。值得注意的是&#xff0c;存储过程可以创建或访问临时表&#xff0c;而函数不可以&#xff1b; 同时函数不可 以修改表中的数…...

自定义日期转换配置

文章目录 1.日期问题出现原因以及解决方案概述1.图示2.三种解决方案概述1.对于表单数据 application/x-www-form-urlencoded2.对于JSON数据1.使用JsonFormat注解2.自定义Jackson日期转换配置 2.解决方案common-web-starter1.目录2.BaseController.java 使用InitBinder解决表单数…...

“AI智能服务平台系统,让生活更便捷、更智能

大家好&#xff0c;我是资深产品经理老王&#xff0c;今天咱们来聊聊一个让生活变得越来越方便的高科技产品——AI智能服务平台系统。这个系统可是现代服务业的一颗璀璨明珠&#xff0c;它究竟有哪些魅力呢&#xff1f;下面我就跟大家伙儿闲聊一下。 一、什么是AI智能服务平台系…...

SQL美化器优化

文章目录 1.目录2.代码 1.目录 2.代码 package com.sunxiansheng.mybatis.plus.inteceptor;import org.apache.ibatis.executor.statement.StatementHandler; import org.apache.ibatis.mapping.*; import org.apache.ibatis.plugin.*; import org.apache.ibatis.reflection.*…...

我的128天创作之路:回顾与展望

大家好呀&#xff01;今天来和你们分享一下我的创作历程&#x1f601;。 一、机缘 最开始创作呢&#xff0c;是因为在学习 C 的 STL 时&#xff0c;像 string、list、vector 这些模板可把我折腾得够呛&#xff0c;但也让我学到了超多东西&#xff01;我就想&#xff0c;要是把我…...

内核配置参数整理

#参考网页 linux5.2 &#xff1c;.config&#xff1e;文件注释 详细解释 CONFIG_ARMy&#xff1a;启用ARM架构支持&#xff0c;这是ARM处理器专用的内核配置选项。 CONFIG_ARM_HAS_SG_CHAINy&#xff1a;启用对散列表&#xff08;scatter-gather&#xff09;链的支持&#xf…...

SpringBoot整合Easy-es

一.什么是Easy-Es Easy-Es&#xff08;简称EE&#xff09;是一款基于ElasticSearch(简称Es)官方提供的RestHighLevelClient打造的ORM开发框架&#xff0c;在 RestHighLevelClient 的基础上,只做增强不做改变&#xff0c;为简化开发、提高效率而生,您如果有用过Mybatis-Plus(简称…...

于交错的路径间:分支结构与逻辑判断的思维协奏

大家好啊&#xff0c;我是小象٩(๑ω๑)۶ 我的博客&#xff1a;Xiao Xiangζั͡ޓއއ 很高兴见到大家&#xff0c;希望能够和大家一起交流学习&#xff0c;共同进步。* 这一节内容很多&#xff0c;文章字数达到了史无前例的一万一&#xff0c;我们要来学习分支与循环结构中…...

Linux之读者写者模型与特殊锁的学习

目录 读者写者模型 特殊锁 悲观锁 自旋锁 在前几期&#xff0c;我们学习了多线程的生产者和消费者模型&#xff0c;生产者和消费者模型中&#xff0c;有三种关系&#xff0c;两个角色&#xff0c;一个场所&#xff0c;那么读者写者模型和生产者消费者模型有什么关联吗&…...

回溯专题 记录

回溯的题目按照这套模板进行&#xff1b; 我感觉整体逻辑还是递归&#xff0c;只不过有了pop_back才是回溯概念&#xff1b; class Solution {public:vector<int> path;vector<vector<int>> ans;void backtracking(int n,int k,int startindex){if(path.…...

使用 Python 实现自动化办公(邮件、Excel)

目录 一、Python 自动化办公的准备工作 1.1 安装必要的库 1.2 设置邮件服务 二、邮件自动化处理 2.1 发送邮件 示例代码 注意事项 2.2 接收和读取邮件 示例代码 三、Excel 自动化处理 3.1 读取和写入 Excel 文件 示例代码 3.2 数据处理和分析 示例代码 四、综合…...

贪心算法笔记

贪心算法笔记 大概内容 贪心就是对于一个问题有很多个步骤,我们在每一个步骤中都选取最优的那一个,最后得出答案。就是在一些函数中可行,但是有些比如二次函数,因为它的转折点不一定最优,就是不可行的。那么如何判断贪心呢?有这么几种 看时间复杂度,一般的就是 O ( n…...

Formality:两种等价状态consistency和equality

相关阅读 Formalityhttps://blog.csdn.net/weixin_45791458/category_12841971.html?spm1001.2014.3001.5482 背景 逻辑锥的等价性检查时&#xff0c;存在两种验证模式&#xff1a;一致(consistency)和等同(equality)&#xff0c;要理解这两点&#xff0c;首先得明白综合工具…...

Java Web开发基础:HTML的深度解析与应用

文章目录 前言&#x1f30d;一.B/S 软件开发架构简述&#x1f30d;二.HTML 介绍❄️2.1 官方文档❄️2.2 网页的组成❄️2.3 HTML 是什么❄️2.4html基本结构 &#x1f30d;三.HTML标签1.html 的标签/元素-说明2. html 标签注意事项和细节3.font 字体标签4.标题标签5.超链接标签…...

第30章 汇编语言--- 性能优化技巧

汇编语言是用于直接编程计算机硬件的低级语言&#xff0c;它几乎是一对一地映射到机器指令。因为汇编代码与特定处理器架构紧密相关&#xff0c;所以在讨论性能优化技巧时&#xff0c;通常需要考虑具体的CPU架构和指令集。 以下是一些通用的汇编语言性能优化技巧&#xff0c;并…...

HTB:Paper[WriteUP]

目录 连接至HTB服务器并启动靶机 信息收集 使用rustscan对靶机TCP端口进行开放扫描 将靶机TCP开放端口号提取并保存 使用nmap对靶机TCP开放端口进行脚本、服务扫描 使用nmap对靶机TCP开放端口进行漏洞、系统扫描 使用nmap对靶机常用UDP端口进行开放扫描 对靶机进行子域…...

数据库中的 DDL、DML 和 DCL

数据库中的 DDL、DML 和 DCL 在数据库的定义与操作中&#xff0c;DDL、DML 和 DCL 是三个核心概念&#xff0c;分别用于不同层面的数据库管理与操作。 1. DDL&#xff08;Data Definition Language&#xff09; - 数据定义语言 定义 DDL 用于定义和管理数据库的结构或模式。…...

OKR 极简史及理解

大家读完觉得有帮助记得点赞和关注&#xff01;&#xff01;&#xff01; 目录 MBO SMART 和 KPI OKR 1. 什么是 OKR&#xff1f; 1.1 Objectives&#xff08;目标&#xff09; 1.2 Key Results&#xff08;关键成果&#xff09; KR 应当是困难的&#xff0c;但并非不可…...

电商项目-基于ElasticSearch实现商品搜索功能(四)

一、 高亮显示 1.1 高亮分析 高亮显示是指根据商品关键字搜索商品的时候&#xff0c;显示的页面对关键字给定了特殊样式&#xff0c;让它显示更加突出&#xff0c;如商品搜索中&#xff0c;关键字变成了红色&#xff0c;其实就是给定了红色样式。 1.2 高亮搜索实现步骤解析 …...

TCP封装数据帧

void *send_data(void *arg) //这是一个发送数据的线程 {int sockfd init_tcp_cli("192.168.0.148",50000) //传ip和port&#xff0c;port 50000是因为大概前五万都被其它服务所占用&#xff0c;50000后是私人ipif(sockfd < 0){return NULL;}unsigned char …...

数据结构与算法之二叉树: LeetCode 515. 在每个树行中找最大值 (Ts版)

在每个树行中找最大值 https://leetcode.cn/problems/find-largest-value-in-each-tree-row/description/ 描述 给定一棵二叉树的根节点 root &#xff0c;请找出该二叉树中每一层的最大值 示例1 输入: root [1,3,2,5,3,null,9] 输出: [1,3,9]示例2 输入: root [1,2,3]…...

百度视频搜索架构演进

导读 随着信息技术的迅猛发展&#xff0c;搜索引擎作为人们获取信息的主要途径&#xff0c;其背后的技术架构也在不断演进。本文详细阐述了近年来视频搜索排序框架的重大变革&#xff0c;特别是在大模型技术需求驱动下&#xff0c;如何从传统的多阶段级联框架逐步演变为更加高…...

构造函数的原型原型链

代码示例 // 定义一个构造函数 Test function Test() {this.name 张三 }; //向构造函数的原型添加一个属性 age18 Test.prototype.age 18;//使用构造函数 Test 来实例化一个新对象 const test new Test();//向 Object.prototype 添加了一个名为 sex 的属性&#xff0c;其值…...

nginx反向代理及负载均衡

华子目录 nginx反向代理功能http反向代理反向代理配置参数proxy_pass的注意事项案例&#xff1a;反向代理单台后端服务器案例&#xff1a;反向代理实现动静分离案例&#xff1a;反向代理的缓存功能非缓存场景下测压准备缓存缓存场景下测压验证缓存文件 反向代理负载均衡&#x…...

单片机实物成品-011 火灾监测

火灾监测&#xff08;20个版本&#xff09; 版本20&#xff1a; oled显示温湿度烟雾浓度火焰传感器天然气浓度窗户风扇水泵排气系统声光报警语音播报按键WIFI模块 ----------------------------------------------------------------------------- https://www.bilibili.com…...

使用 Docker 在 Alpine Linux 下部署 Caddy 服务器

简介 在现代 web 开发中&#xff0c;选择合适的 web 服务器至关重要。Caddy 是一个功能强大的现代化 HTTP/2 服务器&#xff0c;支持自动 HTTPS&#xff0c;配置简单&#xff0c;适合开发和生产环境。Docker 则为我们提供了一种轻量级的容器化技术&#xff0c;使得应用程序的部…...

每日十题八股-2025年1月12日

1.为什么四次挥手之后要等2MSL? 2.服务端出现大量的timewait有哪些原因? 3.TCP和UDP区别是什么&#xff1f; 4.TCP为什么可靠传输 5.怎么用udp实现http&#xff1f; 6.tcp粘包怎么解决&#xff1f; 7.TCP的拥塞控制介绍一下&#xff1f; 8.描述一下打开百度首页后发生的网络过…...

Python中定位包含特定文本信息的元素

目录 一、为什么需要定位包含文本信息的元素 二、使用Selenium定位包含文本的元素 1. 使用find_element_by_link_text 2. 使用find_element_by_partial_link_text 3. 使用XPath定位包含文本的元素 4. 使用CSS选择器定位包含文本的元素 三、使用BeautifulSoup定位包含文本…...

深圳网站建设忧化/策划方案

这篇文章将教会大家如何利用 Postman&#xff0c;通过 Mock 的方式测试我们的 API。 什么是 Mock Mock 是一项特殊的测试技巧&#xff0c;可以在没有依赖项的情况下进行单元测试。通常情况下&#xff0c;Mock 与其他方法的主要区别就是&#xff0c;用于取代代码依赖项的模拟对…...

做seo网站推广价格/优化方案官方网站

问题及代码&#xff1a; /*。 *Copyright(c)2014,烟台大学计算机学院 *All right reserved, *文件名&#xff1a;test.cpp *作者&#xff1a;liu_feng_zi_ *完成日期&#xff1a;2015年3月1日 *版本号&#xff1a;v1.0 *问题描述&#xff1a; *输入描述&#xff1a; *…...

郑州响应式网站建设/推广软文发稿

keras框架为我们提供了一些常用的内置数据集。比如&#xff0c;图像识别领域的手写识别MNIST数据集、文本分类领域的电影影评imdb数据集等等。 数据地址&#xff1a; 链接: https://pan.baidu.com/s/138a6cbP_Pn-dQNIxaio0aw 提取码: sxih...

京津冀协同发展英文/seo怎么推排名

1075 链表元素分类 (25 分) 题目链接 算法分析 读入时&#xff0c;直接把各结点分成三类&#xff1a; 1.value < 0 2.value > 0 && valude < k 3.value > k 分别存到三个结构体数组中&#xff0c;然后再存回来&#xff08;便于输出&#xff09; 代…...

建设部网站危房鉴定标准规定/免费网站模板网

时间同步: 首先需了解linux内一任务计划工具crontabcrontab可以定时去执行你要做的动作直接用crontab命令编辑crontab -u //设定某个用户的cron服务&#xff0c;一般root用户在执行这个命令的时候需要此参数crontab -l //列出某个用户cron服务的详细内容crontab -r //删除某个用…...

区政府网站建设/企业员工培训课程内容

概念 序列化&#xff1a;将java对象转换为字节序列的过程叫做序列化 反序列化&#xff1a;将字节对象转换为java对象的过程叫做反序列化 要解决的问题 1.序列化时间 2.反序列化时间 3.bytes大小 4.操作方便 支持的数据类型和应用传输数据的格式是否恰当 例举几种方式序列化的方…...