非零环绕规则
非零环绕规则是图形学中判断某个区域是在所属区域外面还是内部的一种规则。
简单说一下就是这个样子:对于路径中的任意给定区域,从该区域内部画一条足够长的线段,使此线段的终点完全露在路径范围之外。然后将计数器初始化为0,每当这条线段与路径上的直线或曲线相交时,就改变计数器的值。如果与路径顺时针部分相交的时候,则加1;如果与路径的逆时针部分相交的时候,则减1。如果最终值不是0,那么说明区域在路径的里面。
如上图,一条闭合的路径,围绕成了3个区域,也就是图中的A、B、C(图略丑,凑合着看吧)。 A区域向外引一条线段(绿色的),可以看到与路径的顺时针相交,所以计数器加1,变成了1,而再外面一些是不会相交了,由于1不是0,所以A在路径里面。 同理,B区域引一条线段,我们可以看到和逆时针相交,所以减1,也就是-1,也不会再与路径相交了,由于-1不是0,所以B也在路径的内部。 对于C我们引入一条线段,它2次都与顺时针相交,所以计数为2,也就在区域的内部了。
明白了基本的原理我们看一个代码相关的例子吧。 现有HTML:
<canvas id="canvas">不支持canvas</canvas>
如果支持HTML5的canvas
的时候会创建一个默认大小为300px*150px
的canvas画板;如果不支持的时候会把canvas当成一个div元素来处理,那么就会显示里面的文字了。
然后我们使用JS来绘制图案:
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
context.fillStyle = "red";
context.beginPath();
context.arc(150, 75, 50, 0, Math.PI * 2, false);
context.arc(150, 75, 25, 0, Math.PI * 2, true);
context.fill();
由上我们画了2个弧线,顶点都是(150,75)的位置(其实就是canvas的中心),然后半径一个是50,一个是25,都是从0到2π(弧度2π也就是360°),所以我们画的是2个圆形(弧线是从右边开始画弧的)。最后一个参数有意思,如果为true的时候是逆时针绘制,如果是false则是顺时针绘制(默认是false),那么上述路径中,内圆内部向外引一条射线,那么与内圆交叉的地方是逆时针,那么减1,而与外圆相交的地方是顺时针,所以加1,所以最终的结果是0,也就是内圆内部其实是路径的外面,所以绘制出来的结果如下:
如果我们把上述画弧的最后一个参数都去掉的话(使用默认值false),那么效果是怎么样子呢?当然是内圆内部也在路径的内部了(有点绕),如下:
- TortoiseSVN客户端使用的2个配置问题
- JavaWeb(二)会话管理之细说cookie与session
- 概率论09 期望
- Javascript中数组的sort()和reverse()方法
- CentOS6.5开放端口,配置防火墙
- JavaWeb(一)Servlet中乱码解决与转发和重定向的区别
- Java魔法堂:四种引用类型、ReferenceQueue和WeakHashMap
- Javascript中数组的使用
- JavaWeb(一)Servlet中的request与response
- 数据库18456错误怎么解决
- JavaWeb(一)Servlet中的ServletConfig与ServletContext
- 语义化HTML:p、h1-6、q、blockquote、hr、address、code、pre、var、cite、dfn和samp
- Win7系统 IIS 调试ASP(aspcmsgbk25) 错误号:3706 提示 “未找到提供程序 该程序可能未正确安装”解决办法
- 普通文件和数据库存储的对比
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 树莓派Redis集群部署
- Linux防止ssh暴力破解常用方案
- 实用!8个 chrome插件玩转GitHub,单个文件下载小意思
- LeetCode105|有序数组的平方
- LeetCode104|求根到叶子节点数字之和
- LeetCode103|路径总和II
- LeetCode102|二叉树的所有路径
- LeetCode101|路径总和
- LeetCode100|两个数组的交集II
- LeetCode108|数组中重复的数字
- LeetCode107|从上打印二叉树
- LeetCode106|从尾到头打印链表
- LeetCode113|两数之和
- LeetCode112|两数之和II-输入有序数组
- LeetCode111|独一无二的出现次数