矩形包围盒,顾名思义,就是使用一个矩形来包围住图像,矩形的大小以刚好包围住图像为最佳,这种包围盒最适用的场景是刚好物体的形状接近于矩形。

在具体的应用中,描述矩形包围盒的的常用方式有以下两种,

一:采用最小最大顶点法描述AABB包围盒

上图中使用了最小最大顶点法来描述包围盒信息,由于是在屏幕坐标系中,y轴是向下延伸的,所以只需要保留矩形中坐标的最小值和最大值即可,即矩形的左上角和右下角的顶点,其他的点都在这两个点范围内。

在这种情况下要判断两个矩形是否碰撞只需要比较两个矩形顶点的坐标即可,假设矩形 A用(x1, y1)表示左上角,(x2, y2)表示右下角,矩形B用(x3, y3)表示左上角,(x4, y4)表示右下角,则满足下列条件则表示没有碰撞,反之则碰撞。

• 没碰撞:x1>x4 或者x2<x3。

• 没碰撞:y1>y4 或者y2<y3。

关键代码如下:

        function hitTest(source, target) {/* 源物体和目标物体都包含 x, y 以及 width, height */return !(( ( source.y + source.r ) < ( target.y ) ) ||( source.y > ( target.y + target.r ) ) ||( ( source.x + source.r ) < target.x ) ||( source.x > ( target.x + target.r ) ));}

DEMO代码:

<!DOCTYPE html>
<html lang="en">
<head><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"><meta charset="UTF-8"><title>盒包围碰撞算法-矩形</title><style>#stage {border: 1px solid lightgray;}</style>
</head>
<body>
<h1>是否碰撞:<span class="hitTest">否</span></h1>
<canvas id="stage"></canvas>
</body>
<script>window.onload = function () {var stage = document.querySelector('#stage'),ctx = stage.getContext('2d');stage.width = 400;stage.height = 400;//栅格线条function drawGrid(context, color, stepx, stepy) {context.strokeStyle = color;context.lineWidth = 0.5;for (var i = stepx + 0.5; i < context.canvas.width; i += stepx) {context.beginPath();context.moveTo(i, 0);context.lineTo(i, context.canvas.height);context.stroke();}for (var i = stepy + 0.5; i < context.canvas.height; i += stepy) {context.beginPath();context.moveTo(0, i);context.lineTo(context.canvas.width, i);context.stroke();}}var rect = {x: stage.width / 2 - 20,y: stage.height / 2 - 20,r: 40,c: "red"}, rects = [];;rects.push(rect);for (var i = 0; i < 10; i++) {var trace = {x: 40 * i,y: 40 * i,r: 40,c: "blue"};rects.push(trace);}function createRect(x, y, r, c) {ctx.beginPath();ctx.fillStyle = c;ctx.rect(x, y, r, r);ctx.fill();}document.onkeydown = function (event) {var e = event || window.event || arguments.callee.caller.arguments[0];//根据地图数组碰撞将测switch (e.keyCode) {case 37:console.log("Left");if (rects[0].x > 0) {rects[0].x -= 2;}break;case 38:console.log("Top");if (rects[0].y > 0) {rects[0].y -= 2;}break;case 39:console.log("Right");if (rects[0].x < stage.width) {rects[0].x += 2;}break;case 40:console.log("Bottom");if (rects[0].y < stage.height) {rects[0].y += 2;}break;default:return false;}};stage.addEventListener('click', function (event) {var x = event.clientX - stage.getBoundingClientRect().left;var y = event.clientY - stage.getBoundingClientRect().top;rects[0].x = x - rects[0].r/2;rects[0].y = y - rects[0].r/2;});function hitTest(source, target) {/* 源物体和目标物体都包含 x, y 以及 width, height */return !(( ( source.y + source.r ) < ( target.y ) ) ||( source.y > ( target.y + target.r ) ) ||( ( source.x + source.r ) < target.x ) ||( source.x > ( target.x + target.r ) ));}function update() {ctx.globalAlpha = 1;ctx.clearRect(0, 0, 400, 400);drawGrid(ctx, 'lightgray', 40, 40);document.querySelector('.hitTest').innerHTML = "否";for (var i = 1, len = rects.length; i < len; i++) {createRect(rects[i].x, rects[i].y, rects[i].r, rects[i].c);var flag = hitTest(rects[0], rects[i]);if (flag) {document.querySelector('.hitTest').innerHTML = "是";ctx.globalAlpha = 0.5;}}createRect(rects[0].x, rects[0].y, rects[0].r, rects[0].c);requestAnimationFrame(update);}update();};
</script>
</html>

二:采用点和半径描述AABB包围盒

在上图中使用了中心点和对应两个轴的半径来描述包围盒信息,假设有两个矩形A和B,矩形A 的中心坐标为A(x1, y1),宽度和高度分别为rx1、ry1,矩形B 的中心坐标为B(x2, y2),宽度和高度分别为rx1、ry1,矩形B 的中心坐标为B(x2, y2),宽度和高度分别是rx2、ry2,则采用这种包围盒检测方式如下。

如果满足两个矩形在x方向的距离小于两个矩形宽度和的一半,并且在y方向上的距离小于两个矩形高度和的一半则表示两个矩形有重叠,即表示发生碰撞,换成公式如下:

X方向满足:|x2-x1|<=rx1+rx2并且Y方向满足:|y2-y1|<=ry1+ry2

当然,也可以把这种形式换算成第一种形式演算,这两种方式很显然第一种的效率比较高效一点,毕竟第二种算法需要使用

Math.abs获取绝对值,第一种只是单纯使用了坐标比较。

以上所描述的矩形包围盒也称为 AABB(轴对齐)包围盒,轴对齐包围盒中的矩形的四条边分别和坐标轴平行,实际上也就是表示该矩形没有进行过旋转操作,使用轴对齐包围盒检测算法比较简单高效,精度上也能满足大多数条件,因此实际应用中也比较多。

有兴趣的可以搜索下OBB(定向接线)包围盒。

在线预览地址:https://github.com/krapnikkk/JS-gameMathematics

【H5/JS】游戏常用算法-碰撞检测-包围盒检测算法(2)-矩形相关推荐

  1. html5 游戏 算法,JS/HTML5游戏常用算法之碰撞检测 包围盒检测算法详解【圆形情况】...

    JS/HTML5游戏常用算法之碰撞检测 包围盒检测算法详解[圆形情况] 发布时间:2020-10-10 13:42:43 来源:脚本之家 阅读:95 作者:krapnik 本文实例讲述了JS/HTML ...

  2. 路面裂痕检测YOLO算法、目标检测算法实现地面裂缝检测

    道路裂纹检测YOLO算法,目标检测,目标识别,裂纹检测 路面裂痕检测YOLO算法.目标检测算法实现地面裂缝检测 车头定位 交通标志识别 车道线识别 自己标注数据,训练模型,效果很好4360063193 ...

  3. 【H5/JS】游戏常用算法-碰撞检测-地图格子算法

    这种算法经常用于RPG(早期的<最终幻想>.<DQ>.<仙剑奇侠传>).SLG(<炎龙骑士团>.<超级机器人大战>).PUZ(<俄罗斯 ...

  4. 基于haar特征的adaboost算法_目标检测算法介绍

    什么是目标检测 目标检测是指从图像中找出目标,包括检测和识别两个过程,现实中由于环境的复杂性以及各类物体的形状.外观以及光照,遮挡等因素的干扰,所以目标检测一直也是计算机视觉最常见的挑战之一. 目标检 ...

  5. 2018目标检测最新算法+经典目标检测算法

    干货 CVPR2018的目标检测总结(论文+开源代码)https://blog.csdn.net/wfei101/article/details/80861681 目标检测算法集合(论文+开源代码)h ...

  6. 点在不规则图形内算法python_目标检测算法中规则矩形和不规则四边形IOU的Python实现...

    交并比(Intersection-over-Union,IoU),目标检测中使用的一个概念,我们在进行目标检测算法测试时,重要的指标,是产生的预测框(candidate bound)与标记框(grou ...

  7. 目标检测算法 2020_One-stage目标检测算法综述

    yolo-v1: YOLO 就是使用回归这种做法的典型算法. 首先将图片 Resize 到固定尺寸,然后通过一套卷积神经网络,最后接上 FC 直接输出结果,这就他们整个网络的基本结构. 更具体地做法, ...

  8. ap 目标检测算法map_目标检测算法的评估指标:mAP定义及计算方式

    前面依次介绍了: 本节介绍目标检测算法的评估指标:mAP定义及计算方式 mAP:mean Average Precision,平均精度均值,即AP(Average Precision)的平均值,它是目 ...

  9. 基于线条特征的机场检测算法——LSD直线检测算法、平行线组提取和聚类

    遥感图像的机场检测是图像处理在军事以及航空领域一个重要的应用,现有一些机场提取方法利用显著性特征获取机场区域的方法容易使得机场提取不够完整,而且会混入过多的虚警区域,原因在于图像的显著性特征并能用来表 ...

最新文章

  1. Python实现一元及多元线性回归
  2. python excel web_使用python在WEB页面上生成EXCEL文件
  3. 宅男抖音某猫协议分析及应用破解
  4. Winform中实现根据配置文件重新加载ZedGraph属性的实现思路
  5. jdk动态代理与cglib动态代理例子
  6. php获取当前世界,php获取网站alexa世界流量排名代码
  7. element 方法返回的boolean被当成字符串了_JavaScript 原生对象、属性、方法、事件、事件参数...
  8. python导入data-Python通过load data导入MySQL数据
  9. 利用python如何进行数据挖掘
  10. 2015年度APP分类
  11. mp3格式转换软件哪个好?
  12. 使用pygame制作双人五子棋小游戏
  13. 30天自制操作系统——第八天鼠标控制与32位模式切换
  14. [EE261学习笔记] 13.离散傅里叶逆变换及离散傅里叶变换的一些性质
  15. 终端常用的命令及功能
  16. 深入浅出JS—20 生成器控制函数执行
  17. Ansys2020R2的Fluent网格重排问题(reorder)
  18. 计算机一级是word2010,WORD2010讲义计算机一级
  19. javaSwing+MySQl实现图书馆登录页面(完整)
  20. CTO应具备的知识体系

热门文章

  1. 机器学习集成学习进阶LightGBM算法和案例
  2. MTK OTA更新方法
  3. 人活一辈子,到底为了什么而工作?这是我看过最好的答案
  4. 原神一面:Java 泛型中的通配符 T,E,K,V,?,你确定都了解吗?
  5. java解析word示例(支持docx、doc,wps格式)
  6. Windows磁盘管理软件/磁盘管理工具/硬盘分区管理工具
  7. 安装php vcruntime140,win7安装apache或者php 5.7缺少vcruntime140.dll的问题
  8. mysql远程3306不通_mysql服务器3306端口不能远程连接的解决
  9. jdbc连接mysql数据库,设置字符集编码
  10. php创作原声,抖音这是发小哥哥的唯一号创作的原声什么歌 I keep saying no歌曲分享...