写点什么

自定义 View:使用二阶贝塞尔曲线绘制正弦函数

作者:Changing Lin
  • 2021 年 12 月 03 日
  • 本文字数:1263 字

    阅读完需:约 4 分钟

1.知识点

  • 贝塞尔曲线(Bézier curve):又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线。

  • 二阶贝塞尔曲线:B(t)=(1-t)²P0+2t(1-t)P1+t²P2,t∈[0,1]

  • 想绘制一个侧边栏的右滑的返回控件,类似与 东方航空的 APP 上的页面返回图标。因此,想到了正弦函数,考虑到计算机系统,使用贝塞尔曲线绘制,


2.原理

  • 系统 API

/* Add a quadratic bezier from the last point, approaching control point (x1,y1), and ending at (x2,y2). If no moveTo() call has been made for this contour, the first point is automatically set to (0,0).Params: 起始点默认从 (0,0)开始,也可通过moveTo移动到指定起始点。x1 – The x-coordinate of the control point on a quadratic curve 二阶曲线的控制点y1 – The y-coordinate of the control point on a quadratic curve 二阶曲线的控制点x2 – The x-coordinate of the end point on a quadratic curve 结束点y2 – The y-coordinate of the end point on a quadratic curve 结束点*/public void quadTo(float x1, float y1, float x2, float y2)
复制代码
  • 正弦函数的数学模型

如上图所示,只需要计算出 P0,P1,P2,P3,P4 点,通过 2 个贝塞尔曲线即可绘制出一个正弦函数。正弦函数具有幅值和周期两个属性组成,因此,可以再代码中定义

private static final int SIN_HEIGHT = (int) Util.dp2px(100); // 正弦函数幅值private static final int SIN_PERIOD = (int) Util.dp2px(100); // 正弦函数周期
复制代码

3.源码

		private static final int SIN_HEIGHT = (int) Util.dp2px(100);    private static final int SIN_PERIOD = (int) Util.dp2px(100);    		private void setPathData() {        //  1、复位    清空一次路径        path.reset();				int linePos = getHeight()/2; // 正弦函数在Y轴上的位置        for (int i = 0; i < getWidth()/SIN_PERIOD; i++) {            int x0 = i*SIN_PERIOD; // 计算 P0 点坐标            int y0 = linePos;            int x1 = SIN_PERIOD/4 + x0; // 计算 P1 点坐标            int y1 = y0+SIN_HEIGHT/2;            int x2 = x0 + SIN_PERIOD/2; // 计算 P2 点坐标            int y2 = linePos;            int x3 = SIN_PERIOD*3/4+x0; // 计算 P3 点坐标            int y3 = linePos-SIN_HEIGHT/2;            int x4 = x0+SIN_PERIOD; // 计算 P4 点坐标            int y4 = linePos;            path.moveTo(x0, y0);            path.quadTo(x1, y1, x2, y2); // 绘制贝塞尔曲线,需要注意的是,起始点为(x0,y0),控制点(x1,y1),结束点(x2,y2)            path.quadTo(x3, y3, x4, y4); // 第二个贝塞尔曲线是在上一个的结束点开始的,此时,起始点(x2,y2),控制点(x3,y3),结束点(x4,y4)        }
// path.close(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); setPathData(); canvas.drawPath(path, paint2); }
复制代码
  • 实际效果:


发布于: 1 小时前阅读数: 5
用户头像

Changing Lin

关注

获得机遇的手段远超于固有常规之上~ 2020.04.29 加入

我能做的,就是调整好自己的精神状态,以最佳的面貌去面对那些未曾经历过得事情,对生活充满热情和希望。

评论

发布
暂无评论
自定义View:使用二阶贝塞尔曲线绘制正弦函数