搞懂svg/canvas中nonzero和evenodd填充规则(代码片段)

ssen ssen     2023-01-06     319

关键词:

一、填充有两种规则

技术分享图片

只要是路径填充,都有两种规则,nonzero和evenodd,无论是SVG中的路径填充,还是Canvas中的路径填充,如果还有其他和路径相关的技术(甚至设计软件),也离不开这两种填充规则。

换句话说,这是超越各种语言,普世通用的技能点。

下面,看看我能不能用足够精简的语言,尽可能让大家都搞懂这两种路径填充规则。

如果我们用3个点,连成一个三角形,则这两种填充规则没什么区别,如下对比(Canvas语法举例,JS实时渲染,如果无效果,请访问原文)。

nonzero(默认)evenodd
   

如果是两个三角形,并且发生重叠,差异就出现了,如下:

nonzero(默认)evenodd
   

究竟是如何作用的呢?且看~

二、一切都是交叉点们的选择

填充规则的关键,就是确定复杂路径构成的图形,哪些是内部,哪些是外部。内部则填充,外部则透明。

“nonzero规则”顾名思意就是“非零规则”,用通俗的话讲,就算计算某些东西是不是0,如果不是0则内部,填充;如果是0则外部,不填充。

“evenodd规则”顾名思意就是“奇偶规则”,用通俗的话讲,就算计算某些东西是不是奇数,如果是是奇数则内部,填充;如果是偶数则外部,不填充。

下面关键来了,这里的“计算某些东西”究竟计算的是什么东西呢?

nonzero规则和evenodd规则计算的东西还不一样,nonzero是计算顺时针逆时针数量,evenodd是交叉路径数量。


为了示意更加直观,我们可以把本文示意的三角路径方向和序号标记下,如下表:

nonzero(默认)evenodd
   

 

接下来,高能来了……


我们要判断某一个区域是路径内还是路径外,很简单,在这个区域内任意找一个点,然后以这个点为起点,发射一条无限长的射线,然后——

  • 对于nonzero规则:起始值为0,射线会和路径相交,如果路径方向和射线方向形成的是顺时针方向则+1,如果是逆时针方向则-1,最后如果数值为0,则是路径的外部;如果不是0,则是路径的内部,因此被称为“非0规则”。

    一图胜千言:

    技术分享图片

    例如上图点A,我们随便发出一条射线,结果经过了路径5和路径2,我们顺着路径前进方向和射线前进方向,可以看到,合并后的运动方向都是逆时针,逆时针方向-1,因此,最后计算值是-2,不是0,因此,是内部,fill时候可以被填充。

    再看外部的例子,一图胜千言+1:

    技术分享图片

    点B再发出一条射线,经过两条路径片段,为路径2和路径3,我们顺着路径前进方向和射线前进方向,可以看到,合并后的运动方向一个是逆时针,-1,一个是顺时针,+1,因此,最后的计算值是0,是外部,因此,不被填充。

  • 对于evenodd规则:起始值为0,射线会和路径相交,每交叉一条路径,我们计数就+1,最后看我们的总计算数值,如果是奇数,则认为是路径内部,如果是偶数,则认为是路径外部。

    一图胜千言+2:

    技术分享图片

    例如上图点A,我们随便发出一条射线,结果经过了路径5和路径2,交叉的路径个数为2,是偶数,因此,属于路径外,不填充。

    一图胜千言+3:

    技术分享图片

    点B再发出一条射线,经过路径片段路径2和路径3,交叉的路径个数为2,是偶数,因此,也属于路径外,不填充。

    一图胜千言+4:

    技术分享图片

    最后这个点C,发出的射线总共和3个路径交叉,是奇数。因此,属于路径内,填充。

三、啦啦啦,结束语

不知大家搞懂没?

技术分享图片

快速响应的交互式图表/图形:SVG、Canvas 还是其他?

】快速响应的交互式图表/图形:SVG、Canvas还是其他?【英文标题】:Fastandresponsiveinteractivecharts/graphs:SVG,Canvas,other?【发布时间】:2012-08-3120:38:50【问题描述】:我正在尝试选择合适的技术来更新项目,该项目基本上在可缩放、可... 查看详情

canvas一段背景色鼠标移入后

...加了一个没有意义的DOM节点,不符合语义化编程规范SVG、Canvas都可以使用脚本语言来实现动画SVG本质上是使用XML描述2D图形的语言(矢量图),SVG创建的每一个元素都是一个独立的DOM元素,既然是独立的DOM元素,那表示我们可以... 查看详情

htmld3:svg,canvas,path,style:svgtrianglewithoutline(代码片段)

查看详情

prolog中两个执行偶数和奇数的区别(代码片段)

我有两个Prolog的实现,函数是决定给定的数字是奇数还是偶数第一个正常工作even1(0).even1(X):-X>0,X1isX-1,odd1(X1).odd1(1).odd1(X):-X>1,X1isX-1,even1(X1).even1(2)返回true但第二个不能正常工作even2(0).even2(X):-X>0,odd2(X-1).odd2(1).odd2(X):- 查看详情

使用fabric.js加载SVG中的错误图像大小

...加载SVG文件:svg_url2="http://localhost/fabric/bozzabiglietto-03.svg";canvas=newfabric.Canvas(\'canvas\ 查看详情

python利用循环计算50到100中奇数的和和偶数的和?

...和if语句可以计算50到100中奇数的和和偶数的和。odd_sum=0even_sum=0foriinrange(50,101):ifi%2==0:even_sum+=ielse:odd_sum+=iprint("50到100中偶数的和为:",even_sum)print("50到100中奇数的和为:",odd_sum)以上代码中,我们首先定义了两个变... 查看详情

nonzero(代码片段)

...为0的元素的索引(indics)。fromnumpyimportarray1fromnumpyimportnonzero2x=array([[1,0,0],[0,2,0],[1,1,0]])3print(x)4nonzero(x) output:[[100][020][110]](array([0,1,2,2],dtype=int64),array([0,1,0,1],dtype=int64))这个是要把两行捏在一起来看:[0,1,2,2][0,1,0,1]代表作为... 查看详情

使用 nth-last-child(odd) 和 (even) 将 css 添加到图像

】使用nth-last-child(odd)和(even)将css添加到图像【英文标题】:Usingnth-last-child(odd)and(even)toaddcsstoanimage【发布时间】:2019-06-2222:59:37【问题描述】:我在wordpress页面中有一个有2行的部分,第一行布局是文本|图像和第二行布局是文本|... 查看详情

html5新特性

...个检测你掌握程度的检测html5新特性综述:1、用于绘画的canvas和SVG,    canvas和SVG都允许在浏览器中创建图片,但是他们的实现原理是不同的。    SVG通过xml完成2d图形的绘制;--------- 查看详情

一文全搞懂postgresql的权限

权限结构图pg中权限至上而下层次分明,首先要了解pg的逻辑架构,如下图需要注意的是在如上架构中数据库是严格分开的,这意味着不能同时使用两个不同的数据库,而模式不是严格分开的,可以一起使用和访问同一数据库的... 查看详情

从喧闹与富有中搞懂搜索和拓扑(代码片段)

前言大家好我是bigsai。今天给大家分享一个非常有趣的面试题,通过这个问题你可能会对某些情况下,搜索和拓扑有一定的认识,一个问题,既可以用搜索来处理,用记忆化搜索优化,也可以用拓扑排序来... 查看详情

从喧闹与富有中搞懂搜索和拓扑(代码片段)

前言大家好我是bigsai。今天给大家分享一个非常有趣的面试题,通过这个问题你可能会对某些情况下,搜索和拓扑有一定的认识,一个问题,既可以用搜索来处理,用记忆化搜索优化,也可以用拓扑排序来... 查看详情

向文件添加新的目标成员身份会导致“没有这样的模块”和“Command CompileSwiftSources failed with a nonzero exit code”

】向文件添加新的目标成员身份会导致“没有这样的模块”和“CommandCompileSwiftSourcesfailedwithanonzeroexitcode”【英文标题】:Addingnewtargetmembershiptofilescauses"Nosuchmodule"and"CommandCompileSwiftSourcesfailedwithanonzeroexitcode"【发布 查看详情

如何为 svg 路径的渐进式绘制动画?

...间】:2012-12-2520:42:58【问题描述】:我想仅使用带有svg/canvas和js的css来为线条的渐进式绘制动画。我想画的线的想法可以找到here<svgxmlns="http://www.w3.org/2000/svg"><!--CreatedwithSVG- 查看详情

彻底搞懂标准盒模型和怪异盒模型(代码片段)

一:标准盒模型:box-sizing:content-box;1:首先强调一点:这个盒子真正的的大小是由文本区域content内边距padding和边框border组成。但在标准盒模型的代码中的with和height是只指向content的大小不包含padding和border的。我... 查看详情

数据可视化实践(代码片段)

...的第三方库都是基于这两种浏览器图形渲染技术实现的:Canvas和SVG。canvas和webGL都是基于openGL来进行封装。但是webGL由于更贴近openGL所以学习曲线较陡,这里就讲解Canvas和SVG两种。下面是两种图形渲染技术的对比SVGCanvas不依赖分... 查看详情

cas和aqs一文搞懂(代码片段)

JAVA多线程,面试官喜欢问的东西一些概念的东西原子性就是指该操作是不可再分的。不论是多核还是单核,具有原子性的量,同一时刻只能有一个线程来对它进行操作。简而言之,在整个操作过程中不会被线程调... 查看详情

java多态——一个案例彻底搞懂它(代码片段)

原文:https://www.cnblogs.com/1693977889zz/p/8296595.html 最近,发现基础真的很重要。比如,Java中多态的特性,在学习中就是很难懂,比较抽象的概念。学的时候就犯糊涂,但日后会发现,基础在日常工作的理解中占有重要的角色。... 查看详情