canvas 形状碰撞_中秋前夕,聊聊canvas

2024-01-31 00:59

本文主要是介绍canvas 形状碰撞_中秋前夕,聊聊canvas,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

起因

首先上图: 

4276ed56f67d1a6146a5870c773c1d29.png

今天,我们前端群问了一个这样的问题,然后就开始了激烈的讨论。那么下面咱们一起来看看这个问题,这个问题问了两个小问题:

1.如何在 canvas 上绘制多边形?
2.鼠标怎么选中绘制的某一个图形?

那么咱们就来分为两个问题解答。

绘制多边形

    要绘制一个多边形,多边形图形的基本元素是路径。路径是通过不同颜色和宽度的线段或曲线相连形成的不同形状的点的集合。一个路径,甚至一个子路径,都是闭合的。使用路径绘制图形需要一些额外的步骤。

  • 首先,你需要创建路径起始点

  • 然后你使用画图命令去画出路径。

  • 之后你把路径封闭

  • 一旦路径生成,你就能通过描边或填充路径区域来渲染图形。以上这些步骤会用到一些 API:

beginPath()
新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径。

closePath()
闭合路径之后图形绘制命令又重新指向到上下文中。

stroke()
通过线条来绘制图形轮廓。

fill()
通过填充路径的内容区域生成实心的图形。

详解绘制过程

这里详细解答一下绘制的过程:第一步,生成路径,调用 beginPath,本质上路径是有很多子路径所构成的,这些子路径全部在一个列表里面,所有的子路径(线、弧)构成图形。而每次调用这个方法之后,列表都会被重置,然后就可以绘制新的图形。(你需要在设置路径之后指定你的起始位置);第二步,调用指定函数绘制路径;第三步,闭合路劲 closePath(不是必须的);

笔式绘图仪模型

绘制一个三角形例子:

var ctx = canvas.getContext("2d");ctx.beginPath(); //开始路径ctx.moveTo(75, 50); //指定起始位置ctx.lineTo(100, 75); //绘制到这个位置的一条线ctx.lineTo(100, 25); //绘制到这个位置的一条线ctx.fill(); //填充图形,默认就制动结束路径了

    在这个过程中,有一个比较有用的函数,moveTo,这个函数实际上画不出来任何东西,它是属于上面描述的路劲列表的一部分。

    看下这个函数的作用:

moveTo()
将笔触移动到指定的坐标 x 以及 y 上。

    当 canvas 初始化或者 beginPath()调用后,你通常会使用 moveTo()函数设置起点。我们也能够使用 moveTo()绘制一些不连续的路径。

    这个时候你可以想象一下在纸上画东西,笔尖从一个点到另一个点的移动过程。这个过程的模式叫做笔式绘图仪模式。所以 canvas 2d 绘图的模式也就是这种模式。

    现在绘制多边形就没有什么问题了。

canvas 上找出指定的图形

    首先,完成描述一下这个问题:按下鼠标,如何判断出选中了某一个图形?比如下图: 

1ff373c41de572ac27d5564c923eb1fc.png

    鼠标点击了这个不规则多边形的内部,怎么判断?

    第一反应就是 isPointInPath,或者是迭代所有图形,拿鼠标的点去与图形的点碰撞检测,这个方法可以用,但是适用场景比较少,还有就是性能开销比较大,如果图形太多,每一个都需要经过计算,那么这个交互会变得非常的不友好。

    有没有其他方案了,在游戏界有一个普遍使用的方案——包围盒,什么是包围盒呢?我们以上面的图形举例,外面画的红线框就是这个多边形的包围盒。

    很形象的一个例,就是公司发的月饼盒子,就是里面圆圆的月饼 🥮 的包围盒。

    包围盒的方案有个缺点,选取的范围比较粗。比如上图的红框,框选了不是多边形部分的内容。如果你想用包围盒的方案来做,那就要分的足够细,比如下图: 

ec5d3a3d984f315e1b302357ea1cf70f.png

    分出来了多个包围盒,这种情况在图形特别复杂的时候,包围盒这个方案就有点粗糙了。

    还有下图这种,实心和空心圆,用包围盒也就非常的不友好。 

3e309901ed342a244eb413a6f0baee79.png

 那怎么办?

方案

    如果想要快速选中某一个图形,我们能不能对我们的每一个图形有一个对应的 hash,而在鼠标点击的时候,又能够取到这个 hash。用 hash 的值,去找这个图形,这个过程的时间复杂度是 O(1)。

比如在画布的这些图形: 

c58b510f70abd6b5cb615c6ea940c772.png

在另一张一模一样的画布上,画了这些图形 

3ab115c2270862fc107d7e7512627c53.png

上层画布(显示出来的)是正常的图形,但是每个图形分配一个 rgb 色值。下层画布(隐藏)用这个 rgb 色值做填充或者 stroke。当鼠标点击的时候,在隐藏画布相同的位置,取一个像素点。

而这个像素点的rgb值就是我们要找的 hash。

至此,两个问题已经解答了,这几天中秋节,祝大家中秋节快乐,阖家幸福,人长久,共婵娟。

最后附上想进前端群的可以加微信,备注:玄说前端。

af67b878d4bb0adbff9234ae4ddc4658.png

END

获得更多信息

关注公众号

ff057fc0dd8999799e15c2a72453dc89.png

73a683260e0096c9249d9c76b77a3d2d.png

这篇关于canvas 形状碰撞_中秋前夕,聊聊canvas的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/662115

相关文章

OpenCV结构分析与形状描述符(11)椭圆拟合函数fitEllipse()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C++11 算法描述 围绕一组2D点拟合一个椭圆。 该函数计算出一个椭圆,该椭圆在最小二乘意义上最好地拟合一组2D点。它返回一个内切椭圆的旋转矩形。使用了由[90]描述的第一个算法。开发者应该注意,由于数据点靠近包含的 Mat 元素的边界,返回的椭圆/旋转矩形数据

聊聊说话的习惯

1 在日常生活中,每个人都有固定的说话习惯。心理学研究表明,通过一个人的说话习惯,也可以分析出他的性格特点。对于每一个人来讲,说话习惯已经融为他们生活中的一部分。在社交活动中,一些不良的说话习惯很可能会给他们带来麻烦。因此,了解说话习惯对心理活动的影响是十分有必要的。 2 具有顺畅的说话习惯的人,大多思路清晰、语速适中、用词准确并且声声人耳,是典型的顺畅型说话方式这种类型的人要么不说话,要么

聊聊分布式,再讨论分布式解决方案

前言 最近很久没有写博客了,一方面是因为公司事情最近比较忙,另外一方面是因为在进行 CAP 的下一阶段的开发工作,不过目前已经告一段落了。 接下来还是开始我们今天的话题,说说分布式事务,或者说是我眼中的分布式事务,因为每个人可能对其的理解都不一样。 分布式事务是企业集成中的一个技术难点,也是每一个分布式系统架构中都会涉及到的一个东西,特别是在微服务架构中,几乎可以说是无法避免,本文就分布式事

OpenCV结构分析与形状描述符(10)检测并提取轮廓函数findContours()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C++11 算法描述 在二值图像中查找轮廓。 该函数使用算法 253从二值图像中检索轮廓。轮廓是有用的工具,可用于形状分析和对象检测与识别。参见 OpenCV 示例目录中的 squares.cpp。 findContours 是 OpenCV 库中的一个重要函数

OpenCV结构分析与形状描述符(8)点集凸包计算函数convexHull()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C++11 算法描述 查找一个点集的凸包。 函数 cv::convexHull 使用斯克拉斯基算法(Sklansky’s algorithm)来查找一个二维点集的凸包,在当前实现中该算法的时间复杂度为 O(N logN)。 函数 cv::convexHull 是

OpenCV结构分析与形状描述符(9)检测轮廓相对于其凸包的凹陷缺陷函数convexityDefects()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C++11 算法描述 查找一个轮廓的凸性缺陷。 下图显示了一个手部轮廓的凸性缺陷: convexityDefects 是 OpenCV 库中的一个函数,用于检测轮廓相对于其凸包的凹陷缺陷。这个函数可以帮助识别轮廓中的凹进去的部分,通常被用来分析手部或其他物体的形状

urdf ( xacro ) 的 collision碰撞参数设置

目录 写在前面的话整体流程1 URDF 文件结构2 查看原始碰撞形状描述3 加入简单碰撞形状描述方法一 Meshlab 自动测量方法二 人为测量 4 加入XACRO函数简化描述 最终结果展示侧视图正视图碰撞几何体中心点设置不对出现的结果 写在前面的话 本文使用的 URDF 文件是由 solidworks 的 URDF export 插件生成,详情请看上一篇文章:solidwor

聊聊资源调度

资源调度 般分为两个阶段: 是实现物理资源的虚拟化(即资源的抽象)于当前机器的性能越来越好,硬件配置越来越高,直接用物理机跑业务比较浪费,所以将物理机分割成更小单位的虚拟机,这样可以显著提升机器的利用效率,在公司内部一般采用容器技术来隔离资源 是将资源虚拟化后进 步在时间和空间上实现更细粒度的编排 ,优化资源的使用。 1 .一些数据 如果公司的几万台机器都是物理机,那么资源的使用率稍低: CP

影响画布微信小程序canvas及skyline和webview用户界面布局的关键流程

影响微信小程序画布canvas及skyline和webview用户界面布局的关键流程 目录 影响微信小程序画布canvas及skyline和webview用户界面布局的关键流程 一、微信小程序canvas开发流程 1.1、官方指南 1.2、客制化开发 第一步:在 WXML 中添加 canvas 组件 第二步:获取 Canvas 对象和渲染上下文 第三步 画布#ID选择器执行回调——

中秋国庆请客喝酒,面子与钱包双赢的红酒选择

平时生活中,总少不了各种聚会,不管是朋友小聚,还是正式的商务宴请,酒都是少不了的,而现在,越来越多的人都喜欢选择红酒来助兴。 喝红酒的人不少,懂红酒的人却不多。有时候真的很尴尬,明明环境菜都不错,就是红酒太难喝,每一口都要鼓足勇气才能下咽。 其实,酒也是饭局的重要组成部分,如果酒不好喝,客人事后也是会暗暗吐槽的。所以,一个好的饭局,酒一定也是好的。 这里说的“好”,既要面子上