您当前的位置: 首页 >  ui

命运之手

暂无认证

  • 3浏览

    0关注

    747博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

【高级UI】【018】代码模拟贝塞尔曲线形成过程

命运之手 发布时间:2021-11-11 10:05:05 ,浏览量:3

前言

前面我们讲解过贝塞尔曲线的原理和公式

这篇博客,我们通过代码来实现任意阶的贝塞尔曲线,并通过动画演示其形成过程

能把这份代码完成吃透,说明对贝塞尔曲线已经完全了解了

效果图

在这里插入图片描述

核心代码


	package com.android.architecture;
	
	import android.content.Context;
	import android.graphics.Canvas;
	import android.graphics.Color;
	import android.graphics.Paint;
	import android.graphics.Path;
	import android.graphics.PointF;
	import android.util.AttributeSet;
	import android.view.MotionEvent;
	import android.view.View;
	
	import java.util.ArrayList;
	import java.util.List;
	import java.util.Random;
	
	//一个演示N阶贝塞尔曲线形成过程的控件
	@SuppressWarnings("all")
	public class BezierDemoView extends View {
	
	    //贝塞尔曲线取样数
	    final int BEZIER_SAMPLE_COUNT = 1000;
	
	    //控制点半径
	    final int CONTROL_POINT_RADIUS = 6;
	
	    //所有线条的宽度
	    final int CONTROL_LINE_WIDTH = 6;
	
	    //贝塞尔曲线最大最小阶数
	    final int MIN_LEVEL = 1;
	    final int MAX_LEVEL = 7;
	
	    //切线颜色,七阶曲线共有六条切线,六种颜色
	    final String[] TANGENT_LINE_COLORS = {"#7FFF00", "#7A67EE", "#EE82EE", "#FFD700", "#1C86EE", "#8B8B00"};
	
	    //贝塞尔曲线路径
	    Path bezierPath = new Path();
	    PointF bezierPoint;
	    List bezierPoints;
	
	    //贝塞尔曲线阶数
	    int bezierLevel = 4;
	
	    //贝塞尔曲线移动速率,每帧跳过几个点
	    int bezierMoveRate = 5;
	    //当前帧贝塞尔曲线上点的Index
	    int bezierPointIndex = 0;
	
	    //控制点
	    List controlPoints;
	
	    //每阶切线的所有切线点
	    //贝塞尔曲线的取点过程,就是一个位置比率变化和切线逐级降阶的过程
	    //这个不懂的,可以先去网上补充下这方面的基础
	    List roundTanPoints;
	
	    //所有帧的切线点
	    //上面的点是单帧的,这个是全部数据
	    List frameTanPoints;
	
	    //画布大小
	    int w = 0;
	    int h = 0;
	
	    //控制线画笔
	    Paint controlLinePaint;
	    //控制点画笔
	    Paint controlPointPaint;
	    //控制点名称画笔
	    Paint controlTextPaint;
	    //切线画笔
	    Paint tangentLinePaint;
	    //贝塞尔曲线画笔
	    Paint bezierPaint;
	    //当前贝塞尔点画笔
	    Paint currentPointPaint;
	
	    //状态锁,防止数据未准备完毕就开始绘制
	    final Object readyLock = new Object();
	
	    //动画暂停中
	    boolean isAnimationPaused = false;
	
	    //循环显示
	    boolean loop = false;
	
	    public BezierDemoView(Context context) {
	        this(context, null);
	    }
	
	    public BezierDemoView(Context context, AttributeSet attributeSet) {
	        super(context, attributeSet);
	        init();
	    }
	
	    protected void init() {
	
	        //控制线画笔
	        controlLinePaint = new Paint();
	        controlLinePaint.setAntiAlias(true);
	        controlLinePaint.setColor(Color.LTGRAY);
	        controlLinePaint.setStrokeWidth(CONTROL_LINE_WIDTH);
	        controlLinePaint.setStyle(Paint.Style.FILL);
	        controlLinePaint.setStrokeCap(Paint.Cap.ROUND);
	
	        //控制点画笔
	        controlPointPaint = new Paint();
	        controlPointPaint.setAntiAlias(true);
	        controlPointPaint.setColor(Color.BLACK);
	        controlPointPaint.setStyle(Paint.Style.STROKE);
	
	        //控制点名称画笔
	        controlTextPaint = new Paint();
	        controlTextPaint.setAntiAlias(true);
	        controlTextPaint.setColor(Color.BLACK);
	        controlTextPaint.setTextSize(40);
	
	        //切线画笔
	        tangentLinePaint = new Paint();
	        tangentLinePaint.setAntiAlias(true);
	        tangentLinePaint.setColor(Color.parseColor(TANGENT_LINE_COLORS[0]));
	        tangentLinePaint.setStrokeWidth(CONTROL_LINE_WIDTH);
	        tangentLinePaint.setStyle(Paint.Style.FILL);
	
	        //贝塞尔曲线画笔
	        bezierPaint = new Paint();
	        bezierPaint.setAntiAlias(true);
	        bezierPaint.setColor(Color.RED);
	        bezierPaint.setStrokeWidth(CONTROL_LINE_WIDTH);
	        bezierPaint.setStyle(Paint.Style.STROKE);
	
	        //当前贝塞尔点画笔
	        currentPointPaint = new Paint();
	        currentPointPaint.setAntiAlias(true);
	        currentPointPaint.setColor(Color.RED);
	        currentPointPaint.setStyle(Paint.Style.FILL);
	    }
	
	    @Override
	    protected void onDraw(Canvas canvas) {
	
	        synchronized (readyLock) {
	
	            //没有数据,返回
	            if (bezierPoints == null) {
	                postInvalidateDelayed(20);
	                return;
	            }
	
	            //首帧将Path移动到起点
	            if (bezierPath.isEmpty()) {
	                PointF startPoint = bezierPoints.get(0);
	                bezierPath.moveTo(startPoint.x, startPoint.y);
	            }
	
	            //画控制点之间的连线
	            for (int i = 0; i  0)
	                    canvas.drawLine(controlPoints.get(i - 1).x, controlPoints.get(i - 1).y, p.x, p.y, controlLinePaint);
	            }
	
	            //画控制点
	            for (int i = 0; i             
关注
打赏
1654938663
查看更多评论
0.0417s