应用场景

我们的项目中有个功能是,canvas上的某个图片选中后可以再这个图片上用鼠标拖拽绘制画笔线条。

当然绘制的边界要控制在图片大小范围内的,那么鼠标是可以随意动的,怎么能控制只在图片上的时候才绘制呢?

Canvas 2D API 有直接提供的方法:CanvasRenderingContext2D.isPointInPath() 用于判断在当前路径中是否包含检测点的方法

isPointInPath介绍

语法:

boolean ctx.isPointInPath(x, y);
boolean ctx.isPointInPath(x, y, fillRule); boolean ctx.isPointInPath(path, x, y);
boolean ctx.isPointInPath(path, x, y, fillRule);

参数:

x 检测点的X坐标  
y 检测点的Y坐标  
fillRule 用来决定点在路径内还是在路径外的算法。
  • "nonzero": 非零环绕规则,缺省值。
  • "evenodd": 奇偶环绕原则 。

返回值:

一个Boolean值,当检测点包含在当前或指定的路径内,返回 true;否则返回 false。

非零环绕原则

规则是从点引出任意一条射线,与路径交点结果计算,如果计数不为0,那么此点就在路径范围里面,在调用fill()方法时,浏览器就会对其进行填充。如果最终值是0,那么此区域就不在路径范围内,浏览器就不会对其进行填充。

首先,我们得给图形确定一条路径,只要“一笔画”并且“不走重复路线”就可以了。如图,标出的是其中的一种路径方向。我们先假定路径的正方向(逆时针)为1,那么反方向(顺时针)就是其相反数-1。(整个定义可以反过来的,正方向为顺时针,反方向为逆时针)

接下来,我们就来判断了。

点P1中引出的任意一条射线L1,与一条正方向路径相交,那么我们就给计数器+1,结果为+1,所以点P1在外面。

点P2中引出的任意一条射线L2,与两条子路径的正方向相交,计数器+2,结果为+2,所以点P2在外面。

点P3中引出的任意一条射线L3,与两条子路径相交,但是其中有一条的反方向,计数器+1-1,结果为0,所以点P3在里面。

点P4中引出的任意一条射线L4,与一条子路径相交,路径为反方向,计数器-1,结果为-1,所以点P4在外面。

只要结果不为0,判断的点就在区域的外面。结果为0,点在区域里面(绿色区域)

奇偶环绕原则

奇偶环绕原则理解为:

平面内的任何一点P,引出一条射线,注意不要经过多边形的顶点,如果射线与多边形的交点的个数为奇数,则点P在多边形的内部;如果交点的个数为偶数,则点P在多边形的外部。

我们用这个方法判断的结果是:

P1,P4与路径交点为1,所以是在里面

P2,P3与路径交点为2,所以实在外面

参考:https://www.jianshu.com/p/ce72c4402f7a

canvas判断点是否在路径内的更多相关文章

  1. canvas路径剪切和判断是否在路径内

    1.剪切路径 clip() var ctx=mycanvas.getContext('2d'); ctx.beginPath(); // 建一个矩形路径 ctx.moveTo(20,10) ctx.l ...

  2. 百度地图 判断marker是否在多边形内

    昨天画了圆形,判marker是否存在圆形内.今天来画多边形,判断marker在多边形内. 需要引入一个js      <script type="text/javascript&quo ...

  3. 【Unity3D自学记录】判断物体是否在镜头内

    判断物体是否在镜头内. 其实很简单的方法 代码如下: using UnityEngine; using System.Collections; public class DJH_IsRendering ...

  4. hrbustoj 1429:凸多边形(计算几何,判断点是否在多边形内,二分法)

    凸多边形 Time Limit: 2000 MS    Memory Limit: 65536 K Total Submit: 130(24 users)   Total Accepted: 40(1 ...

  5. C# 判断点是否在多边形内

    /// <summary>/// 判断点是否在多边形内/// </summary>/// <param name="pnt">点</par ...

  6. js jquery 判断元素是否在数组内

    js jquery 判断元素是否在数组内 一,js方法 var arr = ["a", "b", "c"]; // js arr.index ...

  7. js 日期比较大小,js判断日期是否在区间内,js判断时间段是否在另外一个时间段内

    /** * 日期解析,字符串转日期 * @param dateString 可以为2017-02-16,2017/02/16,2017.02.16 * @returns {Date} 返回对应的日期对 ...

  8. JS判断元素是否在数组内

    //判断元素是否在数组内 function contains(arr, obj) { var i = arr.length; while (i--) { if (arr[i] === obj) { r ...

  9. C#路径的八种相关操作,判断字符串是否为路径等

    原文:C#路径的八种相关操作,判断字符串是否为路径等 1.判定一个给定的C#路径是否有效,合法 通过Path.GetInvalidPathChars或Path.GetInvalidFileNameCh ...

随机推荐

  1. NGK公链依靠技术创新推动数字经济产业发展

    数字经济更让人们的生活发生了翻天覆地的变化.数字经济的发展要依靠技术的创新,发展出生态新模式.同时数字经济的发展要利用新技术对传统产业进行全面的的改造升级,释放数字对经济发展的放大.倍增作用.打造数字 ...

  2. MySQL修改表中字段的字符集

    MySQL修改表中字段的字符集 ALTER TABLE 表名 MODIFY 字段名 要修改的属性: 例:ALTER TABLE `guaduates` MODIFY `studentno` CHAR( ...

  3. (转)linux下的系统调用函数到内核函数的追踪

    转载网址:http://blog.csdn.net/maochengtao/article/details/23598433 使用的 glibc : glibc-2.17使用的 linux kerne ...

  4. C++算法代码——和为给定数

    题目来自:http://218.5.5.242:9018/JudgeOnline/problem.php?cid=1376&pid=0 题目描述 给出若干个整数,询问其中是否有一对数的和等于给 ...

  5. 03.Jupyter Notebook高级-魔法命令

    %run %run C:\Users\User\Desktop\hello.py hello world %timeit %timeit L = [i for i in range(1000)] 29 ...

  6. Typescript快速入门

    目录 什么是Typescript 为什么学习Typescript 快速搭建开发环境 1.安装node.js 2.使用node自带的npm安装Typescript编译器 3.配置vscode编辑环境 4 ...

  7. Elasticsearch---DSL搜索实践

    Domain Specific Language 特定领域语言,基于JSON格式的数据查询,查询更灵活,有利于复杂查询 一.普通url路径参数搜索 数据准备 1.建立名字为 shop 的索引 2.手动 ...

  8. IHttpClientFactory 踩过的坑

    public class BasicUsageModel : PageModel { private readonly IHttpClientFactory _clientFactory; publi ...

  9. 扒几个 3D 模型备用

    前言 在上一篇中,我展示了 OpenGL 开发的基本过程,算是向 3D 世界迈出的一小步吧.对于简单的 3D 物体,比如立方体.球体.圆环等等,我们只需要简单的计算就可以得到他们的顶点的坐标.但是仅仅 ...

  10. Java Socket编程基础及深入讲解

    原文链接:https://www.cnblogs.com/yiwangzhibujian/p/7107785.html 原文写的特别好,非常详细,但是禁止转载,那我就不再复制粘贴了! socket实现 ...