Android PathMeasure

本文介绍了Android中的PathMeasure类,用于测量Path的长度、坐标和正切值。通过示例展示了如何使用PathMeasure获取Path的某段长度以及在不同startWithMoveTo参数下对结果的影响。同时,讲解了getPosTan()方法的应用,用于实现纸飞机的平移和旋转动画,通过实时测量路径长度更新飞机的位置和角度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PathMeasure 是针对Path的测量类,它可以测量Path的长度、某点的坐标、正切值等。api中提供了两个构造方法,这里我们来看带参数的构造方法

    public PathMeasure(Path path, boolean forceClosed) {
        // The native implementation does not copy the path, prevent it from being GC'd
        mPath = path;
        native_instance = native_create(path != null ? path.readOnlyNI() : 0,
                                        forceClosed);
    }

path表示需要进行测量的对象,forceClosed表示在测量过程中,是否路径考虑闭合的状况,传递true值表示不论是否调用path.close()方法,都认为是闭合状态。

    public float getLength() {
        return native_getLength(native_instance);
    }

表示获取当前path的长度。

 public boolean getSegment(float startD, float stopD, Path dst, boolean startWithMoveTo) {
        float length = getLength();
        if (startD < 0) {
            startD = 0;
        }
        if (stopD > length) {
            stopD = length;
        }
        if (startD >= stopD) {
            return false;
        }

        return native_getSegment(native_instance, startD, stopD, dst.mutateNI(), startWithMoveTo);
    }

表示获取path中的某一段长度,startD表示起始值,stopD表示测量终点值,dst为测量后的path对象,startWithMoveTo表示是否移动至path起点并连线,看一下示例
在这里插入图片描述
红色区域是绘制了两个边长为200的矩形,我们分别对两个红色矩形测量200至600范围的path,上方的红色矩形在测量中startWithMoveTo参数传递了true,下方的则传递了false,可以很明显的观察到传递false时,将path范围为200的点与我们的画布起始点进行了连线,为true时则不会。

public boolean nextContour() {
        return native_nextContour(native_instance);
    }

如果path为多条互不连接的曲线构成,那么在测量过程中,如果想要测量下一个path的相关数据,调用该方法,则会顺沿到下一个path。

    public boolean getPosTan(float distance, float pos[], float tan[]) {
        if (pos != null && pos.length < 2 ||
            tan != null && tan.length < 2) {
            throw new ArrayIndexOutOfBoundsException();
        }
        return native_getPosTan(native_instance, distance, pos, tan);
    }

测量距离path起始点的长度distance,pos、tan都是长度为2的数组,pos[0]表示x坐标,pos[1]表示y坐标,tan[0]是邻边边长,tan[1]是对边边长,通过Math.atan2(tan[1], tan[0])*180.0/Math.PI 可以得到正切角的弧度值。

下面我们做一个简单的示例,效果图如下:
在这里插入图片描述
重点在于getPosTan()方法的使用,该效果实际是对纸飞机进行平移和旋转操作,在对圆path的测量过程中,获取每一个路径的坐标以及正切值,坐标就是飞机的平移坐标,而正切值转换为角度值,就是飞机的旋转角度,主要实现onDraw()方法:

 @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.drawLine(0, getHeight() / 2, getWidth(), getHeight() / 2, linePaint);
        canvas.drawLine(getWidth() / 2, 0, getWidth() / 2, getHeight(), linePaint);
        canvas.translate(getWidth() / 2, getHeight() / 2);

        path.reset();
        path.addCircle(0, 0, 200, Path.Direction.CW);
        canvas.drawPath(path, paint);

        PathMeasure measure = new PathMeasure();

        measure.setPath(path, false);

        speed += 0.004;
        if (speed > 1) {
            speed = 0;
        }
        //这里对圆path进行测量
        measure.getPosTan(measure.getLength() * speed, pos, tan);
        //计算当前角度
        double degree = Math.atan2(tan[1], tan[0]) * 180.0 / Math.PI;

        matrix.reset();
        //旋转飞机
        matrix.postRotate((float) degree,bitmap.getWidth()/2,bitmap.getHeight()/2);
        //平移飞机
        matrix.postTranslate(pos[0]-bitmap.getWidth()/2,pos[1]-bitmap.getHeight()/2);
        canvas.drawBitmap(bitmap,matrix,paint);

        invalidate();
    }

这里我们通过speed对象来实时测量measure.getLength() * speed这一段路径值,并实时计算相应的坐标及角度,不断的对纸飞机进行旋转和平移操作即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值