Path:

Path类封装复合(多轮廓)几何路径由直线段、二次曲线和三次曲线组成。它可以用画布绘制。drawPath(路径、绘制),填充或笔划(基于绘画的样式),或者可以用于剪裁或绘制路径上的文本。

Path属于路径,路径走多了就变成一种套路,只要我们会解套,那这种套路就是高速公路。路径走完形成闭环,最终形成一个图形。

path的合作伙伴是Paint

Paint:

paint.setAntiAlias(true);
     // 设置画笔的style (Paint.Style.FILL填充,Paint.Style.STROKE描边    Paint.Style.FILL_AND_STROKE填充加描边)
        paint.setStyle(Paint.Style.STROKE);
        // 设置画笔的颜色
        paint.setColor(Color.RED);
        //设置描边宽度
        paint.setStrokeWidth(10f);

关于setStyle:

1.有人会发现不同的填充效果不一样,比如绘制路径,三个点,描边出来的效果是两条线,而填充模式下是一个三角形的色块。


Paint.Style.FILL_AND_STROKE:会出现角有缺陷,在使用需要注意


Android Canvas之Path的详解与使用(二)_重置

   paint.setStyle(Paint.Style.STROKE);

Android Canvas之Path的详解与使用(二)_贝塞尔曲线_02

paint.setStyle(Paint.Style.FILL);

 


Android Canvas之Path的详解与使用(二)_android_03

paint.setStyle(Paint.Style.FILL_AND_STROKE);

 

 

一、Path的使用

1.构造一个path对象

1.1:构造一个空对象


public Path() 1.2 拷贝一个对象 public Path(Path src)


二、Path的方法介绍

2.1:moveTo(x,y);

path默认的起始坐标是0,0;如果想改变起始坐标,通过moveTo来设置

private void moveTo(Path path) {
        path.moveTo(x, y);
        path.lineTo(0, 1000);
        path.lineTo(500, 500);


    }

Android Canvas之Path的详解与使用(二)_数据结构_04

Android Canvas之Path的详解与使用(二)_贝塞尔曲线_05

 

 图一是没设置moveTo,默认(0,0)坐标,图二是moveTo(100,100)新的坐标点

 

2.2rLineTo

与lineTo相同,但坐标被视为相对于最后一个此轮廓上的点。如果没有上一个点,则将moveTo(0,0)将自动插入。

说明:这里有三个点A(0,0)B(0,1000)C(1000,0)

rLineTo:从A点到B点,C点的坐标以B点为起点,也就是后一个点以前一个坐标为起点

LineTo:直接将A、B、C三个点按顺序在view中连起来

private void rLineTo(Path path) {

        path.rLineTo(0, 1000);
        path.rLineTo(1000, 0);

    }


Android Canvas之Path的详解与使用(二)_数据结构_06

rLineTo

Android Canvas之Path的详解与使用(二)_android_07


LineTo

 

 2.3贝塞尔曲线:quadTo


public void quadTo(float x1, float y1, float x2, float y2)


一般曲线是由三个点完成,开始,顶点,结束。在而塞尔曲线中,

(x1,y1)为曲线的顶点

(x2,y2)为曲线的结束点

开始默认是(0,0),可以通过moveTo来改变

private void quadTo(Path path) {
        path.moveTo(100, 0);
        path.quadTo(100, 1000, 1000, 0);
    }

Android Canvas之Path的详解与使用(二)_重置_08

  2.4贝塞尔曲线:rQuadTo

与quadTo相同,但坐标被视为相对于最后一个此轮廓上的点。如果没有上一个点,则将moveTo(0,0)将自动插入。

可参考上方

2.5立方贝塞尔:cubicTo


public void cubicTo(float x1, float y1, float x2, float y2,float x3, float y3)


从接近控制点的最后一点添加一个立方贝塞尔(x1,y1)和(x2,y2),并在(x3,y3)处结束。如果没有moveTo()调用对于此轮廓,第一个点自动设置为(0,0)

private void cubicTo(Path path) {

        int width=getWindowSize(0)/2;
        int height=getWindowSize(1)/2;

        path.cubicTo(0, height, width, height, width, 0);
    }

Android Canvas之Path的详解与使用(二)_重置_09

 

2.6圆弧:arcTo


public void arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)


将指定的圆弧作为新轮廓附加到路径。如果开始路径与路径的当前最后一点不同,则添加了automatic lineTo()以将当前轮廓连接到弧的起点。但是,如果路径为空,则调用moveTo()弧的第一点

oval:扇形图形view大小

startAngle:开始角度

sweepAngle:扇形角度

forceMoveTo:如果为真,则始终以圆弧开始新轮廓

private void arcTo(Path path) {
        paint.setStyle(Paint.Style.FILL);
        RectF rectF=new RectF(0,0,500,500);
        path.arcTo(rectF,startAngle,sweepAngle,true);

    }


Android Canvas之Path的详解与使用(二)_贝塞尔曲线_10

paint.setStyle(Paint.Style.STROKE)

 

Android Canvas之Path的详解与使用(二)_重置_11

paint.setStyle(Paint.Style.FILL)

 

2.7关闭当前轮廓 :close

关闭当前轮廓。如果当前点不等于轮廓的第一个点,自动添加线段。


没有调用close()之前:三个点确定两条线


private void close(Path path) {
    path.moveTo(100,100);
    path.lineTo(100,500);
    path.lineTo(500,500);
}


Android Canvas之Path的详解与使用(二)_android_12

未调用close()

调用close():三个点,首位相连

 

private void close(Path path) {
        path.moveTo(100,100);
        path.lineTo(100,500);
        path.lineTo(500,500);
        path.close();
    }


Android Canvas之Path的详解与使用(二)_android_13

调用close()

 

2.8将闭合矩形轮廓添加到路径:addRect


public void addRect(RectF rect, Direction dir)


rect:矩形区域

dir:缠绕矩形轮廓的方向,CW=顺时针,CCW=逆时针

private void addRect(Path path)
    {

        RectF rect=new RectF(0,0,500,500);
        path.addRect(rect, Path.Direction.CCW);

    }

Android Canvas之Path的详解与使用(二)_重置_14

2.9绘制椭圆:addOval

 


public void addOval(RectF oval, Direction dir)


private void addOval(Path path) {
        RectF rect = new RectF(0, 0, 1000, 500);
        path.addOval(rect, Path.Direction.CCW);
    }

注意:如果矩形是正方形绘制出来的图形是圆形

Android Canvas之Path的详解与使用(二)_贝塞尔曲线_15

 2.10绘制圆形:addCircle


public void addCircle(float x, float y, float radius, Direction dir)


(x ,y):圆心的坐标

radius:半径

private void addCircle(Path path) {
        path.addCircle(100, 100, 100, Path.Direction.CCW);
    }

Android Canvas之Path的详解与使用(二)_android_16

 2.11在矩形区域画弧度:addArc


public void addArc(RectF oval, float startAngle, float sweepAngle)


如果这个矩形是一个正方形,那么画出来的弧度是半圆形,否则是一个不规则的股弧度

private void addArc(Path path) {
        paint.setStyle(Paint.Style.STROKE);
        RectF rect = new RectF(0, 0, 500, 500);
        path.addArc(rect,0,180);

    }

Android Canvas之Path的详解与使用(二)_重置_17

 

private void addArc(Path path) {
    paint.setStyle(Paint.Style.FILL);
    RectF rect = new RectF(0, 0, 500, 500);
    path.addArc(rect,0,180);

}

Android Canvas之Path的详解与使用(二)_贝塞尔曲线_18

 

private void addArc(Path path) {
        paint.setStyle(Paint.Style.FILL);
        RectF rect = new RectF(0, 0, 1000, 500);
        path.addArc(rect,0,180);

    }

Android Canvas之Path的详解与使用(二)_数据结构_19

 

private void addArc(Path path) {
        paint.setStyle(Paint.Style.STROKE);
        RectF rect = new RectF(0, 0, 1000, 500);
        path.addArc(rect,0,180);

    }

Android Canvas之Path的详解与使用(二)_android_20

 2.12在矩形中绘制一个圆形:addRoundRect


public void addRoundRect(RectF rect, float rx, float ry, Direction dir)


(rx,ry)代表圆形在矩形中的中心坐标,如果这个坐标正在矩形的正中心,那绘制出来的正好是圆形,否则距离中心远近代表角度的大小

注意:这里面rx或者ry中,只要有一个角的坐标为0,都无法生效。

rx和ry其实看成到各个顶点的角度百分比。

rx=ry,四个角大小是一致,否则不一样

private void addRoundRect(Path path) {
        RectF rect = new RectF(0, 0, 1000, 500);
        path.addRoundRect(rect,500,100, Path.Direction.CW);
    }

Android Canvas之Path的详解与使用(二)_android_21

 

private void addRoundRect(Path path) {
        RectF rect = new RectF(0, 0, 1000, 500);
        path.addRoundRect(rect,rect.right/2,rect.bottom/2, Path.Direction.CW);
    }

Android Canvas之Path的详解与使用(二)_贝塞尔曲线_22

 

private void addRoundRect(Path path) {
        RectF rect = new RectF(0, 0, 1000, 500);
        path.addRoundRect(rect,100,100, Path.Direction.CW);
    }

Android Canvas之Path的详解与使用(二)_重置_23

 

private void addRoundRect(Path path) {
        RectF rect = new RectF(0, 0, 1000, 500);
        path.addRoundRect(rect,0,0, Path.Direction.CW);
    }

Android Canvas之Path的详解与使用(二)_贝塞尔曲线_24

 

2.13在path中添加新的path :addPath


1.public void addPath(Path src, Matrix matrix)


2.public void addPath(Path src)


3.public void addPath(Path src, float dx, float dy)


matrix和(dx,dy)可以指定src在path中的坐标,类似View在viewGroup的坐标。如果没有,默认覆盖在父path的view上,坐标dx=dy=0;

private void addPath(Path path) {
        RectF rect = new RectF(0, 0, 1000, 500);
        path.addRoundRect(rect,0,0, Path.Direction.CW);

        Path path1=new Path(path);
        Matrix matrix=new Matrix();
        matrix.setTranslate(200,200);

        path.addPath(path1,100,100);
        path.addPath(path1,matrix);

    }

Android Canvas之Path的详解与使用(二)_数据结构_25

2.14整体偏移 :offset

offset是针对整个path来完成偏移的,而不是某个点,MoveTo是针对起始坐标点

如下:起始坐标是0,0。通过偏移来完成整体的下移

private void offset(Path path) {
        RectF rect = new RectF(0, 0, 1000, 500);
        path.addRoundRect(rect,0,0, Path.Direction.CW);

        path.offset(100,100);


    }

 

Android Canvas之Path的详解与使用(二)_数据结构_26

 

2.15重置最后一个点的位置:setLastPoint

正常如下:

private void setLastPoint(Path path) {
        path.lineTo(0,1000);
        path.lineTo(500,1000);
//        path.setLastPoint(500,500);

    }


Android Canvas之Path的详解与使用(二)_数据结构_27

正常

Android Canvas之Path的详解与使用(二)_数据结构_28

path.setLastPoint(500,500)

 

 

2.16 path的控制:transform

通过Matrix对path的路径进行控制和操控,比offset更灵活,只要操作Matrix即可完成当前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

矩阵变换