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 天前
这是一个很酷的金属球,点击它会产生涟漪……
前端·javascript·three.js
胖虎2653 天前
Three.js 工业 3D 可视化:生产线状态监控系统实现方案
three.js
何贤6 天前
🪐 行星科技概念官网!Hero Section 回归!(Three.js ✨)
前端·javascript·three.js
爱看书的小沐6 天前
【小沐杂货铺】基于Three.js绘制三维管道Pipe(WebGL、vue、react)
javascript·vue.js·webgl·three.js·管道·pipe·三维管道
小码编匠8 天前
Three.js 遇上 Vue3 开发现代化 3D 可视化编辑系统
vue.js·typescript·three.js
阿明Drift10 天前
从炫酷粒子星云学 Three.js:深度解析一个 15 万粒子的 GPU 动画系统
前端·three.js
秋田君13 天前
3D热力图封装组件:Vue + Three.js 实现3D图表详解
javascript·vue.js·3d·three.js·热力图
Mintopia16 天前
🌌 Three.js 几何变化动画配合噪声粒子教程:让你的代码也会“呼吸”
前端·javascript·three.js
爱看书的小沐21 天前
【小沐杂货铺】基于Three.js渲染三维风力发电机(WebGL、vue、react、WindTurbine)
javascript·vue.js·webgl·three.js·opengl·风力发电机·windturbine