记录一下 NSBezierPath 的基本知识
NSBezierPath组成
NSBezierPath主要由4中Element组成,它们的枚举为:
NSMoveToBezierPathElement 移动绘制点到指定的点,这种类型通常作为第一个点
NSLineToBezierPathElement 从当前的绘制的点到指定的点,创建一条直线
NSCurveToBezierPathElement 从当前的绘制点到指定的点,绘制一掉曲线
这个Element与其他的Element不同,它包含3个点,其他的Element只包含一个点
三个点顺序为:controlPoint1, controlPoint2, endPoint
绘制曲线的控制点的理解可以参考:iOS世界里的贝塞尔曲线(一):贝塞尔曲线基础
NSClosePathBezierPathElement 将指定的点标记为曲线的结束点,并闭合曲线,注意这个Element标记的点就是当前的绘制点。
上面图片对应的例程:
NSBezierPath* aPath = [NSBezierPath bezierPath];
[aPath moveToPoint:NSMakePoint(0.0, 0.0)];
[aPath lineToPoint:NSMakePoint(10.0, 10.0)];
[aPath curveToPoint:NSMakePoint(18.0, 21.0)
controlPoint1:NSMakePoint(6.0, 2.0)
controlPoint2:NSMakePoint(28.0, 10.0)];
[aPath appendBezierPathWithRect:NSMakeRect(2.0, 16.0, 8.0, 5.0)];
appendBezierPathWithRect:
的说明:首先会把当前的绘制点移动到Rect的原点,然后逆时针的方向绘制Rect。
Subpaths
subpath 由一系列的线段和曲线构成,一个NSBezierPath对象可以包含多个Subpath,当使用moveToPoint:
或者closePath
方法的时候,将当前绘制中的path关闭了,接下来绘制的path都是新的subpath。
使用moveToPoint
结束当前path的绘制,并确定下一个subPath绘制的起点。
使用closePath
方法会闭合当前绘制点的path,在最开始的绘制点与最后的绘制点之间连接一条直线。
一些NSBezierPath的方法会自动创建一个新的subpath,如上面代码用到过的appendBezierPathWithRect:
subpath会影响填充,Winding Rules有说明。
subpath还会影方法响如bezierPathByReversingPath的运行结果。
一个NSBezierPath的所有subpath共用同样的Path Attributes。
Path Attributes
Line Width(线段宽度)
默认的line width是1,可以通过[NSBezierPath setDefaultLineWidth:]
来设置默认的宽度。
setLineWidth:
设置当前path的宽度。
如果要设置非NSBezierPath对象的默认宽度,可以通过Quartz的CGContextSetLineWidth
方法来设置
Line Cap Styles
一张图,不多说
用setLineCapStyle:
方法设置。setDefaultLineCapStyle:
设置默认的。
Line Join Styles
用setLineJoinStyle:
方法设置,setDefaultLineJoinStyle:
设置默认的
Line Dash Style
Line Flatness
Miter Limits
Winding Rules
Winding Rules用来确定path构成的一块区域是否需要填充。
不管是open还是close的path都可以通过Winding Rules来判断。
以Close Path path element结尾的path是close的,以Move To path element结尾的path是open的。
- NSNonZeroWindingRule 区域内取一点画射线(不要经过虚线的闭合线段?),相交的部分,如果是顺时针则-1,如果是逆时针则+1,和为0说明在曲线外,其他值说明在曲线内
- NSEvenOddWindingRule 区域内取一点画射线,有偶数个相交点则不再曲线内,奇数个相交点则在曲线内