PathMeasure就是对Path进行计算的类。
PathMeasure有两个构造方法:
方法名 | 释义 |
---|---|
PathMeasure() | 创建一个空的PathMeasure |
PathMeasure(Path path, boolean forceClosed) | 创建 PathMeasure 并关联一个指定的Path(Path需要已经创建完成)。 |
PathMeasure主要方法:
返回值 | 方法名 | 释义 |
---|---|---|
void | setPath(Path path, boolean forceClosed) | 关联一个Path |
boolean | isClosed() | 是否闭合 |
float | getLength() | 获取Path的长度 |
boolean | nextContour() | 跳转到下一个轮廓 |
boolean | getSegment(float startD, float stopD, Path dst, boolean startWithMoveTo) | 截取片段 |
boolean | getPosTan(float distance, float[] pos, float[] tan) | 获取指定长度的位置坐标及该点切线值 |
boolean | getMatrix(float distance, Matrix matrix, int flags) | 获取指定长度的位置坐标及该点Matrix |
PathMeasure的第二个构造函数中的path就是要测量的对象,后边的forceClosed是设置要不要闭合计算。
比如说一个不必和的path,使用PathMeasure计算它的长度,如果forceClosed为false,则计算的就是这条path的真是长度,如果forceClosed为true,那么PathMeasure计算出来的长度就是真是长度加上首尾。
PathMeasure中forceClosed的设置不会对path产生任何影响。
简单讲一下setPath、 isClosed 和 getLength
setPath 是 PathMeasure 与 Path 关联的重要方法,效果和 构造函数 中两个参数的作用是一样的。
isClosed 用于判断 Path 是否闭合,但是如果你在关联 Path 的时候设置 forceClosed 为 true 的话,这个方法的返回值则一定为true。
getLength 用于获取 Path 的总长度,在之前的测试中已经用过了。
getSegment
getSegment是用来获取path中某一段的path对象
boolean getSegment (float startD, float stopD, Path dst, boolean startWithMoveTo)
getSegment用来获取path路径中从startD到stopD的一段,然后将这一段添加在dst中。startWithMoveTo是用来判断你现在截取的这一段要不要连接dst中之前的路径。因为截取的路径是添加到dst中的,所以dst中之前可能已经有路径了。
如果 startD、stopD 的数值不在取值范围 [0, getLength] 内,或者 startD == stopD 则返回值为 false,不会改变 dst 内容。
canvas.translate(mWidth / 2, mHeight / 2);
Path path = new Path();
path.addRect(-200, -200, 200, 200, Path.Direction.CW);
Path dst = new Path();
PathMeasure pathMeasure = new PathMeasure();
pathMeasure.setPath(path, false);
pathMeasure.getSegment(200, 600, dst, true);
//保持当前获取的这段路径起始点不变
// pathMeasure.getSegment(800, 900, dst, true);
//不保持当前获取的这段路径起始点不变
pathMeasure.getSegment(800, 900, dst, false);
canvas.drawPath(dst, paint);
nextContour
Path可能不是有一条路径组成的,PathMeasure中的getLength(),getSegment()方法都是作用在一条路径上的。如果我们想要测量下一条路径,就可以使用nextContour()方法跳到下一条路径上,然后在进行计算测量。
canvas.translate(mViewWidth / 2, mViewHeight / 2); // 平移坐标系
Path path = new Path();
path.addRect(-100, -100, 100, 100, Path.Direction.CW); // 添加小矩形
path.addRect(-200, -200, 200, 200, Path.Direction.CW); // 添加大矩形
canvas.drawPath(path,mDeafultPaint); // 绘制 Path
PathMeasure measure = new PathMeasure(path, false); // 将Path与PathMeasure关联
float len1 = measure.getLength(); // 获得第一条路径的长度
measure.nextContour(); // 跳转到下一条路径
float len2 = measure.getLength(); // 获得第二条路径的长度
Log.i("LEN","len1="+len1); // 输出两条路径的长度
Log.i("LEN","len2="+len2);
结果:
com.gcssloop.canvas I/LEN: len1=800.0
com.gcssloop.canvas I/LEN: len2=1600.0mn
getPosTan
这个方法用于得到路径上某一长度的坐标和该位置正切值。
boolean getPosTan (float distance, float[] pos, float[] tan)
getPosTan方法是将举例起点distance距离的位置的坐标值存入pos中,将这一点的正切值存放到tan中。
tan代表这一点在曲线上的方向,可以用Math.atan2(tan[1], tan[0]) 获取到正切角的弧度值,弧度值可以转化为角度值。
tan[0]是临边长,tan[1]代表对边长。
我们此处用 tan 来描述 Path 上某一点的切线方向,主要用了两个数值 tan[0] 和 tan[1] 来描述这个切线的方向(切线方向与x轴夹角) 。具体讲解参考:安卓自定义View进阶-PathMeasure
getMatrix
这个方法是用于得到路径上某一长度的位置以及该位置的正切值的矩阵:
boolean getMatrix (float distance, Matrix matrix, int flags)
这个方法可以讲距起点distance这一位置的坐标位置和正切值存入矩阵matrix中,flags有两个值:POSITION_MATRIX_FLAG(位置)
ANGENT_MATRIX_FLAG(正切)
可以两个一起选择,中间用|分隔
measure.getMatrix(distance, matrix, PathMeasure.TANGENT_MATRIX_FLAG | PathMeasure.POSITION_MATRIX_FLAG);