贝塞尔曲线介绍及其应用

  贝塞尔样条是一个允许用户控制节点处斜率的样条,是一种特殊的三次样条。
  皮埃尔·贝塞尔在其为雷诺(Renault)汽车公司工作时有了这个创意。Paul de Casteljau在与雷诺竞争关系的汽车公司雪铁龙Citroen公司工作时也独立有了这个想法。这在两家公司都认为是工业秘密,事实上在贝塞尔发表了他的研究后,大家才知道两家公司都进行了相同的研究。今天贝塞尔曲线(Bézier curve)是计算机辅助设计和制造的奠基石。
  平面贝塞尔样条的每一段由4个点 ( x 1 , y 1 ) , ( x 2 , y 2 ) , ( x 3 , y 3 ) , ( x 4 , y 4 ) (x_{1}, y_{1}), (x_{2}, y_{2}), (x_{3}, y_{3}),(x_{4}, y_{4}) (x1,y1),(x2,y2),(x3,y3),(x4,y4)所确定。第一个点和最后一个点是样条的起点和终点,中间的两个点是控制点,曲线以切线方向 ( x 2 − x 1 , y 2 − y 1 ) (x_{2}-x_{1}, y_{2}-y_{1}) (x2x1,y2y1)离开 ( x 1 , y 1 ) (x_{1}, y_{1}) (x1,y1),并以切线方向 ( x 4 − x 3 , y 4 − y 3 ) (x_{4}-x_{3}, y_{4}-y_{3}) (x4x3,y4y3) ( x 4 , y 4 ) (x_{4}, y_{4}) (x4,y4)点结束。

对于贝塞尔曲线,给定端点 ( x 1 , y 1 ) , ( x 4 , y 4 ) (x_{1}, y_{1}), (x_{4}, y_{4}) (x1,y1),(x4,y4)和控制点 ( x 2 , y 2 ) , ( x 3 , y 3 ) (x_{2}, y_{2}), (x_{3}, y_{3}) (x2,y2),(x3,y3),设
b x = 3 ( x 2 − x 1 ) c x = 3 ( x 3 − x 2 ) − b x d x = x 4 − x 1 − b x − c x b y = 3 ( y 2 − y 1 ) c y = 3 ( y 3 − y 2 ) − b y d y = y 4 − y 1 − b y − c y b_{x}=3(x_{2}-x_{1})\\ c_{x}=3(x_{3}-x_{2})-b_{x}\\ d_{x}=x_{4}-x_{1}-b_{x}-c_{x}\\ b_{y}=3(y_{2}-y_{1})\\ c_{y}=3(y_{3}-y_{2})-b_{y}\\ d_{y}=y_{4}-y_{1}-b_{y}-c_{y} bx=3(x2x1)cx=3(x3x2)bxdx=x4x1bxcxby=3(y2y1)cy=3(y3y2)bydy=y4y1bycy
定义在 0 ≤ t ≤ 1 0\leq t \leq 1 0t1的贝塞尔曲线如下:

x ( t ) = x 1 + b x t + c x t 2 + d x t 3 y ( t ) = y 1 + b y t + c y t 2 + d y t 3 x(t) = x_{1}+b_{x}t+c_{x}t^{2}+d_{x}t^{3}\\ y(t) = y_{1}+b_{y}t+c_{y}t^{2}+d_{y}t^{3} x(t)=x1+bxt+cxt2+dxt3y(t)=y1+byt+cyt2+dyt3

应用1 绘制贝塞尔曲线

  找出贝塞尔曲线(x(t), y(t))通过点(x,y)=(1, 1)和(2, 2),控制点为(1, 3)和(3, 3)。
  Python实现程序如下:

# -*- coding: utf-8 -*-
# @Time : 2023/3/9 10:56
# @Author : Jclian91
# @File : Bezier_curve.py
# @Place : Xuhui, Shanghai
# solve Bézier curve with given four points
import matplotlib.pyplot as plt


def get_bezier_curve(pass_points, control_points):
    p_point1, p_point2 = pass_points
    x1, y1 = p_point1
    x4, y4 = p_point2
    c_point1, c_point2 = control_points
    x2, y2 = c_point1
    x3, y3 = c_point2
    # parameter in bezier curve
    b_x = 3 * (x2-x1)
    c_x = 3 * (x3-x2) - b_x
    d_x = x4 - x1 - b_x - c_x
    b_y = 3 * (y2 - y1)
    c_y = 3 * (y3 - y2) - b_y
    d_y = y4 - y1 - b_y - c_y
    # curve
    n = 1000    # sample points in interval [0, 1]
    step = 1/n
    x_list, y_list = [], []
    t = 0
    for i in range(n):
        t += step
        x_list.append(x1 + b_x * t + c_x * (t**2) + d_x * (t**3))
        y_list.append(y1 + b_y * t + c_y * (t ** 2) + d_y * (t ** 3))
    return x_list, y_list


# plot bezier curve
def plot_bezier_curve(pass_points, control_points):
    x_list, y_list = get_bezier_curve(pass_points, control_points)
    plt.plot(x_list, y_list, label='bezier_curve', color='red')
    plt.title(f'Bezier Curve')
    plt.legend()
    # plt.show()
    plt.savefig(f"bezier_curve.png")


if __name__ == '__main__':
    # example curve
    p_points = [(1, 1), (2, 2)]
    c_points = [(1, 3), (3, 3)]
    plot_bezier_curve(p_points, c_points)

绘制的贝塞尔曲线如下:
样例贝塞尔曲线

绘制计算机字符

  在这个例子中,我们将解释如何使用二维贝塞尔曲线划出Times Roman字体的T字母。
  Python实现程序如下:

# -*- coding: utf-8 -*-
# @Time : 2023/3/9 10:56
# @Author : Jclian91
# @File : Bezier_curve.py
# @Place : Xuhui, Shanghai
# solve Bézier curve with given four points
import matplotlib.pyplot as plt


def get_bezier_curve(pass_points, control_points):
    p_point1, p_point2 = pass_points
    x1, y1 = p_point1
    x4, y4 = p_point2
    c_point1, c_point2 = control_points
    x2, y2 = c_point1
    x3, y3 = c_point2
    # parameter in bezier curve
    b_x = 3 * (x2-x1)
    c_x = 3 * (x3-x2) - b_x
    d_x = x4 - x1 - b_x - c_x
    b_y = 3 * (y2 - y1)
    c_y = 3 * (y3 - y2) - b_y
    d_y = y4 - y1 - b_y - c_y
    # curve
    n = 1000    # sample points in interval [0, 1]
    step = 1/n
    x_list, y_list = [], []
    t = 0
    for i in range(n):
        t += step
        x_list.append(x1 + b_x * t + c_x * (t**2) + d_x * (t**3))
        y_list.append(y1 + b_y * t + c_y * (t ** 2) + d_y * (t ** 3))
    return x_list, y_list


# plot character T in Times Roman Font
def plot_t_in_times_roman_font():
    points = [[(237, 620), (237, 620), (237, 120), (237, 120)],
              [(237, 120), (237, 35), (226, 24), (143, 19)],
              [(143, 19), (143, 19), (143, 0), (143, 0)],
              [(143, 0), (143, 0), (435, 0), (435, 0)],
              [(435, 0), (435, 0), (435, 19), (435, 19)],
              [(435, 19), (353, 23), (339, 36), (339, 109)],
              [(339, 109), (339, 108), (339, 620), (339, 620)],
              [(339, 620), (339, 620), (339, 620), (339, 620)],
              [(339, 620), (507, 620), (529, 602), (552, 492)],
              [(552, 492), (552, 492), (576, 492), (576, 492)],
              [(576, 492), (576, 492), (570, 662), (570, 662)],
              [(570, 662), (570, 662), (6, 662), (6, 662)],
              [(6, 662), (6, 662), (0, 492), (0, 492)],
              [(0, 492), (0, 492), (24, 492), (24, 492)],
              [(24, 492), (48, 602), (71, 620), (183, 620)],
              [(183, 620), (183, 620), (237, 620), (237, 620)]
              ]
    for point_list in points:
        pass_points, control_points = [point_list[0], point_list[-1]], point_list[1:3]
        x_list, y_list = get_bezier_curve(pass_points, control_points)
        plt.plot(x_list, y_list, color='black')
    plt.title('Bezier Curve')
    # plt.show()
    plt.savefig("T_in_Times_Roman_Font.png")


if __name__ == '__main__':
    # T in Times Roman Font with Bézier Curve
    plot_t_in_times_roman_font()

运行结果如下:
Times Roman字体的字母T
当前使用贝塞尔曲线可以生成数百种不同字体的字符,显示在计算机屏幕或者打印机上。尽管字体信息很多年来都是一个秘密,但是现在一部分在网上已经公开。因此,今天贝塞尔曲线(Bézier curve)是计算机辅助设计和制造的奠基石。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值