什么是贝塞尔曲线

贝塞尔曲线是应用于二维图形应用程序的数学曲线。
曲线定义:起始点、终止点(也称锚点)、控制点,通过调整控制点,贝塞尔曲线的形状会发生变化
贝塞尔曲线于1962由法国工程师皮埃尔·贝塞尔(Pierre Bézier)所广泛发表,他运用贝塞尔曲线来为汽车的主体进行设计。现在贝塞尔曲线在计算机图形学领域也是一个相当重要的参数曲线,很多画图工具软件都包含贝塞尔曲线的工具对象。

以下公式中,B(t)为t时间下点的坐标,P0为起点,Pn为终点,Pi为控制点

一阶贝塞尔曲线(线段):

一阶贝塞尔曲线
一阶贝塞尔曲线公式
意义:由P0至P1的连续点描述的一条线段

# -*- coding:utf-8 -*-
# @功能描述:使用turtle绘制一阶贝塞尔曲线
# @程序作者:老九学堂·窖头
# @版权信息:http://www.xuetang9.com
# @版本信息:0.0.1

import turtle
import time

def Bezier(p0, p1, t):
    """
    一阶贝塞尔函数,由P0至P1的连续点描述的一条线段
    :param p0:  起始点
    :param p1:  终点
    :param t:   时间
    :return:    返回对应时间点的中间坐标值
    """
    return (1 - t) * p0 + t * p1

# 定义开始和结束的两个点坐标
x1, y1 = 0, 0
x2, y2 = 100, -100
speed = 1           # 移动速度
show_count = 20     # 贝塞尔函数的取样次数
turtle.setup(500, 400, 0, 0)
turtle.pensize(1)
turtle.speed(1)
turtle.penup()
turtle.goto(x1, y1)
turtle.pendown()
for t in range(0, show_count + 1):              # 取样15次
    curr_x = Bezier(x1, x2, t / show_count)
    curr_y = Bezier(y1, y2, t / show_count)
    turtle.goto(curr_x, curr_y)
turtle.penup()
turtle.goto(curr_x, curr_y - 40)
turtle.write("一阶贝塞尔曲线绘制的线段", font=('华文新魏', 18,), align="right")
turtle.done()

二阶贝塞尔曲线(抛物线)

二阶贝塞尔曲线
二阶贝塞尔曲线公式
原理:由P0至P1的连续点Q0描述一条线段
由P1至P2的连续点Q1描述一条线段
由Q0至Q1的连续点B(t)描述一条二次贝塞尔曲线。

# -*- coding:utf-8 -*-
# @功能描述:使用turtle绘制二阶贝塞尔曲线
# @程序作者:老九学堂·窖头
# @版权信息:http://www.xuetang9.com
# @版本信息:0.0.1

import turtle
import time

def Bezier_2(p0, p1, p2, t):
    """
    二阶贝塞尔公式函数
    """
    return (1 - t) ** 2 * p0 + 2 * t * (1 - t) * p1 + t ** 2 * p2

# 二阶贝塞尔曲线需要三个控制点
x1, y1 = 0, 0
x2, y2 = 60, 80
x3, y3 = 140, 0
speed = 1           # 移动速度
show_count = 20     # 函数的取样次数

turtle.setup(500, 400, 0, 0)
turtle.pensize(1)
turtle.speed(1)
turtle.penup()
turtle.goto(x1, y1)
turtle.pendown()
for i in range(0, show_count + 1):
    # curr_x = Bezier_2(x1, x2, x3, i / show_count)
    # curr_y = Bezier_2(y1, y2, y3, i / show_count)
    # 也可以使用下面的方式,组合一阶函数来计算
    curr_x = Bezier(
                Bezier(x1, x2, i / show_count),
                Bezier(x2, x3, i / show_count),
                i / show_count
    )
    curr_y = Bezier(
                Bezier(y1, y2, i / show_count),
                Bezier(y2, y3, i / show_count),
                i / show_count
    )

    turtle.goto(curr_x, curr_y)

turtle.done()

了解了一阶、二阶函数的使用后,三阶、四阶等高阶函数的理解就不再困难了
有兴趣的小伙伴们就自行往下推导试试看看吧:)

三阶贝塞尔曲线:

三阶贝塞尔曲线
通用公式:
三阶贝塞尔曲线的通用公式


高阶贝塞尔曲线:

四阶贝塞尔曲线

五阶贝塞尔曲线

Leave a Comment