非零缠绕规则和奇偶规则

在图形学中判断一个点是否在多边形内,若多边形不是自相交的,那么可以简单的判断这个点在多边形内部还是外部;若多边形是自相交的,那么就需要根据非零环绕规则和奇-偶规则判断。

判断多边形是否是自相交的:多边形在平面内除顶点外还有其他公共点

内-外测试
    不自交的多边形:多边形仅在顶点处连接,而在平面内没有其他公共点,此时可以直接划分内-外部分。
    自相交的多边形:多边形在平面内除顶点外还有其他公共点,此时划分内-外部分需要采用以下的方法。

(1)奇-偶规则(Odd-even Rule):奇数表示在多边形内,偶数表示在多边形外

从任意位置p作一条射线,若与该射线相交的多边形边的数目为奇数,则p是多边形内部点,否则是外部点。

(2)非零环绕规则(Nonzero Winding Number Rule):若环绕数为0表示在多边形内,非零表示在多边形外
    首先使多边形的边变为矢量。将环绕数初始化为零。再从任意位置p作一条射线。当从p点沿射线方向移动时,对在每个方向上穿过射线的边计数,每当多边形的边从右到左穿过射线时,环绕数加1,从左到右时,环绕数减1。处理完多边形的所有相关边之后,若环绕数为非零,则p为内部点,否则,p是外部点。

奇偶规则和线的方向没有关系(逆时针或者顺时针), 非零缠绕规则是根据线的方向来确定的.

判断点p是否在多边形内,从点p向外做一条射线(可以任意方向),多边形的边从左到右经过射线时环数减1,多边形的边从右往左经过射线时环数加1,最后环数不为0,即表示在多边形内部。

当然,非零绕数规则和奇偶规则会判断出现矛盾的情况,如下图所示,左侧表示用 奇偶规则判断绕环数为2 ,表示在多边形外,所以没有填充。右侧图用非零绕环规则判断出绕数为2,非0表示在多边形内部,所以填充。

另外一个例子,如下

非零环绕规则和奇-偶规则(Non-Zero Winding Number Rule&&Odd-even Rule)在iphone中应用

1.CGContextClip  使用非零环绕规则来判断当前路径和裁剪路径的交集。

2.CGContextEOClip 使用奇偶环绕规则来判断当前路径和裁剪路径的交集。

时间: 2024-08-04 11:17:26

非零缠绕规则和奇偶规则的相关文章

填充路径时所使用的 “非零环绕规则”

工作繁忙之际,抽了点时间看了下canvas,今天看到了“非零环绕规则”,抱着好奇的心里写了下书上的demo看了看效果,感觉还蛮实用的. 先简单说说“非零环绕规则”原理(基本摘自书本):如果绘图路径是循环的,或是包含多个相交的子路径,那么canvas的绘图环境变量就必须要判断,当fill()方法被调用时,应该如何对当前路径进行填充.canvas在填充那种互相有交叉路径时就会使用到“非零环绕规则”.“非零环绕规则是这么来判断自我交叉情况的路径的:对于路径中的任意给定的区域,从该区域内部画一条足够长的

Canvas中的非零围绕规则原理

非零围绕规则:对于路径中指定范围区域,从该区域内部画一条足够长的线段.使此线段的全然落在路径范围之外. 非零围绕规则计数器:然后,将计数器初始化为0,每当这个线段与路径上的直线或曲线相交时,就改变计数器的值,假设是与路径顺时针相交时.那么计数器就加1, 假设是与路径逆时针相交时.那么计数器就减1.假设计数器始终不为0,那么此区域就在路径范围里面,在调用fill()方法时,浏览器就会对其进行填充.假设终于值是0,那么此区域就不在路径范围内,浏览器就不会对其进行填充. 从上图中看第一条线段:依据非零

Canvas中的非零环绕规则原理

非零环绕规则:对于路径中指定范围区域,从该区域内部画一条足够长的线段,使此线段的完全落在路径范围之外. 非零环绕规则计数器:然后,将计数器初始化为0,每当这个线段与路径上的直线或曲线相交时,就改变计数器的值,如果是与路径顺时针相交时,那么计数器就加1, 如果是与路径逆时针相交时,那么计数器就减1.如果计数器始终不为0,那么此区域就在路径范围里面,在调用fill()方法时,浏览器就会对其进行填充.如果最终值是0,那么此区域就不在路径范围内,浏览器就不会对其进行填充. 从上图中看第一条线段:根据非零

填充路径时使用的非零环绕规则

如果当前路径是循环的,或者包含多个相交的子路径,那么Canvas的绘图环境变量就必须判断,当fill()方法被调用时,应该如何对当前路径进行填充. Canvas在填充互相有交叉的路径时,使用非零环绕规则 非零环绕 对于路径中的任意给定区域,从该区域内部画一条足够长的线段,使此线段的终点完全落在路径范围之外. 接下来将计数器初始化为0,然后,每当这条线段与路径上的直线或曲线相交时,就改变计算器的值.如果是与路径的顺时针部分相交,则加1,如果与路径的逆时针相交,则减1. 若计算器的最终值不是0,那么

非规则浮点数和规则浮点数

本文由量化.数据类型.上溢和下溢衍生,将浮点数看作是实数域的一种量化方式,分析浮点数,尤其是非规则浮点数和规则浮点数之间的差异. 0. 背景.动机和目的 为了更好理解本文内容,可先行阅读<量化.数据类型.上溢和下溢>中内容.这里依旧将浮点数看作是一种量化方式,将连续的不可数的集合映射到有限的集合上去.本文结合单精度浮点数讨论,双精度浮点与之类似. 已有多位博主撰写过关于非规则浮点数(Denormalized Number)和规则浮点数之间的区别,这里首推卢钧轶的你应该知道的浮点数基础知识.这篇

递归转非递归(13条消除规则)

直接递归的消去规则: 基本思路:将递归调用的地方用等价的非递归代码来代替,并对return语句做适当处理.13条规则:处理直接递归调用和return语句,将之转换成等价的迭代代码. 初始化     ⑴ 在过程的开始部分,插入说明为栈的代码并将其初始化为空:  StackType Stack[1..SIZE]      Top ← 0    在一般情况下,这个栈用来存放参数.局部变量和函数的值.每次递归调用的返回地址.   ⑵ 将标号L1附于第一条可执行语句.      ...     L1:第一

Keil MDK下如何设置非零初始化变量(转)

源:Keil MDK下如何设置非零初始化变量 一些工控产品,当系统复位后(非上电复位),可能要求保持住复位前RAM中的数据,用来快速恢复现场,或者不至于因瞬间复位而重启现场设备.而keil mdk在默认情况下,任何形式的复位都会将RAM区的非初始化变量数据清零.如何设置非初始化数据变量不被零初始化,这是本篇文章所要探讨的. 在给出方法之前,先来了解一下代码和数据的存放规则.属性,以及复位后为何默认非初始化变量所在RAM都被初始化为零了呢. 什么是初始化数据变量,什么又是非初始化数据变量?(因为我

Canvas中的非零环绕

先上图 当要填充图形时,必须区分开哪些部分是覆盖的,哪些是空的,根据绘制的方向可以判断出来 非零环绕规则:对于路径中指定范围区域,从该区域内部画一条足够长的线段,使此线段的完全落在路径范围之外. 非零环绕规则计数器:然后,将计数器初始化为0,每当这个线段与路径上的直线或曲线相交时,就改变计数器的值,如果是与路径顺时针相交时,那么计数器就加1, 如果是与路径逆时针相交时,那么计数器就减1.如果计数器始终不为0,那么此区域就在路径范围里面,在调用fill()方法时,浏览器就会对其进行填充.如果最终值

n!最右非零数字

n!最右非零数字 注此文大部分来自luoyuchu的blog + ##Description: 给出正整数N(可能有前导0),请求出N!最右非零的数位的值 + ##Range: n<=10^100 + HDU1066 弱化问题USACO 3.2.1 以前做USACO暴力水过了 这是多么的愚昧于是我去学习了一下 考虑虑到末位的0 是由于 2 * 5 这样的运算而产生的,那么我们把2与5成对的剔除就不会出现精度问题了? 其实问题还可以继续深入思考.我们考虑在 10^1000 下如何解决问题 我们考虑