在 Three.js 中,THREE.Ray
和 THREE.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.Camera 和 THREE.Scene |
计算方式 | 手动计算射线与几何体的交点 | 自动检测射线与 3D 物体的交点 |
适用场景 | 计算射线与平面、包围盒的交点 | 检测鼠标点击、视线检测 |
4. 总结
THREE.Ray
:用于 数学计算,如射线与几何体的交点、距离计算等。THREE.Raycaster
:用于 场景交互,如鼠标拾取、碰撞检测等。Raycaster
内部使用了Ray
**,但提供了更高级的功能,可以直接检测 3D 物体。
如果你要做 鼠标交互 (如点击选中物体),用 Raycaster
;
如果你要做 数学计算 (如射线与平面的交点),用 Ray
。