Three.js-硬要自学系列32之专项学习箭头辅助器

箭头辅助器是什么

想象一下我们在玩一个3D建造游戏或者看一个科学模拟动画。如果想直观地看到:

  1. 这个物体是朝哪边转的? (比如一个陀螺的旋转轴)
  2. 这个力是往哪个方向推的? (比如一阵风吹的方向)
  3. 这个灯光是照向哪里的? (比如手电筒的光束方向)
  4. 摄像机是看向哪里的? (比如你的第一人称视角方向)

three.js中提供了一个可视化工具 ArrowHelper ,专门用来在3D场景中绘制一个箭头,方便清楚地标出某个方向。

核心参数

  1. 方向 (dir): 这是最关键 的!你需要用一个 THREE.Vector3 向量来表示箭头指向哪里。比如:

    • new THREE.Vector3(1, 0, 0) 表示指向 X 轴正方向 (右边)。
    • new THREE.Vector3(0, 1, 0) 表示指向 Y 轴正方向 (上边)。
    • new THREE.Vector3(0, 0, 1) 表示指向 Z 轴正方向 (屏幕外/前方)。
    • 也可以是 (0.5, 0.5, 0) 这样指向斜上方的向量。
  2. 起点 (origin): 箭头从 3D 空间的哪个位置开始画?也是用一个 THREE.Vector3 表示坐标点。默认通常是世界的中心 (0, 0, 0)

  3. 长度 (length): 箭头画多长?一个数字。太短看不清,太长可能穿模。默认值通常够用(比如 1)。

  4. 颜色 (color): 箭头涂成什么颜色?可以是 0xff0000 (红色), 0x00ff00 (绿色), 0x0000ff (蓝色) 等等。默认是红色。

主要作用

  • 直观调试: 这是它最主要的目的!让我们在开发 3D 应用时能 亲眼看到 抽象的方向信息。
  • 视觉参考: 在场景中提供清晰的方向标识,帮助用户理解朝向。
  • 标记位置和朝向: 可以附加到物体上,实时显示该物体的朝向(比如飞船的机头方向)。
  • 可视化向量: 物理模拟中的速度、力、加速度等向量,用箭头表示一目了然。

实时改变箭头指示方向的案例

效果如图

需要了解的API

ArrowHelper

可视化方向工具 ,用于在 3D 场景中绘制带箭头的线段,直观展示 方向、力、旋转轴等抽象概念

参数 类型 作用 默认值/示例
dir THREE.Vector3 箭头指向的方向 new THREE.Vector3(1, 0, 0) (X轴)
origin THREE.Vector3 箭头的起点坐标 new THREE.Vector3(0, 0, 0) (场景原点)
length Number 箭头总长度(杆+锥头) 1
color Number (十六进制) 箭头颜色 0xff0000 (红色)

典型问题解决方法

  • 箭头不可见?
    检查是否添加至场景:scene.add(arrowHelper)
    确认相机位置是否覆盖箭头区域。
  • 方向相反?
    向量定义错误:new THREE.Vector3(-1,0,0) 指向X轴负方向。
  • 箭头穿透物体?
    调整 length 参数或使用 Raycaster 检测碰撞点作为起点。

实现思路

js 复制代码
const arrow = new THREE.ArrowHelper(new THREE.Vector3(0, 1, 0), new THREE.Vector3(0, 0, 0), 3, "deepskyblue");
scene.add(arrow);

这里在场景中添加了一个长度为3,指向(0,1,0)Y轴方向的蓝色箭头

js 复制代码
let frame = 0;
const maxFrame = 500;
function animation() {
    const per = frame / maxFrame,
    rad = Math.PI * 2 * per, // 弧度制,0~2π
    x = Math.cos(rad),        // 0~1
    y = Math.sin(rad);  // 0~1
    const dir = new THREE.Vector3(x, y, 0).normalize();
    arrow.setDirection(dir);
    frame++;
    frame %= maxFrame;
    renderer.render( scene, camera );
    requestAnimationFrame( animation );  
}

通过arrow.setDirection(dir)设置方向,从而实现上图效果

沿指定方向移动

效果如图

创建一个球体和箭头辅助器,如下

js 复制代码
let V = new THREE.Vector3(1,1,0),
DIR = V.normalize(),
LENGTH = 5;

const arrow = new THREE.ArrowHelper(
    DIR, // 方向向量
    new THREE.Vector3(0, 0, 0), 
    LENGTH, 
    'deepskyblue' 
)
scene.add(arrow);

const sphere = new THREE.Mesh(
    new THREE.SphereGeometry(0.3, 32, 32),
    new THREE.MeshBasicMaterial({color: 'deeppink'})
)
scene.add(sphere);

要想使箭头做运动可参照上一个案例,这里创建一个update方法来更新状态

js 复制代码
const update = secs => {
    const a1 = frame / maxFrame,
    a2 = 1 - Math.abs(0.5 - a1) / 0.5; // 0-1
    V.z = -5 + 10 * a2; 
    DIR = V.clone().normalize(); // 归一化
    arrow.setDirection(DIR); // 设置方向
}

接下来就是处理球体的运动,无非是不断更新小球的位置

js 复制代码
const x = DIR.x * LENGTH * a2, // 计算x
y = DIR.y * LENGTH * a2, // 计算y
z = DIR.z * LENGTH * a2; // 计算z
sphere.position.set(x, y, z);
sphere.lookAt(0, 0, 0);
camera.position.z = z + 3;

最后在循环渲染函数中调用update方法,为了方便观察,这里动态的修改了相机的Z轴位置坐标

以上便是本篇的所有内容,自己动手练一练,感受一下实际效果

相关推荐
天天扭码33 分钟前
《很全面的前端面试题》——HTML篇
前端·面试·html
xw534 分钟前
我犯了错,我于是为我的uni-app项目引入环境标志
前端·uni-app
!win !37 分钟前
被老板怼后,我为uni-app项目引入环境标志
前端·小程序·uni-app
Burt38 分钟前
tsdown vs tsup, 豆包回答一坨屎,还是google AI厉害
前端
群联云防护小杜1 小时前
构建分布式高防架构实现业务零中断
前端·网络·分布式·tcp/ip·安全·游戏·架构
ohMyGod_1233 小时前
React16,17,18,19新特性更新对比
前端·javascript·react.js
前端小趴菜053 小时前
React-forwardRef-useImperativeHandle
前端·vue.js·react.js
@大迁世界3 小时前
第1章 React组件开发基础
前端·javascript·react.js·前端框架·ecmascript
Hilaku3 小时前
从一个实战项目,看懂 `new DataTransfer()` 的三大妙用
前端·javascript·jquery
爱分享的程序员3 小时前
前端面试专栏-算法篇:20. 贪心算法与动态规划入门
前端·javascript·node.js