关于canvas画布上绘制多个(单个也一样)不规则多边形,用户点击这张画布时,判断点击的是哪个多边形

2023-11-15

首先来看看canvas效果图

canvas画布效果图
上面是我在canvas上绘制了多个不规则多边形,如果不是很了解怎么绘制,可以看我上个博客canvas画图

盒子结构

<div class="imgBox" ref="canvas">
     <canvas id="myCanvas" width="660px" height="260px" @click="getWorkShop"></canvas>
</div>

样式

.imgBox {
     width: 100%;
     height: 100%;
     // width: 660px;
     // height: 260px;
     background-color: #c1c8df;
     cursor: pointer;
     #myCanvas {
       width: 100%;
       height: 100%;
     }
   }

这个页面是适配的,imgBox盒子的大小比canvas画布大,canvas是适配上的,这个大小适配方法会影响后面点击画布时有影响,需要在写方法时,判断转化一下

原理 - 光线投射法

原理:

1、从点P出发,任意引一条射线(模拟光线)。

2、该条射线与多边形A的边相交时,若射线从边的左侧贯穿记录leftCount加1,若射线从边的右侧贯穿记录rightCount加1。

3、若leftCount-rightCount等于0表示在图形外部,若不等于0表示图形内部。

点击画布方法
getWorkShop($el, e) {
// 画布上是有一张背景图的,且是响应式的,页面的展示的画布与实际样式的画布尺寸不一致,需要转换一下,例如页面时1300 * 500,但是我的画布实际是660 * 260,然后需要比例转换一下
      let cImgW = this.$refs.canvas.clientWidth; // 画布的渲染的宽度
      let cImgH = this.$refs.canvas.clientHeight; // 画布的渲染高度
      let offsetX = $el.offsetX; // 鼠标点击的横坐标
      let offsetY = $el.offsetY; // 鼠标点击的纵坐标
      // 按照比例实际上用户点击的位置,把鼠标点击的位置转换成660 * 260的相应位置
      let userPointX = parseInt((660 * offsetX) / cImgW);
      let userPointY = parseInt((260 * offsetY) / cImgH);
      // this.pointData 是数组格式,切里面的每个对象里还有对象
      let pointDataCopy = JSON.parse(JSON.stringify(this.pointData));
      // 判断画布上有无图形
      if (pointDataCopy.length > 0) {
        let dot = {
          x: userPointX,
          y: userPointY,
        };

        pointDataCopy.map((item) => {
          item.maxArray = [];
          item.maxArray.push(item.point1);
          item.maxArray.push(item.point2);
          item.maxArray.push(item.point4);
          item.maxArray.push(item.point3);
          item.maxArray.push(item.point1);
          // maxArray 是多边形点的集合,坐标格式是{x, y}
          let flag = this.judge(dot, item.maxArray);
          // if (flag) {
          //   console.log(item.name);
          // }
        });
      }
    },
/**
     * @param  dot {x,y} 需要判断的点
     * @param  coordinates [{x,y},{x,y}....] 多边形点坐标的数组,为保证图形能够闭合,起点和终点必须相等。这里有个要求,就是点坐标的数组集合的点必须是顺时针或逆时针,如果顺序不一样,无法判断
     *        比如三角形需要四个点表示,第一个点和最后一个点必须相同。
     * @param noneZeroMode 对不规则图形进行判断
     */
    judge(dot, coordinates, noneZeroMode) {
      // 默认启动none zero mode
      noneZeroMode = noneZeroMode || 1;
      var x = dot.x,
        y = dot.y;
      var crossNum = 0;
      // 点在线段的左侧数目
      var leftCount = 0;
      // 点在线段的右侧数目
      var rightCount = 0;
      for (var i = 0; i < coordinates.length - 1; i++) {
        var start = coordinates[i];
        var end = coordinates[i + 1];

        // 起点、终点斜率不存在的情况
        if (start.x === end.x) {
          // 因为射线向右水平,此处说明不相交
          if (x > start.x) continue;

          // 从左侧贯穿
          if (end.y > start.y && y >= start.y && y <= end.y) {
            leftCount++;
            crossNum++;
          }
          // 从右侧贯穿
          if (end.y < start.y && y >= end.y && y <= start.y) {
            rightCount++;
            crossNum++;
          }
          continue;
        }
        // 斜率存在的情况,计算斜率
        var k = (end.y - start.y) / (end.x - start.x);
        // 交点的x坐标
        var x0 = (y - start.y) / k + start.x;
        // 因为射线向右水平,此处说明不相交
        if (x > x0) continue;

        if (end.x > start.x && x0 >= start.x && x0 <= end.x) {
          crossNum++;
          if (k >= 0) leftCount++;
          else rightCount++;
        }
        if (end.x < start.x && x0 >= end.x && x0 <= start.x) {
          crossNum++;
          if (k >= 0) rightCount++;
          else leftCount++;
        }
      }

      return noneZeroMode === 1
        ? leftCount - rightCount !== 0
        : crossNum % 2 === 1;
    },
效果

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关于canvas画布上绘制多个(单个也一样)不规则多边形,用户点击这张画布时,判断点击的是哪个多边形 的相关文章

  • 在 Android 上使用 Canvas 绘制两条线之间的区域

    我正在为我的应用程序开发一个简单的统计图形类 我尝试过 aChartEngine 和其他更多 但我更喜欢使用我自己的类 我正在使用包含 Android 的 Canvas 类绘制图形 但问题是我不知道如何填充线条和底部边框之间的区域 现在 矩
  • javascript canvas 函数在没有警报的情况下无法工作

    我正在制作一些演示网页 作为作品集的一部分 向潜在的雇主展示 其中一页是 等离子球 中等离子弧的模拟 然后旋转 等离子球 以 360 度查看 弧 仅当我在每次重绘后放置 警报 然后在脚本运行时取消警报时 每次旋转的弧线重绘才有效 没有警报
  • HTML5 Canvas 填充两种颜色

    我需要用两种颜色填充形状 就像棋盘一样 我见过一些 css 的渐变效果 但还没有见过这样的例子 这在 Html5 Canvas 中可能实现吗 你当然可以 事实上 您可以用任何可重复的东西填充任何任意形状 即使是您在画布本身中制作的形状 这是
  • HTML5 画布元素上的子像素抗锯齿文本

    我对画布元素抗锯齿文本的方式有点困惑 希望你们都能提供帮助 在下面的屏幕截图中 顶部的 Quick Brown Fox 是一个 H1 元素 底部的元素是一个画布元素 上面渲染有文本 在底部 您可以看到两个 F 并排放置并放大 请注意 H1
  • 跟随画布光标的放大镜

    我正在为我的客户设计 T 恤 我使用 html5 canvas 制作了它 衬衫设计师现在已经完成了 但他要求我添加一个放大镜 如下所示 http mlens musings it http mlens musings it 我发现了很多类似
  • toDataURL 不是函数

    我正在尝试为画布生成一个网址 以下是我遵循的步骤 var can document getElementsByTagName canvas var src can toDataURL image png 当我尝试在 firebug 上运行上
  • 了解 HTML Retina Canvas 支持

    最近我迷上了 HTMLcanvas绘图及其视网膜支持 无需进一步绘制配置线canvas 元素在视网膜显示屏上看起来有点模糊 我确实知道视网膜显示屏的像素是其四倍 因此默认情况下必须填充一些设备像素 否则图片将只有预期大小的一半 Exampl
  • 如何在 Android Canvas 上使用大量图元绘制游戏

    我在游戏的每一帧中画了很多线条矩形 这是老式手持电子游戏的娱乐 那些具有用于主游戏的原始点阵显示和用于文本或某些图像的自定义图像的内容 我在虚拟点阵屏幕上有 20x20 大 像素 我还在屏幕上绘制了一些 7 段显示和其他一些东西 根据Tra
  • 如何制作带有圆角的 tkinter 画布矩形?

    我想创建一个带圆角的矩形 我正在使用 tkinter 的画布 为托比亚斯的方法提供另一种方法确实是用一个多边形来实现 如果您担心优化 或者不必担心引用单个对象的标签系统 那么这将具有成为一个画布对象的优点 该代码有点长 但非常基本 因为它只
  • 测量缩放画布上的文本

    我一直在努力处理文本测量和缩放画布 当画布未缩放时 getTextBounds 和measureText 可提供准确的结果 但是 当缩放画布时 这两种方法都无法提供与打印文本的实际大小相匹配的结果 为了进行测试 我使用以下 onDraw 方
  • 将外部 svg 调用到另一个 svg

    我有多个内联 svgs 所有这些都有一个共同的路径 一个图像 通常这个公共部分应该定期更改 因此 如果我将公共区域保存为单独的 svg 文件 是否可以将通用 svg 文件调用到另一个内联 svg 中 E g main svg
  • IE 和 Edge 上绘制图像时出现 IndexSizeError

    我发现某些代码在 Internet Explorer 和 Edge 中失败 但在 Chrome 和 Firefox 中似乎可以完美运行 var image document getElementById myImage var canvas
  • Canvas 动画在 FireFox 中卡顿,但在 Chrome 中完美

    我最近开始做一些 HTML5 Canvas 的东西 并且很高兴地开展我的业务 在 Chrome 中测试东西 直到我决定尝试我在 Firefox 中所做的事情 效果不太好 这是我正在做的事情的一个简单的例子 设置基本的 requestAnim
  • 在 HTML 画布上绘制线宽连续变化的线条

    我试图画一条线 从一条细线开始 然后逐渐加宽直到结束 我需要绘制半平滑曲线 由几条直线合成 并且在寻找解决此任务的方法时遇到问题 这个小提琴显示了我的问题 http jsfiddle net ZvuQG 1 http jsfiddle ne
  • html5 canvas贝塞尔曲线获取所有点

    我喜欢从贝塞尔曲线中得到一些点 我发现 在javascript中查找三次贝塞尔曲线的所有点 https stackoverflow com questions 15397596 find all the points of a cubic
  • 从 url 加载图像并绘制到 HTML5 Canvas

    我在从 javascript 中的 url 加载图像时遇到问题 下面的代码可以工作 但我不想从 html 加载图像 我想使用纯 JavaScript 从 url 加载图像 var c document getElementById myCa
  • 使用画布矩形裁剪图像

    裁剪图像无法正常工作 我哪里错了 我的Xaml
  • Fabric js-在保存和加载回画布时缺少添加附加属性的扩展 toObject 方法

    我创建了一个带有矩形和文本的织物组 最后 我使用以下代码将自定义属性 名称 添加到组类中 我使用 JSON stringify canvas 将画布数据序列化为 JSON 并将 Json 字符串发送到 java 最后将 Json 字符串保存
  • 尝试使用掩码裁剪位图会抛出 IllegalArgumentException:

    我正在使用以下代码 public void cropSelection Bitmap bitmap annotationBitmap copy annotationBitmap getConfig true Canvas canvas ne
  • KineticJS - 将舞台缩放到视口

    我正在努力将默认分辨率设置为 1366x756 我会根据视口来放大和缩小它 类似于此处显示的示例 http blogs msdn com b davrous archive 2012 04 06 modernizing your html5

随机推荐

  • 人生清单100条

    人生清单是一个个人向往 目标和追求的集合 每个人的清单都会因其个人价值观 兴趣和优先事项而不同 以下是一个包含一些常见目标和价值的人生清单的示例 以供参考 1 学习一门新语言 2 旅行至少10个不同的国家 3 完成一次马拉松 4 创办自己的
  • python 自动复制U盘文件到电脑磁盘v202112012250

    python 自动复制U盘文件到电脑磁盘v202112012250 打包exe去黑框 pyinstaller F w D a1 py import pathlib import time import datetime import shu
  • Dynamics CRM邮箱配置 (OP版)

    Dynamics CRM邮箱配置 Dynamics CRM对邮箱有很好的支持 开通邮箱后方便用户通过邮件进行Dynamics CRM的业务处理 同时也可以作为一直消息流提醒的手段应用于审批 通知等场景 可以做一些更深入的功能拓展 本次集成以
  • MyBatis-Plus详解

    MyBatis Plus 1 简介 1 1 操作步骤 1 2 mybatis plus mapper编写规则 2 注解介绍 2 1 常用注解 2 2 mybatis plus通用Mapper接口 3 条件构造器 4 高级查询 4 1 列投影
  • 学习笔记:多重纹理

    学习笔记 多重纹理 2009 09 01 14 20 52 转载 分类 学习笔记 多重纹理 多重纹理就是在渲染一个多边形的时候可以用到多张纹理图 把多张纹理图进行一些颜色的操作 可以达到一些效果 但是多重纹理必须是在显卡支持的情况下 但是还
  • centOS 配置DNS

    修改 etc resolv conf 重启网卡或者重启电脑后 etc resolv conf会恢复到原来的状态 原因说明 CentOS redhat下面直接修改 etc resolv conf 达到临时效果 但是重启网络后会重置 重启后 根
  • c++ 结构体

    1 结构体定义 整形 长整形 字符型以及浮点型等这些数据类型指南记录单一的数据 而这些数据只能被称为基础数据类型 如果需要定义某种类型 同时包含以上几种的基本数据类型 比如一个人同时含有身高 体重以及年龄的属性 而结构体就是将这些变量类型包
  • @ApiImplicitParams这个注解的作用

    ApiImplicitParams这个注解的作用 ApiImplicitParams是一个用于描述方法参数的注解 它可以用在方法上 作用是为方法中的参数定义多个注解 并将这些注解集中到一个注解集中进行统一管理 通过 ApiImplicitP
  • 1028. 从先序遍历还原二叉树

    题目 https leetcode cn com problems recover a tree from preorder traversal 我们从二叉树的根节点 root 开始进行深度优先搜索 在遍历中的每个节点处 我们输出 D 条短
  • 机器学习--Logistic Regression(逻辑回归)---分类器

    写在之前 带着问题去学习 往往能够让我们有着一个纲领的学习方法 而不会迷失在各种概念 和公式的推导中 1 什么是逻辑回归 逻辑回归的推导 损失函数的推导分别是什么 为什么LR需要归一化或者说取log 2 LR为什么要用sigmoid函数 这
  • 深度学习中分类和回归常见损失函数归纳小结

    1 引言 在深度学习领域中 损失函数定义了模型的预测与目标值之间的距离 因此我们必须正确地选择它 只有这样所有的参数才会根据其值进行更新 损失函数的选择取决于模型的设计 在这篇文章中 我们主要讨论两种常见的的任务 即回归和分类 2 回归损失
  • 蓝桥杯算法训练-印章

    这一题是10月份新加的题 网上也没啥答案 标签为dp动态规划 实际上我觉得不用动态规划也能做 毕竟python是自带了求组合数的函数 下面来看一下吧 试题 算法训练 印章 资源限制 时间限制 1 0s 内存限制 256 0MB 问题描述 共
  • mybatis逆向工程

    使用mybatis的逆向工程生成JavaBean和mapper以及映射文件只需要三个步骤 1 逆向工程maven依赖 2 编写配置文件genarator xml 3 编写主函数 启动类 一 maven依赖
  • 基于AIOT技术的智慧校园空调集中管控系统设计与实现

    毕业论文 设计 题 目 基于AIOT技术的智慧校园空调集中管控系统设计与实现 指导老师 XXXX 专业班级 电子商务2XXXX 姓 名 XXXX 学 号 20XXXXXXXXX 20XX年XX月XX日 摘要 近年来 随着物联网技术和人工智能
  • 【计算机视觉】BLIP:源代码示例demo(含源代码)

    文章目录 一 Image Captioning 二 VQA 三 Feature Extraction 四 Image Text Matching 一 Image Captioning 首先配置代码 import sys if google
  • LU分解,LDLT分解,Cholesky分解

    LU分解 如果方阵是非奇异的 即的行列式不为0 LU分解总是存在的 A LU 将系数矩阵A转变成等价的两个矩阵L和U的乘积 其中L和U分别是下三角和上三角矩阵 而且要求L的对角元素都是1 形式如下 本质上 LU分解是高斯消元的一种表达方式
  • 一个简单的chrome拓展程序开发

    最近突然觉得有些常用的功能可以写成浏览器插件 就不用把代码放到console控制台运行了 只要点击插件图标就可以自动运行 会方便很多 就去查了下chrome插件开发教程 本质上讲 chrome插件就是以一些特殊的方式运行一些特定的html
  • vant组件使用van-field解决邮箱校验问题

    需求 用户在返回到上一页的时候 保存用户的编辑资料 所以用户在输入邮箱的时候 校验是否正确 使用van field
  • Redis基础-命令梳理

    文章目录 一 Redis 客户端的基本语法 二 基础数据类型 字符串 String 三 基础数据类型 哈希 Hash 四 基础数据类型 列表 List 五 基础数据类型 集合 Set 六 基础数据类型 有序集合 Sorted set 一 R
  • 关于canvas画布上绘制多个(单个也一样)不规则多边形,用户点击这张画布时,判断点击的是哪个多边形

    首先来看看canvas效果图 上面是我在canvas上绘制了多个不规则多边形 如果不是很了解怎么绘制 可以看我上个博客canvas画图 盒子结构 div class imgBox div