Android PathMeasure 高级使用

本文介绍如何利用Android的PathMeasure类创建一个绕圆环移动的小车动画。通过getSegment和getPosTan方法获取Path上的点信息,结合Matrix进行旋转和位移操作,实现了小车沿圆形路径平滑移动的效果。
摘要由CSDN通过智能技术生成

PathMeasure 是用来测量 Path 的类,可以理解成对 Path 每一个点获取信息的类

常用方法

  • getSegment
    用于获取 Path 某一片段,获取成功后返回 true

    float startD 开始截取位置距离 Path 起点的长度(非负)
    float stopD 结束截取位置距离 Path 起点的长度
    Path dst 截取的 Path 将会添加到 dst 中
    boolean startWithMoveTo 保证截取到的 Path 片段不会发生形变
    
  • getPosTan
    用于获取某个点的角度

    float distance 距离 Path 起点的长度 取值范围 0 <= distance <= getLength
    float pos[] 该点的坐标值,pos[0] 为 x 坐标, pos[1] 为 y 坐标
    float tan[] 该点的正切值, tan[0] 对应角度的 sin 值,对应 x 坐标. tan[1] 对应角度的 cos 值,对应 Y 坐标
    

实例:绕圆环移动的小车

public class CarView extends View {

    private Bitmap carBitmap;
    
    private Path path;
    private PathMeasure pathMeasure;// 路径计算
    
    private float distanceRatio = 0;
    private Paint circlePaint; // 画圆圈的画笔
    private Paint carPaint; // 画小车的画笔
    
    private Matrix carMatrix; // 针对 car bitmap 图片操作矩阵
            
    public CarView(Context context) {
        super(context);
        init(context);
    }

    public CarView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public CarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
        carBitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.car);
        path = new Path();
        path.addCircle(0,0,200,Path.Direction.CW);
        pathMeasure = new PathMeasure(path,false);

        // 初始化 圆圈画笔
        circlePaint = new Paint();
        circlePaint.setStrokeWidth(5);
        circlePaint.setStyle(Paint.Style.STROKE);
        circlePaint.setAntiAlias(true);
        circlePaint.setColor(Color.BLACK);

        // 初始化小车画笔
        carPaint = new Paint();
        carPaint.setColor(Color.DKGRAY);
        carPaint.setStrokeWidth(2);
        carPaint.setStyle(Paint.Style.STROKE);

        carMatrix = new Matrix();
    }

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

        canvas.drawColor(Color.WHITE);

        int width = getWidth();
        int height = getHeight();

        // 移动 canvas 坐标到中心
        canvas.translate(width/2,height/2);
        carMatrix.reset();

        distanceRatio += 0.006f;
        if (distanceRatio>=1){
            distanceRatio = 0;
        }

        float pos[] = new float[2]; // 记录位置
        float tan[] = new float[2]; // 记录切点值 xy

        float distance = pathMeasure.getLength() * distanceRatio;
        pathMeasure.getPosTan(distance,pos,tan);

        // tan[0] 代表 cos, tan[1] 代表 sin
        // 计算小车旋转的角度
        float degress = (float) Math.atan2(tan[1],tan[0]*180/Math.PI);
        // 设置旋转角度
        carMatrix.postRotate(degress,carBitmap.getWidth()/2,carBitmap.getHeight()/2);

        // 设置小车的中心点
        carMatrix.postTranslate(pos[0] - carBitmap.getWidth()/2,pos[1]-carBitmap.getHeight()/2);

        // 绘制圆圈
        canvas.drawPath(path,circlePaint);
        // 绘制小车
        canvas.drawBitmap(carBitmap,carMatrix,carPaint);

        invalidate();
    }
}

请添加图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值