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

相关推荐
CAD老兵2 天前
打造高性能二维图纸渲染引擎系列(一):Batched Geometry 助你轻松渲染百万实体
前端·webgl·three.js
CAD老兵2 天前
打造高性能二维图纸渲染引擎系列(三):高性能 CAD 文本渲染背后的隐藏工程
前端·webgl·three.js
CAD老兵2 天前
打造高性能二维图纸渲染引擎系列(二):创建结构化和可扩展的渲染场景
前端·webgl·three.js
勤奋菲菲3 天前
Vue3+Three.js:requestAnimationFrame的详细介绍
开发语言·javascript·three.js·前端可视化
小兔崽子去哪了7 天前
Three.js 曲线
three.js
Keepreal4968 天前
使用 Three.js 和 GSAP 动画库实现3D 名字抽奖
javascript·vue.js·three.js
Jedi Hongbin9 天前
Three.js NodeMaterial 节点材质系统文档
前端·javascript·three.js·nodematerial
入秋9 天前
Three.js后期处理实战:噪点 景深 以及色彩调整
前端·javascript·three.js
答案answer9 天前
你不知道的Three.js性能优化和使用小技巧
前端·性能优化·three.js
爱看书的小沐10 天前
【小沐学WebGIS】基于Three.JS绘制飞行轨迹Flight Tracker(Three.JS/ vue / react / WebGL)
javascript·vue·webgl·three.js·航班·航迹·飞行轨迹