THREE.Ray 和 THREE.Raycaster 用途和功能

在 ​Three.js ​ 中,THREE.RayTHREE.Raycaster 都是与射线(Ray)相关的类,但它们的用途和功能有所不同。

例如 如图射线检测

1. THREE.Ray(射线)​

THREE.Ray 表示一条 ​3D 空间中的射线 ,由 ​起点(origin)​ ​ 和 ​方向(direction)​​ 定义。它主要用于数学计算,比如检测射线与物体的交点、计算距离等。

基本用法

javascript 复制代码
const origin = new THREE.Vector3(0, 0, 0);  // 射线起点
const direction = new THREE.Vector3(0, 0, 1).normalize();  // 射线方向(单位向量)

const ray = new THREE.Ray(origin, direction);

常用方法

方法 说明
ray.intersectBox(box, target) 计算射线与包围盒(Box3)的交点
ray.intersectPlane(plane, target) 计算射线与平面(Plane)的交点
ray.distanceToPoint(point) 计算射线到某点的最短距离
ray.closestPointToPoint(point, target) 计算射线上离某点最近的点

实战,两个点绘制箭头

csharp 复制代码
const pointer7 = pointers[0]; // 起点
      const pointer8 = pointers[1]; // 终点
      // 更新手部指针位置
      handPointer.set(pointer8.x, pointer8.y, pointer8.z);
      // 更新球体位置(可视化手指位置)
      fingerSphere.position.copy(handPointer);
      // 计算正确的射线方向(终点 - 起点,并归一化)
      const direction = new THREE.Vector3().subVectors(
        new THREE.Vector3(pointer8.x, pointer8.y, pointer8.z), // 终点
        new THREE.Vector3(pointer7.x, pointer7.y, pointer7.z)   // 起点
      ).normalize();// 注意这里的归一化
      if (handIndex == 0) {
        // 设置射线起点和方向
        rayHand1.origin.set(pointer7.x, pointer7.y, pointer7.z);
        rayHand1.direction.copy(direction);
        // 移除旧的箭头(如果存在)
        if (arrowHelper1) {
          handScene.remove(arrowHelper1);
        }
        // 创建新的箭头(方向正确)
        arrowHelper1 = new THREE.ArrowHelper(
          direction,                  // 归一化的方向向量
          rayHand1.origin,             // 起点
          arrowLen,                         // 箭头长度
          0x0000ff,                   // 颜色(黄色)
          arrowLen * 0.2,                        // 头部长度(可选)
          arrowLen * 0.04                         // 头部宽度(可选)
        );

        handScene.add(arrowHelper1);
      } else {
        // 设置射线起点和方向
        rayHand2.origin.set(pointer7.x, pointer7.y, pointer7.z);
        rayHand2.direction.copy(direction);
        // 移除旧的箭头(如果存在)
        if (arrowHelper2) {
          handScene.remove(arrowHelper2);
        }

        // 创建新的箭头(方向正确)
        arrowHelper2 = new THREE.ArrowHelper(
          direction,                  // 归一化的方向向量
          rayHand2.origin,             // 起点
          arrowLen,                         // 箭头长度
          0x0000ff,                   // 颜色(黄色)
          arrowLen * 0.2,                        // 头部长度(可选)
          arrowLen * 0.04                         // 头部宽度(可选)
        );

        handScene.add(arrowHelper2);
      }

2. THREE.Raycaster(射线投射器)​

THREE.Raycaster 是一个更高级的工具,用于 ​检测射线与 3D 场景中的物体(Mesh、Points、Line 等)的交点 。它常用于 ​鼠标拾取(点击检测)、碰撞检测、视线检测​ 等交互功能。

基本用法

javascript 复制代码
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();  // 归一化的鼠标坐标 [-1, 1]

// 更新射线(从相机位置发射到鼠标方向)
raycaster.setFromCamera(mouse, camera);

// 检测射线与场景中的物体相交
const intersects = raycaster.intersectObjects(scene.children);

if (intersects.length > 0) {
    console.log("点击了物体:", intersects[0].object);
}

常用方法

方法 说明
raycaster.set(origin, direction) 手动设置射线
raycaster.setFromCamera(coords, camera) 从相机视角发射射线(用于鼠标拾取)
raycaster.intersectObject(object, recursive) 检测射线与单个物体的交点
raycaster.intersectObjects(objects, recursive) 检测射线与多个物体的交点

示例:鼠标点击拾取物体

javascript 复制代码
window.addEventListener('click', (event) => {
    // 归一化鼠标坐标 [-1, 1]
    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

    // 更新射线
    raycaster.setFromCamera(mouse, camera);

    // 检测相交物体
    const intersects = raycaster.intersectObjects(scene.children);

    if (intersects.length > 0) {
        console.log("点击了:", intersects[0].object);
    }
});

3. THREE.Ray vs THREE.Raycaster

THREE.Ray THREE.Raycaster
用途 数学计算(距离、交点) 场景交互(鼠标拾取、碰撞检测)
依赖 仅依赖 THREE.Vector3 依赖 THREE.CameraTHREE.Scene
计算方式 手动计算射线与几何体的交点 自动检测射线与 3D 物体的交点
适用场景 计算射线与平面、包围盒的交点 检测鼠标点击、视线检测

4. 总结

  • THREE.Ray:用于 数学计算,如射线与几何体的交点、距离计算等。
  • THREE.Raycaster:用于 场景交互,如鼠标拾取、碰撞检测等。
  • Raycaster 内部使用了 Ray**,但提供了更高级的功能,可以直接检测 3D 物体。

如果你要做 ​鼠标交互 ​(如点击选中物体),用 ​Raycaster

如果你要做 ​数学计算 ​(如射线与平面的交点),用 ​Ray

相关推荐
阿里巴啦2 天前
用React+Three.js 做 3D Web版搭建三维交互场景:模型的可视化摆放与轻量交互
前端·react·three.js·模型可视化·web三维·web三维交互场景
阿里巴啦4 天前
React + Three.js + R3F + Vite 实战:可交互的三维粒子化展厅
react.js·three.js·粒子化·drei·postprocessing·三维粒子化
叫我詹躲躲5 天前
基于 Three.js 的 3D 地图可视化:核心原理与实现步骤
前端·three.js
map_3d_vis5 天前
JSAPIThree 加载单体三维模型学习笔记:SimpleModel 简易加载方式
学习笔记·three.js·gltf·glb·初学者·三维模型·mapvthree·jsapithree·simplemodel
Addisonx9 天前
深度复盘 III: 核心逻辑篇:构建 WebGL 数字孪生的“业务中枢”与“安全防线”
webgl·three.js
爱看书的小沐9 天前
【小沐学WebGIS】基于Three.JS绘制二三维地图地球晨昏效果(WebGL / vue / react )
javascript·vue.js·gis·webgl·three.js·opengl·晨昏线
Addisonx12 天前
深度复盘: WebGL 数字孪生前端架构:如何打造高颜值、高性能的 Web 3D 可视化系统
three.js
BUG创建者14 天前
thee.js完成线上展厅demo
开发语言·前端·javascript·css·html·css3·three.js
一千柯橘23 天前
从摄影新手到三维光影师:Three.js 核心要素的故事
前端·three.js
big男孩25 天前
OrbitControls 的完整原理
three.js