SeniorUI1004_小船破浪效果

SeniorUI_目录
SeniorUI1001_PathMeasure语法

一、Rendering

在这里插入图片描述

二、Principe

  • Path利用贝塞尔曲线画波浪
  • Animation实现动画间隔值
  • PathMeasure利用Animation的值获取对应位置坐标斜率信息
  • 利用获取的信息绘制图片

三、Core Code

public class WaveView extends View {

    private static final int INT_WAVE_LENGTH = 1000;
    private static final String TAG = "WaveView";

    private Path mPath;
    private Paint mPaint;

    private int mDeltaX;
    private Bitmap mBitMap;
    private PathMeasure mPathMeasure;
    private float[] pos;
    private float[] tan;
    private Matrix mMatrix;
    private float faction;

    public WaveView(Context context) {
        super(context);
        init();
        
    }

    private void init() {
        mPaint = new Paint();
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);

        mPath = new Path();
        pos = new float[2];
        tan = new float[2];
        mMatrix = new Matrix();

        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize =  2;
        mBitMap = BitmapFactory.decodeResource(getResources(), R.drawable.timg,options);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPath.reset();
        int orginY = 800;
        int halfWaveLength = INT_WAVE_LENGTH / 2;
        mPath.moveTo(-INT_WAVE_LENGTH + mDeltaX, orginY);
        for(int i = -INT_WAVE_LENGTH ; i < getWidth() + INT_WAVE_LENGTH;
            i += INT_WAVE_LENGTH){
            mPath.rQuadTo(halfWaveLength/2,60,halfWaveLength,0);
            mPath.rQuadTo(halfWaveLength/2,-60,halfWaveLength,0);
        }
        mPath.lineTo(getWidth(),getHeight());
        mPath.lineTo(0,getHeight());
        mPath.close();



        canvas.drawPath(mPath,mPaint);

        mPathMeasure = new PathMeasure(mPath,false);
        float length = mPathMeasure.getLength();
        mMatrix.reset();
        boolean posTan = mPathMeasure.getPosTan(length*faction,pos,tan);
        Log.d(TAG,"pos[0] = " + pos[0] + "pos[1] = " +pos[1]);
        Log.d(TAG,"tan[0] = " + tan[0] + "tan[1] = " +tan[1]);
        if(posTan){
            // 方案一 :自己计算
            // 将tan值通过反正切函数得到对应的弧度,在转化成对应的角度度数
            /*float degrees = (float) (Math.atan2(tan[1],tan[0])*180f / Math.PI);
            mMatrix.postRotate(degrees, mBitMap.getWidth()/2, mBitMap.getHeight() / 2);
            mMatrix.postTranslate(pos[0]- mBitMap.getWidth() / 2,pos[1] - mBitMap.getHeight());
            canvas.drawBitmap(mBitMap,mMatrix,mPaint);*/

            // 方案一 :直接使用API
            mPathMeasure.getMatrix(length*faction, mMatrix, PathMeasure.TANGENT_MATRIX_FLAG | PathMeasure.POSITION_MATRIX_FLAG);
            mMatrix.preTranslate(- mBitMap.getWidth() / 2, - mBitMap.getHeight());
            canvas.drawBitmap(mBitMap,mMatrix,mPaint);
        }

        //

    }

    public void startAnimation(){
        /*ValueAnimator animator = ValueAnimator.ofInt(0,INT_WAVE_LENGTH);
        animator.setDuration(1000);
        animator.setInterpolator(new LinearInterpolator());
        animator.setRepeatCount(ValueAnimator.INFINITE);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mDeltaX = (int) animation.getAnimatedValue();
                postInvalidate();
            }
        });
        animator.start();*/

        ValueAnimator animator = ValueAnimator.ofFloat(0,1);
        animator.setDuration(25000);
        animator.setInterpolator(new LinearInterpolator());
        animator.setRepeatCount(ValueAnimator.INFINITE);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                faction  = (float) animation.getAnimatedValue();
                postInvalidate();
            }
        });
        animator.start();
    }

}

四、Demo

WaveViewActivity

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很抱歉,我是一个语言模型,无法访问互联网或文件系统,也无法提供文档或代码实现。但是,我可以为您提供一些关于使用Matlab实现小船过河问题的指导。 首先,您需要定义一个状态向量,其中包括左岸和右岸的每个人和小船的位置。然后,您需要定义一个状态转移矩阵,该矩阵确定在当前状态下可以采取的所有行动以及采取每种行动后可能到达的下一个状态。最后,您需要编写一个函数来执行状态转移并在达到目标状态时停止。 以下是一个简单的示例代码,用于实现小船过河问题: ```matlab % 定义状态向量: [A B C D E], 其中 A-D 表示四个人的位置,E 表示小船的位置 start_state = [1 1 1 1 1]; % 初始状态 goal_state = [0 0 0 0 0]; % 目标状态 % 定义状态转移矩阵,每行表示一个状态转移 % 第一列表示船上的人,第二列表示要移动的方向,0 表示不动,-1 表示向左,1 表示向右 transition_matrix = [1 0; 2 0; 1 -1; 2 -1; 1 1; 2 1; 3 0; 4 0; 3 -1; 4 -1; 3 1; 4 1; 5 -1; 5 1]; % 定义状态转移函数 function [next_state, cost] = transition(current_state, transition_matrix, goal_state) % 计算可用的状态转移 valid_transitions = []; for i = 1:size(transition_matrix, 1) if current_state(5) == transition_matrix(i, 1) && ... % 船上有这个人 current_state(transition_matrix(i, 1)) == 1 && ... % 这个人在船上 current_state(5) + transition_matrix(i, 2) >= 0 && ... % 船不能越过边界 current_state(5) + transition_matrix(i, 2) <= 1 && ... current_state(transition_matrix(i, 1)) + transition_matrix(i, 2) >= 0 && ... % 人不能越过边界 current_state(transition_matrix(i, 1)) + transition_matrix(i, 2) <= 1 && ... current_state(5) + transition_matrix(i, 2) == 0 && ... % 船必须有人 sum(current_state(1:4) == 1) > 1 % 船上必须有两个或以上的人 valid_transitions = [valid_transitions; i]; end end % 随机选择一个合法的状态转移 if ~isempty(valid_transitions) transition_index = valid_transitions(randi(size(valid_transitions, 1))); next_state = current_state; next_state(transition_matrix(transition_index, 1)) = ... next_state(transition_matrix(transition_index, 1)) + transition_matrix(transition_index, 2); next_state(5) = next_state(5) + transition_matrix(transition_index, 2); cost = 1; else next_state = current_state; cost = inf; end % 判断是否达到目标状态 if isequal(next_state, goal_state) cost = 0; end end % 执行状态转移直到达到目标状态 current_state = start_state; total_cost = 0; while ~isequal(current_state, goal_state) [next_state, cost] = transition(current_state, transition_matrix, goal_state); current_state = next_state; total_cost = total_cost + cost; end % 输出结果 disp(['Total cost: ', num2str(total_cost)]); ``` 请注意,这只是一个基本实现,有许多方法可以进行改进,例如使用广度优先搜索或启发式搜索算法来优化搜索速度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值