http://my.eoe.cn/37547/archive/3712.html
android 在绘制多边形时可以指定填充方式。主要涉及的函数和参数有:
- Path 类提供的设置填充方式的函数: public void setFillType(Path.FillType ft).
-
填充方式的枚举类型:
Path.FillType EVEN_ODD,用奇偶规则填充
Path.FillType INVERSE_EVEN_ODD,顾名思义,和EVEN_ODD规则恰好相反。
Path.FillType INVERSE_WINDING,同样,WINDING的反效果。
Path.FillType WINDING,用非零环绕数规则填充。
下面详细说明下什么是奇偶规则和非零环绕数规则:
奇偶规则和非零环绕数都是计算机图形学中用来判断一个点是否在多边形内部的算法。奇偶规则是指:对任意点P,从P到无穷远处画一条射线,注意该射线不能喝多边形的任何顶点相交,计算该射线和多边形的各条边的交点个数,如果交点数目为奇数,则认为P点再多边形内,反之,为偶数则认为P点再多边形外。非零环绕数规则是指从任意点P同样想无穷远处画一条射线,同样不能喝任何顶点相交。首先初始化环绕边数为0,当P点沿射线方向移动时,统计该穿过该射线的边的方向。每当多边形从右到左穿过射线时,边数加1,反之减1。最后如果环绕边数为非0,则认为P是内部点,为0则认为P是外部点。下图是一个关于这两个规则的示意图:
![3-4 填充方式示意图.png 3-4 填充方式示意图.png](http://a1.eoe.cn/www/home/201305/30/3d76/51a720ce5ca9a.png)
下面是示例代码的运行结果截图和源码:
![3-5 填充方式运行效果图.png 3-5 填充方式运行效果图.png](http://a1.eoe.cn/www/home/201305/30/d1a8/51a720e48a5b0.png)
源码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
package com.example.androidgraphicsprogramm;
import android.app.Activity;
import android.content.Context;
import android.graphics.*;
import android.os.Bundle;
import android.view.View;
public class PathFillType extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
private static class SampleView extends View {
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Path mPath;
public SampleView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
mPath = new Path();
mPath.addCircle(40, 40, 45, Path.Direction.CCW);
mPath.addCircle(80, 80, 45, Path.Direction.CCW);
}
private void showPath(Canvas canvas, int x, int y, Path.FillType ft,
Paint paint) {
canvas.save();
canvas.translate(x, y);
canvas.clipRect(0, 0, 120, 120);
canvas.drawColor(Color.WHITE);
mPath.setFillType(ft);
canvas.drawPath(mPath, paint);
canvas.restore();
}
@Override protected void onDraw(Canvas canvas) {
Paint paint = mPaint;
canvas.drawColor(0xFFCCCCCC);
canvas.translate(20, 20);
paint.setAntiAlias(true);
showPath(canvas, 0, 0, Path.FillType.WINDING, paint);
showPath(canvas, 160, 0, Path.FillType.EVEN_ODD, paint);
showPath(canvas, 0, 160, Path.FillType.INVERSE_WINDING, paint);
showPath(canvas, 160, 160, Path.FillType.INVERSE_EVEN_ODD, paint);
}
}
}
|