文章目录

  • 1、什么是贝塞尔曲线
  • 2、常见贝塞尔曲线
  • 3、贝塞尔曲线通用公式
    • 3.1、贝塞尔曲线通用公式
    • 3.2、思路解析
    • 3.3、实现方法
    • 3.4、效果展示
    • 3.5、Demo下载
  • 4、结束语

1、什么是贝塞尔曲线

  Bézier curve(贝塞尔曲线)是应用于二维图形应用程序的数学曲线。 曲线定义:起始点、终止点(也称锚点)、控制点。通过调整控制点,贝塞尔曲线的形状会发生变化。 1962年,法国数学家Pierre Bézier第一个研究了这种矢量绘制曲线的方法,并给出了详细的计算公式,因此按照这样的公式绘制出来的曲线就用他的姓氏来命名,称为贝塞尔曲线。
  看了这段话,相信你还是不大明白贝塞尔曲线到底是怎么样的,这里放上贝塞尔曲线扫盲贴,有需要的自行阅读!这里有个贝塞尔游戏,有兴趣的可以体验一下!

2、常见贝塞尔曲线

  这里我们放上去常见的贝塞尔曲线效果演示图:

以下公式中:
B(t)为t时间下 点的坐标
P0为起点,Pn为终点,Pi为控制点

  • 一阶贝塞尔曲线(线段)

一阶贝塞尔曲线通用公式:
B(t)=(1−t)P0+tP1,t∈[0,1]\begin{aligned} B(t)=(1-t)P_0+tP_1, t∈[0,1] \end{aligned} B(t)=(1−t)P0​+tP1​,t∈[0,1]​

意义:由 P0 至 P1 的连续点, 描述的一条线段

  • 二阶贝塞尔曲线(抛物线)

    二阶贝塞尔曲线通用公式:
    B(t)=(1−t)2P0+2t(1−t)P1+t2P2,t∈[0,1]\begin{aligned} B(t)=(1-t)^2P_0+2t(1-t)P_1+t^2P_2, t∈[0,1] \end{aligned} B(t)=(1−t)2P0​+2t(1−t)P1​+t2P2​,t∈[0,1]​

原理:
由 P0 至 P1 的连续点 Q0,描述一条线段。
由 P1 至 P2 的连续点 Q1,描述一条线段。
由 Q0 至 Q1 的连续点 B(t),描述一条二次贝塞尔曲线。
经验:P1-P0为曲线在P0处的切线

  • 三阶贝塞尔曲线


三阶贝塞尔曲线通用公式:
B(t)=(1−t)3P0+3t(1−t)2P1+3t2(1−t)P2+t3P3,t∈[0,1]\begin{aligned} B(t)=(1-t)^3P_0+3t(1-t)^2P_1+3t^2(1-t)P_2+t^3P_3, t∈[0,1] \end{aligned} B(t)=(1−t)3P0​+3t(1−t)2P1​+3t2(1−t)P2​+t3P3​,t∈[0,1]​

  • 四阶贝塞尔曲线

  • 五阶贝塞尔曲线

3、贝塞尔曲线通用公式

3.1、贝塞尔曲线通用公式

  我们查阅资料给出的一般公式是这样的:

B(t)=∑i=0n(ni)Pi(1−t)n−iti=(n0)P0(1−t)nt0+(n1)P1(1−t)n−1t1+...+(nn−1)Pn−1(1−t)1tn−1+(nn)Pn(1−t)0tn,t∈[0,1]\begin{aligned} B(t)=\sum_{i=0}^n \begin{pmatrix} n\\i \end{pmatrix} P_i(1-t)^{n-i}t^i= \begin{pmatrix} n\\0 \end{pmatrix} P_0(1-t)^nt^0+ \begin{pmatrix} n\\1 \end{pmatrix} P_1(1-t)^{n-1}t^1+...+ \begin{pmatrix} n\\n-1 \end{pmatrix} P_{n-1}(1-t)^1t^{n-1}+ \begin{pmatrix} n\\n \end{pmatrix} P_n(1-t)^0t^n, t\in[0,1] \end{aligned} B(t)=i=0∑n​(ni​)Pi​(1−t)n−iti=(n0​)P0​(1−t)nt0+(n1​)P1​(1−t)n−1t1+...+(nn−1​)Pn−1​(1−t)1tn−1+(nn​)Pn​(1−t)0tn,t∈[0,1]​

3.2、思路解析

观察上面公式,可以查看出,其公式是由一个格式固定的表达式之和来表示,这个表达式就是关键:
(ni)Pi(1−t)n−iti,t∈[0,1]\begin{aligned} \begin{pmatrix} n\\i \end{pmatrix} P_i(1-t)^{n-i}t^i, t\in[0,1] \end{aligned} (ni​)Pi​(1−t)n−iti,t∈[0,1]​

该表达式可分为四个部分看:

  • 从 i 递增到 n 的常数部分
  • PiP_iPi​ 坐标部分
  • (1−t)n−i(1 - t)^{n - i}(1−t)n−i
  • tit^iti

可以看出这四部分都与 i 的值相关,此外 t 值的计算方式为:i/(n+1)

  如果直接从上面的公式上找规律比较抽象,那就从具体的例子中找规律吧。
  设 Bt 为要计算的贝塞尔曲线上的坐标,N 为控制点个数,P0,P1,P2…Pn 为贝塞尔曲线控制点的坐标,当 N 值不同时有如下计算公式:

如 N 为 3 表示贝塞尔曲线的控制点有 3 个点,这时 n 为 2 ,这三个点分别用 P0,P1,P2 表示。

  • N = 3  P=(1−t)2P0+2(1−t)tP1+t2P2P=(1-t)^2P_0 + 2(1-t)tP_1 + t^2P_2P=(1−t)2P0​+2(1−t)tP1​+t2P2​
  • N = 4  P=(1−t)3P0+3(1−t)2tP1+3(1−t)t2P2+t3P3P= (1-t)^3P_0 + 3(1-t)^2tP_1 + 3(1-t)t^2P_2 + t^3P_3P=(1−t)3P0​+3(1−t)2tP1​+3(1−t)t2P2​+t3P3​
  • N = 5  P=(1−t)4P0+4(1−t)3tP1+6(1−t)2t2P2+4(1−t)t3P3+t4P4P = (1-t)^4P_0 + 4(1-t)^3tP_1 + 6(1-t)^2t^2P_2 + 4(1-t)t^3P_3 + t^4P_4P=(1−t)4P0​+4(1−t)3tP1​+6(1−t)2t2P2​+4(1−t)t3P3​+t4P4​

  将贝塞尔曲线一般参数公式中的表达式用如下方式表示,设有常数 a,b 和 c,则该表达式可统一表示为如下形式:
a(1−t)btcPn,t∈[0,1]a(1 - t)^bt^cP_n, t\in[0,1] a(1−t)btcPn​,t∈[0,1]

  分析当 N 分别为3,4,5 时对应 a,b,c 的值:
如 N = 3 时,公式有三个表达式,第一个表达式为 (1−t)2P0(1-t)^2P_0(1−t)2P0​,其对应 a,b,c 值分别为:1,2,0

  • N = 3: 1,2,0 2,1,1 1,0,2
    a: 1 2 1
    b: 2 1 0
    c: 0 1 2
  • N = 4: 1,3,0 3,2,1 3,1,2 1,0,3
    a: 1 3 3 1
    b: 3 2 1 0
    c: 0 1 2 3
  • N = 5: 1,4,0 4,3,1 6,2,2 4,1,3 1,0,4
    a: 1 4 6 4 1
    b: 4 3 2 1 0
    c: 0 1 2 3 4

  根据上面的分析就可以总结出 a,b,c 对应的取值规则:

  • b: (N - 1) 递减到 0 (b 为 1-t 的幂)
  • c: 0 递增到 (N - 1) (c 为 t 的幂)
  • a: 在 N 分别为 1,2,3,4,5 时将其值用如下形式表示:
    N=1:———1
    N=2:——–1 1
    N=3:——1 2 1
    N=4:—–1 3 3 1
    N=5:—1 4 6 4 1
    a 值的改变规则为: 杨辉三角

3.3、实现方法

  好了,到这里我们基本上已经知道思路了,下面我们使用Ts写一下:

这里使用的是:
Vscode
Cocos Creator

/*** * @param ctrlPosArr 贝塞尔曲线控制点坐标* @param precison 精度,需要计算的该条贝塞尔曲线上的点的数目* @param resArr 该条贝塞尔曲线上的点(二维坐标)*/getBezierPos(ctrlPosArr:Array<cc.Vec2>,precison:number):Array<cc.Vec2>{cc.log(ctrlPosArr)let resArr:Array<cc.Vec2> = new Array<cc.Vec2>();/**贝塞尔曲线控制点数目(阶数)*/let number:number = ctrlPosArr.length;if(number < 2){cc.log("控制点数不能小于 2");return resArr;}/**杨辉三角数据 */let yangHuiArr:Array<number> = this.getYangHuiTriangle(number);//计算坐标for (let i = 0; i < precison; i++) {let t:number = i/precison;let tmpX:number = 0;let tmpY:number = 0;for (let j = 0; j < number; j++) {tmpX += Math.pow(1 - t,number - j - 1) * ctrlPosArr[j].x * Math.pow(t,j) * yangHuiArr[j];tmpY += Math.pow(1 - t,number - j - 1) * ctrlPosArr[j].y * Math.pow(t,j) * yangHuiArr[j];}// resArr[i].x = tmpX;// resArr[i].y = tmpY;resArr[i] = new cc.Vec2(tmpX,tmpY);}return resArr;}/*** 获取杨辉三角对应阶数的值* @param num 杨辉三角阶数*/getYangHuiTriangle(num:number):Array<number>{//计算杨辉三角let yangHuiArr = new Array<number>();if(num === 1){yangHuiArr[0] = 1;}else{yangHuiArr[0] = yangHuiArr[1] = 1;for (let i = 3; i <= num; i++) {let t = new Array<number>();for (let j = 0; j < i - 1; j++) {t[j] = yangHuiArr[j];}yangHuiArr[0] = yangHuiArr[i - 1] = 1;for (let j = 0; j < i - 2; j++) {yangHuiArr[j + 1] = t[j] + t[j + 1];            }}}cc.log(yangHuiArr);return yangHuiArr;}

3.4、效果展示

  下面我取几个点,做一下演示:

let p1:cc.Vec2 = cc.v2(0,0);let p2:cc.Vec2 = cc.v2(200,200);let p3:cc.Vec2 = cc.v2(400,150);let p4:cc.Vec2 = cc.v2(500,200);this.drawPoint(p1);this.drawPoint(p2);this.drawPoint(p3);this.drawPoint(p4);this.drawLine(p1,p2,cc.Color.GREEN);this.drawLine(p2,p3,cc.Color.GREEN);this.drawLine(p3,p4,cc.Color.GREEN);let posArr1:Array<cc.Vec2> = [cc.v2(-150,80),cc.v2(1,80),cc.v2(48,92),cc.v2(167,159),cc.v2(309,271),cc.v2(421,394),cc.v2(514,498),cc.v2(597,572),cc.v2(658,590),cc.v2(745,550),cc.v2(802,465),cc.v2(841,320),cc.v2(866,266),cc.v2(951,163),cc.v2(1054,133),cc.v2(1228,126),cc.v2(1278,128),cc.v2(1430,128)]

  为了验证正确性,我这里先用ts自带的贝塞尔曲线公式,通过四个点来画出三阶贝塞尔曲线,再用自己的点来画一遍,然后用自己的代码来画n阶贝塞尔曲线。效果如下:

3.5、Demo下载

  为了方便大家,当然如果有不明白的童鞋也可以在这里点此下载Demo示例!

4、结束语


The End
  好了,今天的分享就到这里,如有不足之处,还望大家及时指正,随时欢迎探讨交流!!!


喜欢的朋友们,请收藏、点赞、评论!您的肯定是我写作的不竭动力!

n 阶贝塞尔曲线计算公式——Ts实现相关推荐

  1. java实现的三阶贝塞尔曲线_n 阶贝塞尔曲线计算公式实现

    n 阶贝塞尔曲线计算公式实现 关于贝塞尔曲线是什么,可以用来做什么,这里就不再介绍,如果你还不了解,可以先去看看下面这篇文章:贝塞尔曲线扫盲 1. 效果参考 2. 思路解析 百度百科上给出的一般参数公 ...

  2. n 阶贝塞尔曲线计算公式实现

    n 阶贝塞尔曲线计算公式实现 关于贝塞尔曲线是什么,可以用来做什么,这里就不再介绍,如果你还不了解,可以先去看看下面这篇文章:贝塞尔曲线扫盲 1. 效果参考 2. 思路解析 百度百科上给出的一般参数公 ...

  3. js-三阶贝塞尔曲线计算公式

    /*** 三阶贝塞尔曲线* B(t) = P0 * (1-t)^3 + 3 * P1 * t * (1-t)^2 + 3 * P2 * t^2 * (1-t) + P3 * t^3, t ∈ [0,1 ...

  4. canvas贝塞尔曲线爱心_canvas实现高阶贝塞尔曲线(N阶贝塞尔曲线生成器)

    写在最前 由于原生的Canvas最高只支持到三阶贝塞尔曲线,那么我想添加多个控制点怎么办呢?(即便大部分复杂曲线都可以用3阶贝塞尔来模拟)与此同时,关于贝塞尔控制点的位置我们很难非常直观的清楚到底将控 ...

  5. 【Android UI】贝塞尔曲线 ② ( 二阶贝塞尔曲线公式 | 三阶贝塞尔曲线及公式 | 高阶贝塞尔曲线 )

    文章目录 一.二阶贝塞尔曲线公式 二.三阶贝塞尔曲线 三.高阶贝塞尔曲线 贝塞尔曲线参考 : https://github.com/venshine/BezierMaker 一.二阶贝塞尔曲线公式 二 ...

  6. canvas实现高阶贝塞尔曲线

    写在最前 由于原生的Canvas最高只支持到三阶贝塞尔曲线,那么我想添加多个控制点怎么办呢?(即便大部分复杂曲线都可以用3阶贝塞尔来模拟)与此同时,关于贝塞尔控制点的位置我们很难非常直观的清楚到底将控 ...

  7. 3阶贝塞尔曲线沿线长等距分割方法

    3阶贝塞尔曲线等距分割 1.引言 2.数学计算 3.应用 4.demo下载 1.引言 贝塞尔(bezier)曲线又称样条曲线,常用的有2阶跟3阶形式,3阶曲线最为常用,其公式(1)为: P0/P1/P ...

  8. 用C语言绘制任意阶贝塞尔曲线(Bézier curve)

    计算机图形学中贝塞尔曲线的绘制.使用的开发软件及版本为VS2015,以及 EasyX库.实现动态演示贝塞尔曲线实现的过程,且阶次不限! 源代码获取方式:1.添加微信(微信号:my_12581)获取.2 ...

  9. 转载:贝塞尔曲线计算公式

    原文地址: https://zhuanlan.zhihu.com/p/33193050 用到贝塞尔曲线公式来计算出顶点,从而生成贝塞尔曲线. /*** 生成四阶贝塞尔曲线定点数据* @param p0 ...

最新文章

  1. easyUI样式之easyui-switchbutton
  2. 引进研究生:​50万房补+年薪13万起;本科生30万房补​
  3. sleep( ) 和 wait( ) 的这 5 个区别,你知道几个
  4. 关于window.history.back()后退问题
  5. golang调用java的函数_大话golang性能分析(一):profile基本原理
  6. 当当年中庆典,力度超前,花120买300的硬核书
  7. 笨办法学 Python · 续 练习 19:改善性能
  8. linux分区压力测试,stress-Linux系统压力测试工具使用及系统负载很高的几种场景测试...
  9. win10,Net Share 共享,每次开机都会出现 --- 彻底关闭的方法---禁用server服务
  10. vue中使用axios发送请求(二)
  11. 计算机二级教程48讲视频,天津大学 《线性代数》视频教程48讲 真人手写精品
  12. 利用uDig 快速生成 GeoServer 可用的 SLD 渲染文件
  13. 你还为给自己的IT团队起名字,写口号烦恼吗?(较为流行的团队名称)
  14. 让华为小米抱团 统一推送联盟究竟是何方神圣?
  15. PowerDesigner导入现有表结构
  16. HashMap中的hash与rehash
  17. offsetParent和parentElement的区别
  18. Pygame从0实战10(泡泡小游戏添加音效)
  19. Koreographer音乐插件基本使用
  20. TMS320C6747的emifa访问异步外部存储

热门文章

  1. 基于phpqrcode生成带LOGO图标的二维码(源代码例子)
  2. Cassandra 集群核心配置和概梳理
  3. 【Papernotes】 Applying Deep Learning To Airbnb Search
  4. Vim 编辑器:如何增加或减少日期、时间、数字和序数
  5. excel2010支持html,Excel 2010中的条件格式
  6. Android禁止输入表情符号
  7. 【基于Python的招聘网站爬虫及可视化的设计与实现】
  8. 使用Node.JS进行谷歌地图定位
  9. 网站分析18——网站竞品分析
  10. SpringBoot:四种读取properties文件的方式