Path

    xiaoxiao2022-06-30  161

    Path

    内容来自:

    安卓自定义View进阶-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

    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);

    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);

    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);

    贝塞尔曲线

    内容来自:安卓自定义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和Path2XOR异或包含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)

    最新回复(0)