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轴位置坐标

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

相关推荐
excel11 分钟前
JavaScript 中 WeakMap、WeakSet、Set、Map、Object、Array 的区别与应用场景
前端
haaaaaaarry1 小时前
Element Plus常见基础组件(一)
java·前端·javascript·vue.js
qingyingWin1 小时前
原生微信小程序研发,如何对图片进行统一管理?
前端·微信小程序
不懂英语的程序猿1 小时前
【JEECG】JVxeTable表格拖拽排序功能
前端·后端
拾光拾趣录1 小时前
前端灵魂拷问:从URL到Redux,17个常见问题
前端·面试
萌萌哒草头将军1 小时前
Prisma ORM 又双叒叕发布新版本了!🚀🚀🚀
前端·javascript·node.js
mldong2 小时前
推荐一款超高颜值的后台管理模板!Art-Design-Pro!开源!免费!
前端·vue.js·架构
草字2 小时前
uniapp 如果进入页面输入框自动聚焦,此时快速返回页面或者跳转到下一个页面,输入法顶上来的页面出现半屏的黑屏问题。
java·前端·uni-app
程序视点2 小时前
Wise Duplicate Finder 重复文件查找工具 - 永久免费专业版文件去重工具
前端·windows
一点一木3 小时前
🚀 2025 年 07 月 GitHub 十大热门项目排行榜 🔥
前端·人工智能·github