svg画五角星,关于fill-rule的理解

先上代码
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="300px" height="300px">
  <polygon points="100,0 160,180 10,60 190,60 40,180" style="fill:red;stroke:black;stroke-width:1;fill-rule:nonzero"/>
</svg>

画出来是这样的


把fill-rule改成evenodd后,是这样的


先看看官方文档里面fill-rule两个属性的解释,

nonzero—这个规则通过从canvas上的某个点往任一方向绘制射线到无穷远,然后检查图形的线段和射线相交的点,来确定“内部区域”。从0开始计数,每次路径线段是从左到右穿过射线就加一,从右到左的就减一。通过计算交叉点,如果结果是0,则这个点在路径外边,不然,就是在里边。


evenodd—这个规则通过从canvas上某个点往任一方向绘制射线到无穷远,然后计算给定图形上线段路径和该射线交叉点的数量。如果这个数是奇数,那么该点在图形内部;如果是偶数,该点在图形外部。


一看两幅图,你可能会有两个疑问,这些线段的箭头是什么?两组图形的第三幅图为什么是一样的?其实这些线段的方向是由我们给出的坐标的顺序决定的,points="100,0 160,180 10,60 190,60 40,180",起始点是最上方的点,然后是右下,最左边,最右边,再到左下。把这些点按顺序连起来就变成了五角星。

先在图上随机取几个点,蓝色射线的起始点就是随机的点,射线1,2,3,4穿过的图形线段数分别是1,2,3,4,如图


先看nozero时,怎么判断点是否在内部区域。射线1和图形线段只有一个交点,为从左到右,所以结果是1,判定为内部区域;射线2有两个交点,都是从左到右,结果是2,内部区域;射线3有三个交点,两个从左到右,一个从右到左,结果是1,内部区域;射线4有四个交点,两个从左到右,两个从右到左,结果是0,所以是外部区域。

evenodd时,只判断交点个数,所以1,3都是内部区域,2,4都是外部区域。

结果就很清楚啦,那两组图的第三个图为什么是一样的,也一目了然啦,在圆环内的点,与图形线段的交点有两个,一左进右出,一右进左出,所以两种判定方式下都是外部区域。

因为方向没固定,所以从一个点可以作出无数条射线,那会不会出现不同射线有不同结果的情况呢?我尝试去掉了一个角

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="300px" height="300px">
  <polygon points="135,104 100,0 40,180 190,60 10,60 100,132" style="fill:red;stroke:black;stroke-width:1;fill-rule:evenodd;"/>
</svg>


结果是这样的,我认为这里右下角的线段其实应该算是两条,画图时两次经过了这个地方,所以应该不能算一条线段,而是两条,所以按上面讲的规则,还是没错。暂时想不到会产生不一样结果射线的点。

学到这里,仍存在两个问题:

1、是否有某些点画出来的射线会得到不同的结果,而最终的结果又是根据哪个?

2、简单的图形容易判断,那复杂的图形呢?怎么才能直观的理解这两个规则?比如下图:


以上内容皆为个人理解,若有错误,请指教。谢谢。

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值