android高级UI

1.2.6基于PathMeasure分析Path测量问题

2019-06-21  本文已影响7人  saygoodbye_e92e

1.概念:

   pathMeasure: 路径测量,一个用来测量path的工具类

2.常用api:

   常用api如path长度的测量,path的跳转,path片段的获取等

 (1)void setPath(Path path,boolean forceClosed);关联一个Path

绘制横竖两条线,然后将画布的中心坐标平移到这个两条线的交点,也就是这个交点,就是画布的(0,0)点。

显示效果如下:

A.当setPath中的第二个参数forceClosed=true时候

显示结果:

打印结果:

显示结果为路径闭合的周长

B.当setPath中的第二个参数forceClosed=false时候

我们讲上面的setPath中的第二个参数设置为false,ui显示效果如上

打印结果:

显示结果为路径未闭合的周长

注意:

  //如果Path进行了调整,需要重新调用setPath方法进行关联

     path.lineTo(200, -200);     

     Log.e("TAG", "onDraw:PathMeasure(path, false) "+ pathMeasure1.getLength())

     pathMeasure1.setPath(path, false);

     Log.e("TAG", "onDraw:PathMeasure(path, false) "+ pathMeasure1.getLength());

 `(2)boolean isClosed();是否闭合

(3)float getLength();//获取Path的长度

(4)boolean nextContour();跳转到下一个轮廓

源码

依次给Path添加一个矩形和一个椭圆(图上实际是一个圆形)

手机ui效果

打印参数结果如下:

打印结果

结果分析:

1.第一打印的是矩形的周长,第二次打印的是圆的周长(2*pi*r)

 2.为啥不调用nextContour()只是打印出了第一个数据(矩形的数据)? 

 答:打印的顺序和path的添加顺序有关,先添加矩形,所以就会打印矩形的周长。

(5)boolean getSegment(float startD,float stopD,Path dst,boolean startWithMoveTo);截取Path的片段

参数值:

startD :表示开始截取位置距离path起点的长度,取值范围(0,,getLength)

 stopD:表示结束截取位置的距离path起点的长度,取值范围(0..getLength)

startWithMoveTo:表示起始点是否使用MoveTo进行移动,用于保证截取的path的第一个点位置不变

返回值:

true:截取成功,false截取失败,会将结果存放在dst中

测试使用如下:

path添加一个矩形,然后从从距离path起点为200的地方开始截取,应为矩形为顺时针绘制的,所以顺着这个方向,截取长度1000.显示的效果如上图

补充:如果将getSegment的最后一个参数设置为false,显示效果如下:

补充:

1.这里主要是startWithMoveTo的取值,

true 表示保证截取出来的path片段保持原状

 false 会将截取出来的path片段的起点移动到dst的最后一个点以保证dst的连续性,主要就是少了一步moveTo的步骤{核心原理}

2.当startWithMoveTo为false时,起始点是dst的最后一个点,getSegment会根据startD的值去判断dst与path的连接点,也就是超过startD的第一个点(这里的点指的是lineTo的点或者Rect的顶点等),然后截取到stopD。

(6)boolean getPosTan(float distance,float[]pos,float[] tan);获取指定长度位置的坐标以及该点的切线值

参数:distance:表示距离path起点的长度。取值范围:0到Path长度之间

pos:长度为2的float数组,里面存放的是当前点在画布上的位置,分别表示x坐标和y坐标

tan:长度为2的float数组,表示的是当前点在曲线上的方向,通过它能够获取到切线方向与X轴的一个夹角

返回值:

true返回成功。

false返回失败。

测试使用:

手机显示ui

distance=0.即距离path起点我位置为0 也就是左边为(200,0)的位置

打印结果如下:

结果分析:1.有上面可以知道pos[0]表示当前点在画布的x坐标,pos[1]表示当前点在画布的y坐标

2.tan表示的是当前点在曲线上的方向,需要找到当前点的切线,tan[0]表示切线与x轴的夹角在单位圆中邻边的长度,

tan[1]表示的切线与x轴的夹角在单位圆中对边的长度

发现切线与x轴夹角为90度,接下来我们需要知道,这个夹角在单位圆中的他的邻边和对边是多少。我们看下图:

如上图,我们发现交为30的邻边为OA,对边长为AB.

当角度为90度的时候,邻边长变为了0,而对边长变成了1

那么也就应证了我们 的打印的结果 。

扩展:

如果我们想获取path中其他位置的tan结果,我们以位置为getLength*7/8点为例演示如下:

找到当前位置的切线

发现与X轴的夹角为45度。我们看上面的单位圆。45度对应的邻边为根号2/2, 对边也是根号2/2,

查看打印结果如下:

我们可以基于这个知识点来实现一个小案例:

效果是箭头不停的在圆环上转。

源码链接:githhub

(7)boolean getMatrix(float distance,Matrix matrix,int flags);获取指定长度位置的矩阵

参数:

distance:距离path起点的长度,范围是0到getLength(path的长度)之间

matrix:将信息存放在Matrix中

flags:指定存放信息的类型

值有两个:

(1)POSITION_MATRIX_FLAG:表示的是位置信息

 (2) TANGENT_MATRIX_FLAG:表示当前点在曲线上的方向

返回值:

true:返回成功

false:返回失败

使用案例在上面github源码,再次就不在赘述了。

疑问:

1. Matrix中preTranslate和posTranslate的区别

 2.Matrix中postRotate的用法

上一篇 下一篇

猜你喜欢

热点阅读