Android Paint 画笔的一些偏知识
setStrokeCap(Paint.Cap cap) 设置线头的形状
放出「平头」「圆头」「方头」这种翻译我始终有点纠结:既觉得自己翻译得简洁清晰尽显机智,同时又担心用词会不会有点太过通俗,让人觉得我不够高贵冷艳?
当线条的宽度是 1 像素时,这三种线头的表现是完全一致的,全是 1 个像素的点;而当线条变粗的时候,它们就会表现出不同的样子:
虚线是额外加的,虚线左边是线的实际长度,虚线右边是线头。有了虚线作为辅助,可以清楚地看出 BUTT 和 SQUARE 的区别。
setStrokeJoin(Paint.Join join)
设置拐角的形状。有三个值可以选择:MITER 尖角、 BEVEL 平角和 ROUND 圆角。默认为 MITER。
辅助理解:
MITER 在现实中其实就是这玩意:
而 BEVEL 是这玩意:
setStrokeMiter(float miter)
这个方法是对于 setStrokeJoin() 的一个补充,它用于设置 MITER 型拐角的延长线的最大值。所谓「延长线的最大值」,是这么一回事:
当线条拐角为 MITER 时,拐角处的外缘需要使用延长线来补偿
而这种补偿方案会有一个问题:如果拐角的角度太小,就有可能由于出现连接点过长的情况。比如这样:
所以为了避免意料之外的过长的尖角出现, MITER 型连接点有一个额外的规则:当尖角过长时,自动改用 BEVEL 的方式来渲染连接点。例如上图的这个尖角,在默认情况下是不会出现的,而是会由于延长线过长而被转为 BEVEL 型连接点:
至于多尖的角属于过于尖,尖到需要转为使用 BEVEL 来绘制,则是由一个属性控制的,而这个属性就是 setStrokeMiter(miter) 方法中的 miter 参数。miter 参数是对于转角长度的限制,具体来讲,是指尖角的外缘端点和内部拐角的距离与线条宽度的比。也就是下面这两个长度的比:
用几何知识很容易得出这个比值的计算公式:如果拐角的大小为 θ ,那么这个比值就等于 1 / sin ( θ / 2 ) 。
这个 miter limit 的默认值是 4,对应的是一个大约 29° 的锐角:
默认情况下,大于这个角的尖角会被保留,而小于这个夹角的就会被「削成平头」
所以,这个方法虽然名叫 setStrokeMiter(miter) ,但它其实设置的是「 线条在 Join 类型为 MITER 时对于 MITER 的长度限制」。它的这个名字虽然短,但却存在一定的迷惑性,如果叫 setStrokeJoinMiterLimit(limit) 就更准确了。 Google 的工程师没有这么给它命名,大概也是不想伤害大家的手指吧,毕竟程序员何苦为难程序员。
以上就是 4 个关于线条形状的方法: setStrokeWidth(width) setStrokeCap(cap) setStrokeJoint(join) 和 setStrokeMiter(miter)。