Path,PathMeasure与贝塞尔曲线

Path

常用方法

        moveTo():设置下一次path的起点。

        lineTo():通过直线连接上个点与参数指定点。没有上一个点的话,上一个点就是(0,0)。

        setLastPoint():重置当前path中的上一个点。

        set():将当前path重置为参数path。

        offset():对当前的path进行平移。Path类型参数是有来存储平移后的path的,如果没有就直接操作修改当前的Path。

        arcTo():指定一个弧形做为path中的一部分。boolean型变量,如果为false则弧线的起点通过直接连接到path的上一个点,如果为true,则不连接到path的上一个点。但弧线的终点始终连接到path的下一个点。如下:


        addArc():将一个弧形添加到path中,并且后继的lineTo()等操作都只与弧形的起始点相连,并不与path的moveTo()指定的点相关,相当于新建了一个path,后继的所有操作都在该path中进行。

        它与arcTo()的区别在于,arcTo()是原path中的一部分,弧形的起始点也是path中的两个点,而addArc()却是新建了一个path,后继的所有操作只是修改该path而对原path这无影响。

        setFillType():设置path填充模式。填充时需要先判断要填充的点是否在path内。判断方法有两种:奇偶规则与非零环绕数规则(链接),两个规则得到的结果并不是完全一样。WINDING:以非零环绕数规则进行填充。EVEN_ODD:以奇偶规则进行填充。INVERSE_***:与***规则相反,***规则判断在内,则INVERSE_***判断在外。

        rLineTo():新点相对于path的最后一个点的坐标,而lineTo()指定的是新点相对于原点的坐标。其余几个以r开头的方法都类似。

        quadTo()与cubicTo():前者绘制二阶贝塞尔曲线,后才是三阶的贝塞尔曲线。系统中只提供到了三阶贝塞尔曲线(ps中钢笔工具也类似),因为复杂的图形可以拆分成多个三阶曲线进行拼合即可。

       op():有一个Path对象时,本path为path1,参数path为path2,使用执行Op参数指定的交,并或差集,并将结果赋值给本path对象。有两个path对象时,第一个为path1,第二个为path2,并将结果赋值给本path对象。

       reset():清除Path中的直接、曲线等数据,但保留Path的FillType。类似于创建一个新的path,并且将该对象的filltype设置为旧path的filltype。

       rewind():清除Path中存储的直线、曲线等。但是会保留内部的数据结构以便快速复用——当每一次path都含有相同数目的点时,rewind()可以显著地提升性能。参考

Path.Op

        类似于Region.Op。

        DIFFERENCE:从path1中减去path2。

        INTERSECT:取两者的交集。

        UNION:取两者并集。

        XOR:两者并集并减去两者交集。

        REVERSE_DIFFERENCE:与DIFFERENCE相反,从path2减去path1。

贝塞尔曲线

       动态图

        ps中的钢笔工具就是利用贝塞尔曲线完成的,而且复杂的图形也是通过多个三阶贝塞尔曲线连接形成的。如下图,是用ps中钢笔工具填充的蓝色部分,蓝色部分的曲线是由两个三阶贝塞尔曲线连接的。


示例

        canvas.drawColor(Color.GRAY);
        path.reset();
        path.moveTo(0, getHeight() / 2);
        path.cubicTo(getWidth() / 3, getHeight() / 2 + 200 - 400 * factor, getWidth() * 2 / 3, getHeight() / 2 - 200 + factor * 400, getWidth(), getHeight() / 2);
        path.lineTo(getWidth(), getHeight());
        path.lineTo(0, getHeight());
        path.close();
        canvas.drawPath(path, paint);
        不断改变factor的值,就不断修改控制点的值,会造成整个图片区域不断变动,成为一种动态效果。

PathMeasure

        用于测量Path。Path与PathMeasure关联后,并不会影响原来的path,而且原来的path修改后必须通过setPath()方法与PathMeasure()进行再次关联。

        PathMeasure(),PathMeasure(Path,boolean forceClosed):构造函数。传入的path是要被测量的,forceClosed表示是否强制close该path。Path与PathMeasure()关联之后,无论boolean型的变量为true还是false,都不会影响之前的path。forceClosed为true时,会强制闭合path,因此得到的path长度可能比path原本的长度要长——因为连接了path的起始点。

        setPath():将path与PathMeasure进行关联,参数与构造方法中的含义一样。

        isClosed():是否关闭。如果构造函数中的forceClosed为true,则该广场的返回值一定为true。为false的话,就要看原来的path是否闭合了。

        getLength():返回path的长度。如果返回0,则代表着当前的measure没有关联path对象。

        getSegment():截取path中的一部分。前两个参数表示截取的部分的起点距离path起点的距离,终点距离path起点的距离。截取的部分将会添加到的第三个参数dst中。第四个参数为true的话,则截取的path保持原样;为false的话,则截取的片段的起点被移动到dst的最后一个点上,以保证dst的连续性。

        nextContour():跳转下一个曲线或直线上。一个path可以由多条直线或曲线构成,而上面的方法都只是在第一条线段上运行,如果想测量别的线段就需要使用nextContour()跳转到下一个线段了。

        getPosTan(distance,pos,tan):获取与path起始相隔distance距离的点的坐标以及该点处切线的正切值——其值为tan[1]/tan[0]。坐标值会存储在pos中,而该位置处的正切值会存储在tan中。

        getMatrix():其作用于getPosTan()一样,只不过将pos与tan的值封装到了matrix中,省却了拿到pos与tan值后进行旋转与位移的操作。

示例

        用path勾勒出一个具体的形状,并使用PathMeasure#getSegment()截取这个path的一部分,然后动态修改截取的长度。并将截取的部分绘制到canvas上,就达到了动态生成的效果。

protected void onDraw(Canvas canvas) {
        canvas.drawColor(Color.GRAY);
        canvas.translate(getWidth() / 2, getHeight() / 2);
        if (path == null) {
            path = new Path();
            path.moveTo(-130 + 50 * (float) Math.sin(Math.PI / 4), -130 + 50 * (float) Math.sin(Math.PI / 4));
            path.addArc(new RectF(-180, -180, -80, -80), 45, 359.9f);
            path.lineTo(-50, -50);
            measure.setPath(path, false);
            length = measure.getLength();
            measure.nextContour();
            length += measure.getLength();
            measure.setPath(path, false);
            p = new Path();
        }
        p.reset();
        measure.getSegment(0, length * (1 - factor), p, true);
        canvas.drawPath(p, paint);
    }
        不断修改factor的值,则可以达到动态显示动画。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值