Path

Path

内容来自:

Path类封装了直线段,二次贝塞尔曲线和三次贝塞尔曲线的几何路径。

作用相关方法备注
移动起点moveTo移动下一次操作的起点位置
设置终点setLastPoint重置当前path中最后一个点位置,如果在绘制之前调用,效果和moveTo相同
连接直线lineTo添加上一个点到当前点之间的直线到Path
闭合路径close连接第一个点连接到最后一个点,形成一个闭合区域
添加内容addRect, addRoundRect, addOval, addCircle, addPath, addArc, arcTo添加(矩形, 圆角矩形, 椭圆, 圆, 路径, 圆弧) 到当前Path (注意addArc和arcTo的区别)
是否为空isEmpty判断Path是否为空
是否为矩形isRect判断path是否是一个矩形
替换路径set用新的路径替换到当前路径所有内容
偏移路径offset对当前路径之前的操作进行偏移(不会影响之后的操作)
贝塞尔曲线quadTo, cubicTo分别为二次和三次贝塞尔曲线的方法
rXxx方法rMoveTo, rLineTo, rQuadTo, rCubicTo不带r的方法是基于原点的坐标系(偏移量), rXxx方法是基于当前点坐标系(偏移量)
填充模式setFillType, getFillType, isInverseFillType, toggleInverseFillType设置,获取,判断和切换填充模式
提示方法incReserve提示Path还有多少个点等待加入(这个方法貌似会让Path优化存储结构)
布尔操作(API19)op对两个Path进行布尔运算(即取交集、并集等操作)
计算边界computeBounds计算Path的边界
重置路径reset, rewind清除Path中的内容 reset 不保留内部数据结构,但会保留FillType. rewind会保留内部的数据结构,但不保留FillType
矩阵操作transform矩阵变换

方法说明

lineTo

lineTo绘制直线,起点是上次调用的最后一个点的坐标,如果没有,则为坐标原点

canvas.translate(mWidth / 2, mHeight / 2);  // 移动坐标系到屏幕中心(宽高数据在onSizeChanged中获取)

Path path = new Path();                     // 创建Path

path.lineTo(200, 200);                      // lineTo
path.lineTo(200,0);

canvas.drawPath(path, mPaint);              // 绘制Path

直线01

addXxx与arcTo

基本形状
// 第一类(基本形状)

// 圆形
public void addCircle (float x, float y, float radius, Path.Direction dir)
// 椭圆
public void addOval (RectF oval, Path.Direction dir)
// 矩形
public void addRect (float left, float top, float right, float bottom, Path.Direction dir)
public void addRect (RectF rect, Path.Direction dir)
// 圆角矩形
public void addRoundRect (RectF rect, float[] radii, Path.Direction dir)
public void addRoundRect (RectF rect, float rx, float ry, Path.Direction dir)

Path.Direction表示是顺时针还是逆时针

类型解释翻译
CWclockwise顺时针
CCWcounter-clockwise逆时针
合并path
// 第二类(Path)
// path
//合并path
public void addPath (Path src)
//将src进行了位移之后再添加进当前path中
public void addPath (Path src, float dx, float dy) 
//将src添加到当前path之前先使用Matrix进行变换
public void addPath (Path src, Matrix matrix)

如下的例子:

canvas.translate(mWidth / 2, mHeight / 2);  // 移动坐标系到屏幕中心
canvas.scale(1,-1);                         // <-- 注意 翻转y坐标轴

Path path = new Path();
Path src = new Path();

path.addRect(-200,-200,200,200, Path.Direction.CW);
src.addCircle(0,0,100, Path.Direction.CW);

path.addPath(src,0,200);

mPaint.setColor(Color.BLACK);           // 绘制合并后的路径
canvas.drawPath(path,mPaint);

path02

addArc与arcTo
// 第三类(addArc与arcTo)

// addArc 直接添加一个圆弧到path中
public void addArc (RectF oval, float startAngle, float sweepAngle)

// arcTo 添加一个圆弧到path,如果圆弧的起点和上次最后一个坐标点不相同,就连接两个点
public void arcTo (RectF oval, float startAngle, float sweepAngle)
public void arcTo (RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)
  • oval - 圆弧的外切矩形
  • startAngle - 开始角度
  • sweepAngle - 扫过角度(-360 <= sweepAngle <360)
  • forceMoveTo - 是否强制使用MoveTo
    • true - 将最后一个点移动到圆弧起点,即不连接最后一个点与圆弧起点
    • false - 不移动,而是连接最后一个点与圆弧起点
canvas.translate(mWidth / 2, mHeight / 2);  // 移动坐标系到屏幕中心
canvas.scale(1,-1);                         // <-- 注意 翻转y坐标轴

Path path = new Path();
path.lineTo(100,100);

RectF oval = new RectF(0,0,300,300);

path.addArc(oval,0,270);
// path.arcTo(oval,0,270,true);             // <-- 和上面一句作用等价

canvas.drawPath(path,mPaint);

path03

canvas.translate(mWidth / 2, mHeight / 2);  // 移动坐标系到屏幕中心
canvas.scale(1,-1);                         // <-- 注意 翻转y坐标轴

Path path = new Path();
path.lineTo(100,100);

RectF oval = new RectF(0,0,300,300);

path.arcTo(oval,0,270);
// path.arcTo(oval,0,270,false);             // <-- 和上面一句作用等价

canvas.drawPath(path,mPaint);

path04

贝塞尔曲线

内容来自:安卓自定义View进阶-Path之贝塞尔曲线

二阶曲线

        Path path = new Path();

        path.moveTo(start.x,start.y);
        path.quadTo(control.x,control.y,end.x,end.y);

        canvas.drawPath(path, mPaint);

三阶曲线

        Path path = new Path();

        path.moveTo(start.x, start.y);
        path.cubicTo(control1.x, control1.y, control2.x,control2.y, end.x, end.y);

        canvas.drawPath(path, mPaint);

其它

内容来自:安卓自定义View进阶-Path之完结篇

rXxx方法

rXxx方法的坐标使用的是相对位置(基于当前点的位移),而之前方法的坐标是绝对位置(基于当前坐标系的坐标)。

Android中的填充模式

模式简介
EVEN_ODD奇偶规则
INVERSE_EVEN_ODD反奇偶规则
WINDING非零环绕数规则
INVERSE_WINDING反非零环绕数规则

Inverse 和含义是“相反,对立”,说明反奇偶规则刚好与奇偶规则相反,例如对于一个矩形而言,使用奇偶规则会填充矩形内部,而使用反奇偶规则会填充矩形外部

填充效果

Android与填充模式相关的方法

方法作用
setFillType设置填充规则
getFillType获取当前填充规则
isInverseFillType判断是否是反向(INVERSE)规则
toggleInverseFillType切换填充规则(即原有规则与反向规则之间相互切换)

如下的例子,内外2个矩形,先使用EVEN_ODD填充规则

        mPaint.setStyle(Paint.Style.FILL);                   // 设置画布模式为填充
        mPaint.setColor(Color.RED);

        canvas.translate(mWidth / 2, mHeight / 2);          // 移动画布(坐标系)

        Path outerPath = new Path();                                   // 创建Path
        outerPath.addRect(-400, -400, 400, 400, Path.Direction.CW); // 给Path中添加一个矩形
        outerPath.setFillType(Path.FillType.EVEN_ODD);                   // 设置Path填充模式为 奇偶规则
        //outerPath.setFillType(Path.FillType.INVERSE_EVEN_ODD);            // 反奇偶规则

        Path innerPath = new Path();
        innerPath.addRect(-200,-200,200,200, Path.Direction.CW);         // 给Path中添加一个矩形

        //合并path
        outerPath.addPath(innerPath);

        canvas.drawPath(outerPath, mPaint);

效果为:

机构填充

填充规则为反奇偶填充规则INVERSE_EVEN_ODD,效果为:

反奇偶填充规则

当内外矩形都为顺时针,使用非零环绕规则WINDING
非零环绕规则

当内外矩形都为顺时针,使用反非零环绕规则INVERSE_WINDING

反非零环绕规则

当内矩形为逆时针,外矩形为顺时针,使用非零环绕规则WINDING

非零环绕规则

当内矩形为逆时针,外矩形为顺时针,使用反非零环绕规则INVERSE_WINDING

反非零环绕规则

布尔操作(API19)

逻辑名称类比说明示意图
DIFFERENCE差集Path1中减去Path2后剩下的部分差集
REVERSE_DIFFERENCE差集Path2中减去Path1后剩下的部分差集
INTERSECT交集Path1与Path2相交的部分交集
UNION并集包含全部Path1和Path2并集
XOR异或包含Path1与Path2但不包括两者相交的部分异或

如下的例子:

        mPaint.setStyle(Paint.Style.FILL);

        canvas.translate(mWidth / 2, mHeight / 2);

        Path path1 = new Path();
        Path path2 = new Path();
        Path path3 = new Path();
        Path path4 = new Path();

        path1.addCircle(0, 0, 200, Path.Direction.CW);
        path2.addRect(0, -200, 200, 200, Path.Direction.CW);
        path3.addCircle(0, -100, 100, Path.Direction.CW);
        path4.addCircle(0, 100, 100, Path.Direction.CCW);

        if (Build.VERSION.SDK_INT >= 19) {
            path1.op(path2, Path.Op.DIFFERENCE);
            path1.op(path3, Path.Op.UNION);
            path1.op(path4, Path.Op.DIFFERENCE);

        }


        canvas.drawPath(path1, mPaint);

布尔操作

计算边界

这个方法主要作用是计算Path所占用的空间以及所在位置,方法如下:

void computeBounds (RectF bounds, boolean exact)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值