有趣且重要的JS知识合集(17)矩形框交互算法

news2025/6/18 0:04:21

之前我讲过如何用js绘制矩形框,下面链接快速通道~

【JS】原生js实现矩形框的绘制/拖动/缩放

那么如何判断多个矩形框是否相交?嵌套还是其他的呢?

那下面我来分别写写关于矩形框常用的几个算法吧

1、数据格式知悉

const { startX, startY, width, height, type } = rectangle

// startX 矩形框左上角X轴
// startY 矩形框左上角Y轴
// width 矩形框宽
// height 矩形框高
// type 矩形框类型

frameList: 矩形框列表,里面有多个rectangle对象
detail:下面算法中实参中有detail代表他是在拿detail和其他矩形框进行对比,detail也是一个rectangle对象哦

其实根据上述数据,我们能得到矩形框的左上角和右下角坐标是

x1 = startX // 矩形框左上角X轴
y1 = startY // 矩形框左上角Y轴
x2 = startX + width // 矩形框右下角X轴
y2 = startY + height // 矩形框右下角Y轴

2、算法源码及解析

2.1、输出两个矩形交互后的交互矩形坐标,若无则不输出(核心算法)

    /**
     * 输出两个矩形交互后的交互矩形坐标,若无则不输出
     * @param rectA 矩形A的详情数据
     * @param rectB 矩形B的详情数据
     */
    intersectRectangle(rectA, rectB) {
      const { startX: xa, startY: ya, width: wa, height: ha } = rectA
      const { startX: xb, startY: yb, width: wb, height: hb } = rectB
      // 以下为矩形A,B的左上和右下两个坐标数据
      const ax1 = xa
      const ay1 = ya
      const ax2 = xa + wa
      const ay2 = ya + ha
      const bx1 = xb
      const by1 = yb
      const bx2 = xb + wb
      const by2 = yb + hb
      const a = Math.max(ax1, bx1)
      const b = Math.min(ay2, by2)
      const c = Math.min(ax2, bx2)
      const d = Math.max(ay1, by1)
      if (a > c || b < d) { // 符合此条件证明无交互矩形
        return
      } else { // 输出交互矩形的左上和右下角坐标
        return [[a, d], [c, b]]
      }
    }

2.2、输出两矩形交互的面积占最小矩形比例(核心算法)

    /**
     * 判断两矩形交互的面积占比
     * @param rectA 矩形A的详情数据
     * @param rectB 矩形B的详情数据
     */
    rectangleArea(rectA, rectB) {
      const { width: wa, height: ha } = rectA
      const { width: wb, height: hb } = rectB
      const pointMap = this.intersectRectangle(rectA, rectB) // 交互矩形的坐标集合,如无输出则表示无交互矩形
      let s = 0
      if (!pointMap) { // 符合此条件证明无交互面积
        s = 0;
      } else { // 计算交互矩形面积
        s = (pointMap[1][0] - pointMap[0][0]) * (pointMap[1][1] - pointMap[0][1]);
      }
      return Number((s / Math.min(wa * ha, wb * hb)).toFixed(3)) // 重叠面积占比计算,保留三位小数: 重叠面积 / 最小的矩形面积
    }

2.3、判断当前点击的矩形框是否和其他矩形框嵌套

示例图:

算法源码:

    /**
     * @description 判断是否嵌套
     * @param object 当前矩形框全部数据
     * @return boolean true(存在嵌套) false(不存在嵌套)
     */
    isContainRect(detail) {
      const { startX, startY, width, height } = detail;
      const copyFrame = this.frameList.filter(item => (item.id !== detail.id))
      let _status = false;
      for (let m = 0; m < copyFrame.length; m++) {
        const { startX: originStartX, startY: originStartY, width: originWidth, height: originHeight } = copyFrame[m];
        // 大框往小框外嵌套
        const scene1 = (originStartX - 1 <= startX + width && startX + width <= originStartX + originWidth + 1) && (originStartY - 1 <= startY + height && startY + height <= originStartY + originHeight + 1) && (originStartX < startX && originStartY < startY)
        // 小框往大框内嵌套
        const scene2 = (startX - 1 <= originStartX + originWidth && originStartX + originWidth <= startX + width + 1) && (startY - 1 <= originStartY + originHeight && originStartY + originHeight <= startY + height + 1) && (startX < originStartX && startY < originStartY)
        if (scene1 || scene2) {
          _status = true;
          break
        }
      }
      return _status
    }

2.4、多个矩形框判断是否有重叠,并且重叠面积是否大于80%

示例图:

 

算法源码:

    /**
     * @description 判断重叠面积是否小于80%
     * @return boolean true(重叠面积大于80%) false(重叠面积小于80%)
     */
    isOverlapRect() {
      const copyFrame = this.frameList
      let flag = false;
      for (let i = 0; i < copyFrame.length; i++) { // 矩形框框两两对比,判断是否有交互的地方,有则将交互矩形输出出来
        for (let j = 0; j < copyFrame.length - 1 - i; j++) {
          const before = copyFrame[i]
          const after = copyFrame[i + 1 + j]
          flag = this.rectangleArea(before, after) > 0.8 // 最小面积占比超过80%则返回true
          if (flag) break
        }
        if (flag) break
      }
      return flag
    }

2.5、 多种类型的矩形框是否有相交的部分(此处举例两种类型)

示例图:

 

算法源码:

    /**
     * @description 大题干框 type 为1 和分栏框 type 为0 是否有相交的部分
     * @return boolean true(有相交部分) false(无相交部分,占比0%或者100%)
     */
    isIntersectRect(detail) {
      const bigFrames = this.frameList.filter(item => (detail.id !== item.id) &&(item.type === 1))
      const splitFrames = this.frameList.filter(item => (this.answerPages.current === item.pageNo) && (item.type === 0))
      let flag = false
      for (let i = 0; i < bigFrames.length; i++) {
        for (let j = 0; j < splitFrames.length; j++) {
          const area = this.rectangleArea(bigFrames[i], splitFrames[j])
          flag = !(area === 0 || area === 1)
          if (flag) break
        }
        if (flag) break
      }
      return flag
    }

2.6、两个同类型矩形框相交部分是否存在嵌套的另种类型框

示例图:

算法源码: 

    /**
     * @description 分栏框相交部分是否存在嵌套的大题干框
     * @param object 当前框的数据
     * @return boolean true(存在嵌套的大题干框) false(不存在嵌套的大题干框)
     */
    isBorderlineRect(detail) {
      if (detail.type === 0) return false
      const splitFrames = this.frameList.filter(item => (this.answerPages.current === item.pageNo) && (item.type === 0))
      let flag = false
      for (let i = 0; i < splitFrames.length; i++) { // 分栏框两两对比,判断是否有交互的地方,有则将交互矩形输出出来
        for (let j = 0; j < splitFrames.length - 1 - i; j++) {
          const before = splitFrames[i]
          const after = splitFrames[i + 1 + j]
          const newRect = this.intersectRectangle(before, after) // 返回的数据为二维坐标数组,需要转换组装新的类坐标格式
          if (newRect) {
            const newDecorateRect = { // 类坐标格式
              startX: newRect[0][0],
              startY: newRect[0][1],
              width: newRect[1][0] - newRect[0][0],
              height: newRect[1][1] - newRect[0][1]
            }
            const area = this.rectangleArea(newDecorateRect, detail)
            if (area === 1) { // 如果有嵌套,则退出循环
              flag = true
              break
            }
          }
        }
        if (flag) break
      }
      return flag
    }

---有不懂的可以随时评论提问噢,我有空会看的噢~---

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/53783.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网页整体如何实现网页变灰效果

网页整体如何变灰?为了纪念一些影响力很大的伟人逝世或者重要的纪念日的时候需要让网页全部变灰来表示我们对逝者的悼念。 其实这个功能很简单&#xff0c;方法也有很多&#xff0c;只需要在HTML 的head标签里加入如下代码即可! <style type"text/css">html …

Vulnhub_CTF-4

目录 一 渗透测试 &#xff08;一&#xff09;信息收集 1 端口扫描 2 目录枚举 &#xff08;二&#xff09;漏洞测试 1 SQL注入 2 ssh爆破 &#xff08;三&#xff09;提权 1 sudo 提权 二 知识点 &#xff08;一&#xff09;SQL延时注入 &#xff08;二…

Vue3聊天气泡简单实现思路

Vue3聊天气泡简单实现 实现聊天气泡主要有两个注意点&#xff1a; ①是根据字体数量自适应框的长度 ②字体到框有边距&#xff0c;也就是为了美观 这篇博客主要讲实现的思路&#xff0c;不讲聊天气泡的三角突出点&#xff0c;如下所示&#xff1a; 三角突出点通过简单的bord…

微服务框架 SpringCloud微服务架构 9 初识 Docker 9.1 什么是Docker

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 SpringCloud微服务架构 文章目录微服务框架SpringCloud微服务架构9 初识 Docker9.1 什么是Docker9.1.1 项目部署的问题9.1.2 Docker9.1.3 总…

StarkNet新手指南

Rollup代表了以太坊未来扩展计划的基础。 StarkNet是一个无需许可的第2层&#xff08;L2&#xff09;扩展网络&#xff0c;是“四大”早期主流rollup之一。本篇Bankless文章将向你展示&#xff0c;对于一个新手来说&#xff0c;如何畅游StarkNet生态系统&#xff01; StarkNe…

【JUC】循环屏障CyclicBarrier详解

前言 jdk中提供了许多的并发工具类&#xff0c;大家可能比较熟悉的有CountDownLatch&#xff0c;主要用来阻塞一个线程运行&#xff0c;直到其他线程运行完毕。而jdk还有一个功能类似并发工具类CyclicBarrier&#xff0c;你知道它的作用吗&#xff1f;和CountDownLatch有什么区…

QA特辑|重点重点!模型开发与部署的标准答案!

11月24日&#xff0c;顶象业务安全大讲堂系列课程之《智能模型平台》正式开讲&#xff0c;顶象人工智能总监无常从从模型平台的现状与需求出发&#xff0c;带大家了解了模型平台的开发环境与部署环境&#xff0c;并且就顶象的Xintell 模型平台 为大家做了演示。 直播也吸引了不…

【LeetCode每日一题】——38.外观数列

文章目录一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【解题思路】七【题目提示】八【时间频度】九【代码实现】十【提交结果】一【题目类别】 字符串 二【题目难度】 中等 三【题目编号】 38.外观数列 四【题目描述】 给定一个正整数 n …

mybatispuls 批处理 rewriteBatchedStatements=true

mybatis-plus原生的批处理 this.saveBatch(list); 实际是一条条处理&#xff0c;特慢&#xff0c;造几万行数据得几分钟以上。 如果加上配置&#xff0c;就十几秒搞定五万行数据入库 &rewriteBatchedStatementstrue

建议收藏——等级保护备案整体流程

等级保护的流程大致为定级—备案—初测—整改—复测—监督检查&#xff0c;备案需先定级。整体备案流程是向属地公安机关提交备案资料&#xff0c;需要先线上提交备案材料。线上审核通过后&#xff0c;再线下提交备案材料。具体如下&#xff1a; 1&#xff0c;先线上提交资料审…

WPF 3D MeshGeometry3D类的Positions和TriangleIndices属性研究

MeshGeometry3D 类&#xff0c;用于生成三维形状的三角形基元&#xff1b; 类的参考在此&#xff1b; https://learn.microsoft.com/zh-cn/dotnet/api/system.windows.media.media3d.meshgeometry3d?viewwindowsdesktop-7.0 写在xaml语法里面是<MeshGeometry3D Positions.…

【Android App】低功耗蓝牙中扫描BLE设备的讲解及实战(附源码和演示 超详细)

需要源码请点赞关注收藏后评论区留言私信~~~ 一、扫描BLE设备 传统蓝牙虽然历史悠久&#xff0c;但它的缺陷也很明显&#xff0c;包括但不限于下列几点&#xff1a; &#xff08;1&#xff09;需要两部设备配对之后才能继续连接&#xff0c;而且连接速度也慢&#xff1b; &a…

数组与字符串总结

一、数组 基本概念 特点&#xff1a;顺序存储&#xff0c;每个元素大小&#xff0c;类型相同&#xff0c;元素有限 高维数组可以转化为一维数组 高维数组存放次序&#xff1a;按行优先或者按列优先 按行优先的寻址公式&#xff1a; 二维数组a[m] [n]: Loc(a[i] [j]) Loc…

Ajax axios JSON Fastjson

1、概述 AJAX (Asynchronous JavaScript And XML) &#xff1a;异步的JavaScript和XML AJAX工作流程如下: 1.1、作用 AJAX作用有以下两方面&#xff1a; 1&#xff09;与服务器进行数据交换&#xff1a;通过AJAX可以给服务器发送请求&#xff0c;服务器将数据直接响应回浏览…

算法训练Day36 贪心算法系列 - 重叠区间问题 | LeetCode435. 无重叠区间;763. 划字母区间;56.合并区间

前言&#xff1a; 算法训练系列是做《代码随想录》一刷&#xff0c;个人的学习笔记和详细的解题思路&#xff0c;总共会有60篇博客来记录&#xff0c;计划用60天的时间刷完。 内容包括了面试常见的10类题目&#xff0c;分别是&#xff1a;数组&#xff0c;链表&#xff0c;哈…

【Linux】快捷键

Ctrl C&#xff1a;终止当前命令

星环科技数据中台解决方案,助力某政府机构建设新型智慧城市

客户背景 城市&#xff0c;是人们工作生活的栖息地&#xff0c;也是展示发展成果的全景图。某政府机构不仅注重城市“中枢大脑”的建设&#xff0c;而且兼顾“神经末梢”的需求&#xff0c;既有技术进步的“面子”&#xff0c;更有民生保障的“里子”。站在新的起点上&#xff…

Linux计划任务管理

一&#xff0c;计划任务管理&#xff1a; 任务管理很宽泛&#xff0c;这里是指的计划任务管理&#xff0c;在指定的时间执行。 1&#xff0c;at命令 &#xff1a; 由atd守护进程来执行&#xff0c;atd进程会定期检查系统上的 /var/spool/at 目录&#xff0c;获取at命令写入的任…

如何建立你的财务体系?

天下人都想同时实现财务管理民主自由&#xff0c;换言之一下&#xff0c;你躺在毛里求斯的海滩上&#xff0c;吹着南风&#xff0c;晒着月亮&#xff0c;还有总收入源源不绝的流向&#xff0c;阿涅尔&#xff1f; 那么&#xff0c;怎样同时实现&#xff1f;坚信我们都知道投资…

准备大半年,面试频繁受挫,Java岗面试为何越来越难?

作为一名优秀的程序员&#xff0c;技术面试都是不可避免的一个环节&#xff0c;一般技术面试官都会通过自己的方式去考察程序员的技术功底与基础理论知识。 如果你参加过一些大厂面试&#xff0c;肯定会遇到一些这样的问题&#xff1a; 1、看你项目都用的框架&#xff0c;熟悉…