bezier曲线_套娃成神:贝塞尔曲线

2695ddfe4e58a91bcf9501d7c1106881.png

说明: 主要参考了 维基百科 , 建议将其和本文对照阅读。

应用场景

贝塞尔曲线在数学和图形学以及设计中都发挥了重要作用,原因就是它能够“作为一种多项式逼近在[ a, b ] 区间上所有的连续函数,并且收敛性很强,也就是一致收敛。” 用人话说呢,就是一种多项式曲线,能够用最少的参数来模拟任意曲线,并且模拟效果普遍极好。

所以各种设计软件,包括Processing, Illustrater等对其进行了广泛使用,从而实现对于曲线数据的数据压缩。

公式

下图选自维基:

ea865ae26c63cab603827d258ad55c17.png

可以看出,n次贝塞尔曲线需要n+1个点来确定,而这n+1个点中都包括了曲线起点和曲线终点。其具体形式和二项式公式有很大的相似性。

公式还是不太好理解,还好这个曲线还有一种图形化的描述,先来大概看看吧:

cfa7343af569fee617e680cec41cd95c.gif
(三次)贝塞尔曲线的图形化描述

这就很容易理解了,首先我们定义函数k平均:

def kmean(pa, pb, k):
    pax, pay = pa
    pbx, pby = pb
    return pax*k+pbx*(1-k), pay*k+pby*(1-k)

这个函数将两个点A, B的坐标按 k :(1-k)进行平均。图中的P0和P1之间的绿点就是P0和P1的k平均点,而k是一个从0到1的变量(也就是插图中的t)。

那么一次贝塞尔曲线就是:参数点(2个)之间的k平均点(1个)的轨迹。

二次贝塞尔曲线就是:参数点(3个)之间的k平均点(2个), 之间的k平均点(1个)的轨迹。

三次贝塞尔曲线就是:参数点(4个)之间的k平均点(3个) , 之间的k平均点(2个), 之间的k平均点(1个)的轨迹。

不知道熟练“套娃之术”的你有没有豁然开朗了呢?

Processing中验证

8ea2fcf92dc50fadbff37ac15998e2ec.png
https://www.zhihu.com/video/1228720109143052288

代码:

p0 = (100.0, 400.0)
p1 = (20.0, 100.0)
p2 = (400.0, 100.0)
p3 = (500.0, 400.0) 
ps = []
for p in (p0, p1, p2, p3):
    ps.extend(p)

def kmean(pa, pb, k):
    pax, pay = pa
    pbx, pby = pb
    return pax*k+pbx*(1-k), pay*k+pby*(1-k)

def line_points(ps):
    beginShape()
    for p in ps:
        vertex(*p)
        circle(p[0], p[1], 12)
    endShape()

def setup():
    size(600, 600)

def draw():
    background(255)
    noFill()
    bezier(*ps)
    k = float(frameCount)/1000 - frameCount/1000
    
    stroke(200, 0, 0)
    line_points((p0, p1, p2, p3))
    
    p01 = kmean(p0, p1, k)
    p12 = kmean(p1, p2, k)
    p23 = kmean(p2, p3, k)
    stroke(200, 100, 0)
    line_points((p01, p12, p23))
    
    p012 = kmean(p01, p12, k)
    p123 = kmean(p12, p23, k)
    stroke(200, 150, 0)
    line_points((p012, p123))
    
    p1234 = kmean(p012, p123, k)
    stroke(200,220, 0)
    line_points((p1234,))

一点扩展

其实贝塞尔曲线概念本身就是极漂亮的,那么想一想下面的这种效果在Processing中是如何实现的呢?

30818d75be5654f817159ae6e9554a94.png

更多资料

互动在线书:贝塞尔曲线的入门书

MIT出版:计算机辅助设计中的图形查询

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值