JS函数实现碰撞检测
创始人
2025-06-01 02:20:18
0

js中实现碰撞检测

原理:

在html的坐标系中,横轴向右为正,纵轴向下为正,将红色方块命名为a,蓝色方块命名为b。四个蓝色方块代表了四个不同方向。t1(2)、b1(2)、l1(2)、r1(2)分别表示红色(蓝色)方块的上偏移量、高度、左偏移量和宽度,当r2 < l1 、 r1 < l2 、 b2 < t1、 b1 < t2时,两方块不会碰撞。

原文链接:https://blog.csdn.net/m0_50947589/article/details/124981691

function isCrash(a,b){var l1 = a.offsetLeft;var t1 = a.offsetTop;var r1 = l1 + a.offsetWidth;var b1 = t1 + a.offsetHeight;// offsetLeft值为与设置position属性的父盒子的距离var l2 = b.offsetLeft;var t2 = b.offsetTop;// offsetWidth: 为元素的width+元素的padding+边框的宽度var r2 = l2 + b.offsetWidth;var b2 = t2 + b.offsetHeight;if(r2 < l1 || r1 < l2 || b2 < t1 || b1 < t2){return false;}else{return true;}}

threejs中实现碰撞检测

  1. 官方的方法 ammo.js

  1. 案例

  1. 中文文档

  1. 使用射线

  1. 原理

  1. 用Raycaster来检测碰撞的原理很简单,我们需要以物体的中心为起点,向各个顶点(vertices)发出射线,然后检查射线是否与其它的物体相交。如果出现了相交的情况,检查最近的一个交点与射线起点间的距离,如果这个距离比射线起点至物体顶点间的距离要小,则说明发生了碰撞。

  1. 检测光线是否与物体相交使用的是 intersectObject( object, recursive ) 或 intersectObjects 方法: 相交的结果会以一个数组的形式返回,其中的元素依照距离排序,越近的排在越前

/*** 功能:检测 movingCube 是否与数组 collideMeshList 中的元素发生了碰撞* */
var originPoint = movingCube.position.clone();for (var vertexIndex = 0; vertexIndex < movingCube.geometry.vertices.length; vertexIndex++) {// 顶点原始坐标var localVertex = movingCube.geometry.vertices[vertexIndex].clone();// 顶点经过变换后的坐标var globalVertex = localVertex.applyMatrix4(movingCube.matrix);// 获得由中心指向顶点的向量var directionVector = globalVertex.sub(movingCube.position);// 将方向向量初始化var ray = new THREE.Raycaster(originPoint, directionVector.clone().normalize());// 检测射线与多个物体的相交情况var collisionResults = ray.intersectObjects(collideMeshList);// 如果返回结果不为空,且交点与射线起点的距离小于物体中心至顶点的距离,则发生了碰撞if (collisionResults.length > 0 && collisionResults[0].distance < directionVector.length()) {crash = true; // crash 是一个标记变量}
}
  1. 缺陷

  1. 当物体的中心在另一个物体内部时,是不能够检测到碰撞的。而且当两个物体能够互相穿过,且有较大部分重合时,检测效果也不理想。

  1. 注意点

  1. 在Three.js中创建物体时,它的顶点(veritces)数目是与它的分段数目相关的,分段越多,顶点数目越多。为了检测过程中的准确度考虑,需要适当增加物体的分段。

  1. 自己实现

  1. 使用 Three.Box3 计算物体的包围盒的长宽高

class DashLinesBoxTool{   /*** 根据 Object 计算几何长宽高, 并 Vector3 形式返回* @param {Object} object*/static getObjectBoxSize(object){const box3 = new Three.Box3()// //box3:示例{max: Vector3 {x: 3.5, y: 0.5, z: 0.5},min: Vector3 {x: 2.5, y: -0.5, z: -0.5}}// min代表最低边界的xyz,max代表最高边界box3.expandByObject(object) // 获得object模型的包围盒const v3 = new Three.Vector3()box3.getSize(v3) //将会把box的长宽高拷贝给v3,并返回box3的长宽高console.log("v3 ", v3) // 获得一个三位坐标对象{x,y,z}return v3}
}
  1. 然后根据移动物体与其他物体的位置差,同移动物体与其他物体包围盒对应的长宽高之和的一半,如果位置差的xyz 都小于移动物体与某个物体包围盒长宽高之和的一半,则可判断碰撞

 /*** 判断是否碰撞*/function isJudgeCollision(){// 声明一个变量用来表示是否碰撞var moveV3 = DashLinesBoxTool.getObjectBoxSize(curMoveObject)var filterObjArr = filterObjects(objectsMesh, curMoveObject)for (var i = 0; i < filterObjArr.length; i++) {var v3 = DashLinesBoxTool.getObjectBoxSize(filterObjArr[i])// 移动物体与场景配置位置之差var xValue = Math.abs(filterObjArr[i].position.x - curMoveObject.position.x)var yValue = Math.abs(filterObjArr[i].position.y - curMoveObject.position.y)var zValue = Math.abs(filterObjArr[i].position.z - curMoveObject.position.z)console.log(" filterObjArr[i].position,  curMoveObject.position ", filterObjArr[i].position , curMoveObject.position )// 移动物体与场景物体包围盒长宽高一半var xCollision = Math.abs(moveV3.x+v3.x) / 2.0var yCollision = Math.abs(moveV3.y+v3.y) / 2.0var zCollision = Math.abs(moveV3.z+v3.z) / 2.0console.log(" xValue , yValue , xCollision , yCollision ", xValue , yValue , xCollision , yCollision )// 位置之差小于长/宽/高和的一半,则发生碰撞if(xValue < xCollision && yValue < yCollision && zValue < zCollision){return true}}return false}
  1. 注意事项

  1. 1、如果有旋转,注意 Box3 获取的也是没有旋转的 Object 的包围盒

  1. 包围盒 + 位置判断碰撞的方法,存在使用有局限性,仅思路仅供参考

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...