在opengl中,我们可以用少许的参数来描述一个曲线,其中贝塞尔曲线算是一种很常见的曲线控制方法,我们先来看维基百科里对贝塞尔曲线的说明:


给定点P0P1,线性贝塞尔曲线只是一条两点之间的直线。这条线由下式给出:

贝塞尔曲线.简单推导与用opengl实现动态画出。

且其等同于线性插值


二次方贝塞尔曲线的路径由给定点P0P1P2的函数Bt)追踪:

贝塞尔曲线.简单推导与用opengl实现动态画出。

TrueType字体就运用了以贝塞尔样条组成的二次贝塞尔曲线。

一些关于参数曲线的术语,有

贝塞尔曲线.简单推导与用opengl实现动态画出。

即多项式

贝塞尔曲线.简单推导与用opengl实现动态画出。

又称作n阶的伯恩斯坦基底多项式,定义00 = 1。

Pi称作贝塞尔曲线的控制点多边形以带有线的贝塞尔点连接而成,起始于P0并以Pn终止,称作贝塞尔多边形(或控制多边形)。贝塞尔多边形的凸包(convex hull)包含有贝塞尔曲线。

在这里贴这些,是因为让我们有个基本的理解,下面把维基百科里一个动态图放上,让大家有更清晰了解贝塞尔曲线是如何生成的。

贝塞尔曲线.简单推导与用opengl实现动态画出。贝塞尔曲线.简单推导与用opengl实现动态画出。贝塞尔曲线.简单推导与用opengl实现动态画出。

然后我们来分析相应数据的产生。最简单的二点,其实就是线段的参数化,大家能简单得到f(t)=p0+(p1-p0)*t=(1-t)p0+t*p1.

二次方贝塞尔曲线话,我直接用下面的图给出相应过程。

贝塞尔曲线.简单推导与用opengl实现动态画出。

对应的三次方贝塞尔曲线,我们会如下图来门简略说明。

贝塞尔曲线.简单推导与用opengl实现动态画出。

在上面,我们给出用我们推导的过程。下面是根据这个过程生成的主要代码。

 1 type BezierCurve() =
 2     static member BasicCurve (p0:Vector3, p1:Vector3,t) = (1.f-t)*p0 + t*p1
 3     static member GetCurveValue(points : Vector3[],t:float32) =
 4         //求得我们是几次方贝兹曲线
 5         let j = points.Length - 1
 6         //复制最先的点p0-pn,以免被新赋值。
 7         let mutable ps = [| for p in points -> p|]
 8         //这是控制层数,如三次方贝兹曲线
 9         //则分别是第一层[p0;p1;p2;p3]二[p4;p5;p6]三[p7;p8]四[p9]
10         for n = j downto 1 do 
11             for i = 0 to n - 1 do
12                 let p0 = ps.[i]
13                 let p1 = ps.[i+1]
14                 //如上,根据(p0,p1求p4)(p1,p2求p5),(p4,p5求p7)
15                 ps.[i] <- BezierCurve.BasicCurve(p0,p1,t)
16         //就是上面p9
17         ps.[0]
18     static member CreateCurve(points : Vector3[],count:int) =
19         let ps = Array.create count Vector3.Zero
20         let step = 1.f/float32 count
21         let len = count - 1
22         for i = 0 to len do
23             ps.[i] <- BezierCurve.GetCurveValue(points,step * float32 i)
24         ps
25     static member GetCurveValueS(points : Vector3[],t:float32) =
26         let j = points.Length - 1
27         let mutable ps = [| for p in points -> p|]
28         let mutable rs = [||]
29         for n = j downto 1 do 
30             for i = 0 to n - 1 do
31                 let p0 = ps.[i]
32                 let p1 = ps.[i+1]
33                 ps.[i] <- BezierCurve.BasicCurve(p0,p1,t)
34             rs <- Array.append rs ps.[0 .. n-1]
35         ps.[0],rs
View Code

相关文章:

  • 2021-11-19
  • 2022-12-23
  • 2022-12-23
  • 2021-11-28
  • 2021-11-21
  • 2022-12-23
猜你喜欢
  • 2021-10-28
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-01-12
  • 2022-12-23
相关资源
相似解决方案