前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Android UI】贝塞尔曲线 ⑥ ( 贝塞尔曲线递归算法原理 | 贝塞尔曲线递归算法实现 )

【Android UI】贝塞尔曲线 ⑥ ( 贝塞尔曲线递归算法原理 | 贝塞尔曲线递归算法实现 )

作者头像
韩曙亮
发布2023-03-30 16:10:44
1.2K0
发布2023-03-30 16:10:44
举报
文章被收录于专栏:韩曙亮的移动开发专栏

文章目录

贝塞尔曲线参考 : https://github.com/venshine/BezierMaker

一、贝塞尔曲线递归算法


一阶贝塞尔曲线 ( 起止点 +

0

个控制点 =

2

个点 ) 是一条直线 , 贝塞尔曲线上的点就是直线上的点 ;

二阶贝塞尔曲线 ( 起止点 +

1

个控制点 =

3

个点 ) 由

2

条 一阶贝塞尔曲线 确定 ,

三阶贝塞尔曲线 ( 起止点 +

2

个控制点 =

4

个点 ) 由

2

条 二阶贝塞尔曲线 确定 ,

四阶贝塞尔曲线 ( 起止点 +

3

个控制点 =

5

个点 ) 由

2

条 三阶贝塞尔曲线 确定 ,

\vdots
n

阶贝塞尔曲线 ( 起止点 +

n-1

个控制点 =

n + 1

个点 ) 由

2

n-1

阶贝塞尔曲线 确定 ;

贝塞尔曲线递推公式如下 :

P_i^k = \begin{cases} P_i , k = 0\\ (1-t)P_i^{k-1} + tP_{i + 1}^{k-1} , k = 1,2,\cdots,n ; i = 0,1,\cdots,n-k \end{cases}

上述公式中

k + 1

是贝塞尔曲线的阶数 ,

i

表示顶点序号 ;

根据上述 贝塞尔曲线递推公式 , 可以得到一个递归算法 , 算法核心公式如下 :

p(i, j) = (1-u) \times p (i - 1, j) + u \times p (i - 1 , j - 1)

上述递推公式中 ,

i

表示贝塞尔曲线的阶数 ,

j

表示贝塞尔曲线中的点个数 ( 包含起止点 + 控制点 ) ,

u

表示比例取值范围

0

~

1

;

递归算法的递归终点是取到第

0

阶 ;

二、贝塞尔曲线递归算法实现


递归算法中最终的一阶贝塞尔曲线上的点计算公式如下 :

p(i, j) = (1-u) \times p (i - 1, j) + u \times p (i - 1 , j - 1)

根据上述计算公式 , 得到如下代码 :

代码语言:javascript
复制
(1 - u) * mControlPoints.get(j).x + u * mControlPoints.get(j + 1).x

完整的贝塞尔曲线上的点坐标算法如下 :

  • BezierX 方法用于计算 贝塞尔曲线上的 X 轴坐标点 ;
  • BezierY 方法用于计算 贝塞尔曲线上的 Y 轴坐标点 ;
代码语言:javascript
复制
    // 贝塞尔曲线控制点集合
    private ArrayList<PointF> mControlPoints = new ArrayList<>();

    /**
     * 贝塞尔曲线递归算法, 本方法计算 X 轴坐标值
     * @param i 贝塞尔曲线阶数
     * @param j 贝塞尔曲线控制点
     * @param u 比例 / 时间 , 取值范围 0.0 ~ 1.0
     * @return
     */
    private float BezierX(int i, int j, float u) {
        if (i == 1) {
            // 递归退出条件 : 贝塞尔曲线阶数 降为一阶
            // 一阶贝塞尔曲线点坐标 计算如下 :
            return (1 - u) * mControlPoints.get(j).x + u * mControlPoints.get(j + 1).x;
        }
        return (1 - u) * BezierX(i - 1, j, u) + u * BezierX(i - 1, j + 1, u);
    }

    /**
     * 贝塞尔曲线递归算法, 本方法计算 Y 轴坐标值
     * @param i 贝塞尔曲线阶数
     * @param j 贝塞尔曲线控制点
     * @param u 比例 / 时间 , 取值范围 0.0 ~ 1.0
     * @return
     */
    private float BezierY(int i, int j, float u) {
        if (i == 1) {
            // 递归退出条件 : 贝塞尔曲线阶数 降为一阶
            return (1 - u) * mControlPoints.get(j).y + u * mControlPoints.get(j + 1).y;
        }
        return (1 - u) * BezierY(i - 1, j, u) + u * BezierY(i - 1, j + 1, u);
    }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-08-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 一、贝塞尔曲线递归算法
  • 二、贝塞尔曲线递归算法实现
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档