贝塞尔曲线(Bezier)

作者:追风剑情 发布于:2019-2-17 14:31 分类:Algorithms

Bezier曲线的定义

给出型值点P0,P1,...,Pn,它们所确定的Bezier曲线是

1111.png

式中,基函数Bi,n(t)是Bernstein多项式:

2222.png

式中可能涉及0!及00,按约定均为1。0的任何次方都为0(0的0次方无意义)。任何数的0次方都为1(0的0次方无意)。

这里Bezier曲线可以看作是n+1个混合函数混合给定的n+1个顶点而产生的,混合函数用Bernstein多项式,所生成曲线是n次多项式。通常n+1个顶点也称为控制点,依次连接各控制点的多边形称为控制多边形。

例如,在n=1时,上式成为

33333.png

这表明一次Bezier曲线是连接起点P0和终点P1的直线段。

在n=2时,上式成为

4444.png

由此不难知道二次Bezier曲线是抛物线。

在n=3时,上式成为

555.png

这是一条三次参数多项式曲线。

Bernstein基函数具有如下性质,这些性质也决定了Bezier曲线的性质。

(1) 正性

1111.png

(2) 端点性质

111111.png

(3) 规范性

11111.png

(4) 对称性

2222.png

33333.png

(5) 权性

3333.png

由二项式定理可知:

4444.png

二项式定理

111111.png

二项式定理常用形式

2222.png

(6) 递推性

555.png

即高一次的Bernstein基函数可由两个低一次的Bernstein基函数线性组合而成。由于有组合恒等式:

666.png

所以

777.png

(7) 导函数

3333.png

因为

4444.png

11111.png

22222.png

(8) 最大值

Bi,n(t)在t=i/n处达到最大值。

因为当Bi,n(t)取最大值时,B'i,n(t)=0。推得Bi-1,n(t)=Bi-1,n(t),整理

222.png

333.png

推导过程

11111.png

几何作图法

几何作图法也称为de Casteljau算法,它利用了Bezier曲线的分割递推性实现Bezier曲线的绘制。

几何作图法的优点是直观性强,计算速度快。

9999.png(图1)

递推关系

888.png

上式含义是: 由点P0,P1,...,Pn所确定的n次Bezier曲线在点t的值,可以由点P0,P1,...,Pn-1所确定的n-1次Bezier曲线在点t的值,与由点P1,P2,...,Pn所确定的n-1次Bezier曲线在点t的值,通过递推关系的线性组合简单地求得。

n次Bezier曲线上控制点在t时的值P(t),可以归结为计算两个n-1次Bezier曲线在t时的值的线性组合,这一过程可以继续下去。图1中已知三次Bezier曲线的控制顶点P0,P1,P2,P3,递归计算先按t的比例在控制多边形各边上求得P0(1),P1(1),P2(1),再求得P0(2),P1(2),最后求得P0(3),即为P(t)对应的点。

示例:C#版——利用几何作图法算法实现

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. namespace BezierTest
  7. {
  8. public class Bezier
  9. {
  10. /// <summary>
  11. /// 作图法算法实现
  12. /// </summary>
  13. /// <param name="P">控制点坐标</param>
  14. /// <param name="t">插值参数</param>
  15. /// <returns>返回曲线在参数t的坐标值</returns>
  16. public static Point Lerp(Point[] P, double t)
  17. {
  18. int m, i;//m 边数
  19. int n = P.Length; //n 控制点个数
  20. Point P0 = null;
  21. Point[] R, Q;
  22. R = new Point[n];
  23. Q = new Point[n];
  24. for (i = 0; i < n; i++)
  25. {
  26. R[i] = P[i];//将控制点坐标P保存于R中
  27. Q[i] = new Point();
  28. }
  29. //作n次外部循环,
  30. //每次循环都计算控制多边形上所有的m条边以参数t为分割比例的坐标值
  31. for(m=n-1; m > 0; m--)
  32. {
  33. //作m次内部循环,
  34. //每次循环计算控制多边形上一条边以参数t为分割比例的坐标值
  35. for(i=0; i <= m - 1; i++)
  36. {
  37. //n次Bezier曲线在点t的值,可由两条n-1次bezier曲线
  38. //在点t的值通过线性组合而求得
  39. Q[i].x = R[i].x + t * (R[i+1].x - R[i].x);
  40. Q[i].y = R[i].y + t * (R[i+1].y - R[i].y);
  41. }
  42. for (i = 0; i <= m - 1; i++)
  43. R[i] = Q[i];
  44. }
  45. P0 = R[0];
  46. R = null;
  47. Q = null;
  48. return P0;
  49. }
  50.  
  51. public class Point
  52. {
  53. public double x;
  54. public double y;
  55. }
  56. }
  57. }
Form1.cs
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9.  
  10. namespace BezierTest
  11. {
  12. public partial class Form1 : Form
  13. {
  14. public Form1()
  15. {
  16. InitializeComponent();
  17. }
  18.  
  19. public void PaintControlPoint(PaintEventArgs e, Bezier.Point[] P)
  20. {
  21. Graphics g = e.Graphics;
  22. Pen myPen = new Pen(Color.Red, 2);
  23. for(int i=0; i<P.Length; i++)
  24. {
  25. g.DrawEllipse(myPen, (float)P[i].x, (float)P[i].y, 3, 3);
  26. }
  27. }
  28.  
  29. public void PaintCurvePoint(PaintEventArgs e, Bezier.Point[] P, double t)
  30. {
  31. Bezier.Point tp = Bezier.Lerp(P, t);
  32.  
  33. Graphics g = e.Graphics;
  34. Pen myPen = new Pen(Color.Blue, 2);
  35. g.DrawEllipse(myPen, (float)tp.x, (float)tp.y, 1, 1);
  36. }
  37.  
  38. private void Form1_Paint(object sender, PaintEventArgs e)
  39. {
  40. Bezier.Point[] P = new Bezier.Point[]
  41. {
  42. new Bezier.Point{ x=0, y=100},
  43. new Bezier.Point{ x=50, y=0},
  44. new Bezier.Point{ x=80, y=200},
  45. new Bezier.Point{ x=130, y=50},
  46. new Bezier.Point{ x=200, y=100},
  47. };
  48.  
  49. PaintControlPoint(e, P);
  50.  
  51. for (double t = 0; t <= 1; t += 0.02)
  52. {
  53. PaintCurvePoint(e, P, t);
  54. }
  55. }
  56. }
  57. }


运行测试

红色为控制点,蓝色为曲线的插值点

55555.png7777.png

标签: Algorithms

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号