贝塞尔曲线-曲线拟合

1、贝塞尔曲线生成原理

生成过程如下图所示:


具体步骤

  1. 在二维平面内选三个不同的点(起点A,中间点B,终点C)并依次用线段连接
  2. 在线段AB和BC上按比例分割找到新的起点和中间点:D、E两点,使得AD/AB=BE/BC
  3. 连接DE,并在DE上找到新的起点F点,EC上找到新的中间点G点,使其满足DF/DE=EG/EC
  4. 重复步骤1、2、3,找出符合上述条件的所有点,直到新的起点和终点C重合或者中间点和终点C重合(完全重合或者距离小于某个设定阈值)时结束递归
  5. 连接上述所有符合条件的点A、D、F、H、J...C,所形成的曲线就是贝塞尔曲线。

上述示意图为二阶贝塞尔曲线形成过程,高阶贝塞尔曲线过程类似,可以使用递归实现。

贝塞尔曲线生成代码如下:

class Bezier:
    def __init__(self,points,baseRatio=1e-5):
        self.curve = []
        self.ratio = baseRatio
        self.Points = points
    def findP(self):  # start,end:矩阵:1*2,1*2。更新p0,p1。ratio:比例:[0,1]
        self.curve.append(self.Points[0])
        self.ratio=self.ratio+1e-2#使raito非固定值,否则递归深度过深,容易栈溢出
        # 寻找pNew
        for ii in range(1, len(self.Points)):
            '''
            *  a(x0,y0)
            .*  b(x,y)
            ...
            ....
            ....*  c(x1,y1)
            (x-x0)/(x1-x0)=0.4-->x=(x1-x0)*0.4+x0
            (y-y0)/(y1-y0)=0.4-->y=(y1-y0)*0.4+y0
            '''
            pNew = [(self.Points[ii][0] - self.Points[ii - 1][0]) * self.ratio + self.Points[ii - 1][0],
                    (self.Points[ii][1] - self.Points[ii - 1][1]) * self.ratio + self.Points[ii - 1][1]]
            # 更新
            self.Points[ii - 1] = pNew
        if np.sqrt(sum(np.power((self.Points[-1][0] - self.Points[0][0],self.Points[-1][1] - self.Points[0][1]), 2)))>1e-5:#新的起点和终点重合时,结束递归
            self.findP()
    def run(self):
        self.findP()
        self.curve.append(self.Points[-1])
if __name__=='__main__':
    Points = [[1, 1], [2, 1], [2, 2], [1, 2]]
    xx = Bezier(p)
    xx.run()
    xx.curve = np.array(xx.curve)
    plt.figure(1)
    plt.plot(xx.curve[:,0],xx.curve[:,1])
    plt.show()

1.1贝塞尔拟合曲线

简单的贝塞尔曲线拟合效果如下

如下图所示,点A、点C分别为起点和终点,"中间"点B称为控制点。

通过调整控制点B的位置,可以调整曲线的曲率以及方向(凸或者凹),如下图所示,其中红点为控制点

                          

 用贝塞尔曲线拟合,需要注意控制点的选择,还要做平滑优化曲线处理(待完成),如下图所示

        

 2、用贝塞尔曲线做路径规划

待完成

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值