PathMeasure
路径测量,一个用来测量Path的工具类
常用API:
- Path的测量
- Path的跳转
- Path片段获取
Path的测量
先进行绘制
Path path = new Path();
path.lineTo(0,200);
path.lineTo(200,200);
path.lineTo(200,0);
进行测量
pathMeasure需要关联一个创建好的path, forceClosed会影响Path的测量结果
//forceClosed = true,会计算四边的长度
PathMeasure pathMeasure = new PathMeasure();
pathMeasure.setPath(path, true);
Log.e("TAG", "forceClosed=true "+ pathMeasure.getLength());
//forceClosed = false,会计算只绘制的3边的长度
PathMeasure pathMeasure2 = new PathMeasure();
pathMeasure2.setPath(path, false);
Log.e("TAG", "forceClosed=false "+ pathMeasure2.getLength());
进行绘制
canvas.drawPath(path, mPaint);
运行程序,可以看到日志
E/TAG: forceClosed=true 800.0
E/TAG: forceClosed=false 600.0
如果Path进行了调整,需要重新调用setPath方法进行关联
截取Path
startWithMoveTo:是否把截取的path,moveto到起始点。
startWithMoveTo为true
Path path = new Path();
path.addRect(-200,-200, 200,200, Path.Direction.CW);
Path dst = new Path();
dst.lineTo(-300,-300);//添加一条直线 (原本已经绘制的,没有影响)
PathMeasure pathMeasure = new PathMeasure(path, false);
//截取一部分存入dst中,startWithMoveTo:保持截取得到的Path第一个点位置不变。
pathMeasure.getSegment(200, 1000, dst, true);
startWithMoveTo为false
Path path = new Path();
path.addRect(-200,-200, 200,200, Path.Direction.CW);
Path dst = new Path();
dst.lineTo(-300,-300);//添加一条直线 (原本已经绘制的,没有影响)
PathMeasure pathMeasure = new PathMeasure(path, false);
//截取一部分存入dst中,startWithMoveTo:保持截取得到的Path第一个点位置不变。
pathMeasure.getSegment(200, 1000, dst, false);
跳转到下一条曲线
Path path = new Path();
path.addRect(-100,-100,100,100, Path.Direction.CW);//添加一个矩形
path.addOval(-200,-200,200,200, Path.Direction.CW);//添加一个椭圆
canvas.drawPath(path, mPaint);
PathMeasure pathMeasure = new PathMeasure(path, false);
Log.e("TAG", "onDraw:forceClosed=false "+ pathMeasure.getLength());
//跳转到下一条曲线
pathMeasure.nextContour();
Log.e("TAG", "onDraw:forceClosed=false "+ pathMeasure.getLength());
mPath.reset();
mPath.addCircle(0,0,200, Path.Direction.CW);
canvas.drawPath(mPath, mPaint);
可以看到日志,第二条日志显示了圆的长度
E/TAG: currContour: 800.0
E/TAG: nextContour: 1256.1292
getPosTan
/**
* @param distance 距离Path起点的长度,取值范围是0-Path的长度之间
* @param pos 当前点在画布上的位置,pos[0]:x坐标 pos[1]:y坐标
* @param tan 当前点在曲线上的方向,可以获取到切换与X轴的夹角,tan[0]:cos tan[1]:sin
**/
public boolean getPosTan(float distance, float pos[], float tan[])
通过这个方法之后,可以计算出当前点和切线的X轴的角度
Path.atan2(tan[1],tan[0]) * 180.0 / Math.PI;
通过这个方法,可以实时画出一个绕着圆环,角度实时变化的箭头、小车等
贴出核心代码
PathMeasure pathMeasure = new PathMeasure(mPath, false);
pathMeasure.getPosTan(pathMeasure.getLength() * mFloat,pos,tan);
//计算出当前的切线与x轴夹角的度数
double degrees = Math.atan2(tan[1], tan[0]) * 180.0 / Math.PI;
mMatrix.reset();
//进行角度旋转
mMatrix.postRotate((float) degrees, mBitmap.getWidth() / 2, mBitmap.getHeight() / 2);
//将图片的绘制点中心与当前点重合
mMatrix.postTranslate(pos[0] - mBitmap.getWidth() / 2, pos[1]-mBitmap.getHeight() / 2);
canvas.drawBitmap(mBitmap,mMatrix, mPaint);
invalidate();
getMatrix
通过PathMeasure.getMatrix(),我们也可以获取到pos和tan的信息。
/**
* @param distance 距离Path起点的长度,取值范围是0-Path的长度之间
* @param matrix 会将信息存放在这个matrix对象中
* @param flags 存放信息的类型 POSITION_MATRIX_FLAG:位置信息(即pos),TANGENT_MATRIX_FLAG:当前点在曲线上的方向(即tan)
**/
public boolean getMatrix(float distance, Matrix matrix, int flags)
核心代码
PathMeasure pathMeasure = new PathMeasure(mPath, false);
//将pos信息和tan信息保存在mMatrix中
pathMeasure.getMatrix(pathMeasure.getLength() * mFloat, mMatrix, PathMeasure.POSITION_MATRIX_FLAG | PathMeasure.TANGENT_MATRIX_FLAG);
//将图片的旋转坐标调整到图片中心位置
mMatrix.preTranslate(-mBitmap.getWidth() / 2, -mBitmap.getHeight() / 2);
canvas.drawBitmap(mBitmap,mMatrix, mPaint);
invalidate();