问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

贝塞尔曲线原理、推导及Matlab实现

创作时间:
作者:
@小白创作中心

贝塞尔曲线原理、推导及Matlab实现

引用
1
来源
1.
https://www.cnblogs.com/zbyisgudi/p/18284215

一、简介

贝塞尔曲线提出

在数学的数值分析领域中,贝塞尔曲线(Bézier curve)是计算机图形学中相当重要的参数曲线。更高维度的广泛化贝塞尔曲线就称作贝兹曲面,其中贝兹三角是一种特殊的实例。

贝塞尔曲线于1962年,由法国工程师皮埃尔·贝兹(Pierre Bézier)所广泛发表,他运用贝塞尔曲线来为汽车的主体进行设计。贝塞尔曲线最初由保尔·德·卡斯特里奥于1959年运用德卡斯特里奥算法开发,以稳定数值的方法求出贝塞尔曲线。

贝塞尔曲线特性

贝塞尔曲线有如下特性:

  • 通过(n)个控制点(P_1, P_2, P_3, ..., P_n)控制曲线形状。
  • 曲线只经过起点(P_1)和终点(P_n)。

二、原理

构建贝塞尔曲线

  1. 一次曲线(线性):
    一次贝塞尔曲线由两个端点(P_0)和(P_1)组成,曲线由线段直接连接这两个点,(B(t))描述一条由(P_0)至(P_1)的直线,可以视为一个(P_0)至(P_1)的连续中间点(Q_0)。

  2. 二次曲线
    二次贝塞尔曲线由定点(P_0, P_1, P_2)的函数(B(t))描述。为构建贝塞尔曲线,引入中间点(Q_0, Q_1):

  • (P_0, P_1)之间的连续点(Q_0),描述一条线性贝塞尔曲线;
  • (P_1, P_2)之间的连续点(Q_1),描述一条线性贝塞尔曲线;
  • (Q_0, Q_1)之间的连续点(B(t)),描述一条二次贝塞尔曲线。
  1. 三次曲线
    对于三次曲线,由定点(P_0, P_1, P_2, P_3)的函数(B(t))描述。可以加入三个可由线性贝塞尔曲线描述的中间点(Q_0, Q_1, Q_2),和两个由二次贝塞尔曲线描述的点(R_0, R_1)来描述:
  • (P_0, P_1)之间的连续点(Q_0),描述一条线性贝塞尔曲线;
  • (P_1, P_2)之间的连续点(Q_1),描述一条线性贝塞尔曲线;
  • (P_2, P_3)之间的连续点(Q_2),描述一条线性贝塞尔曲线;
  • (Q_0, Q_1)之间的连续点(R_0),描述一条二次贝塞尔曲线;
  • (Q_1, Q_2)之间的连续点(R_1),描述一条二次贝塞尔曲线;
  • (R_0, R_1)之间的连续点(B(t)),描述一条三次贝塞尔曲线。
  1. 四次曲线
    对于四次曲线,由定点(P_0, P_1, P_2, P_3, P_4)的函数(B(t))描述。可以加入四个可由线性贝塞尔曲线描述的中间点(Q_0, Q_1, Q_2, Q_3),三个由二次贝塞尔曲线描述的点(R_0, R_1, R_2),和两个由三次贝塞尔曲线描述的点(S_0, S_1)来描述:
  • (P_0, P_1)之间的连续点(Q_0),描述一条线性贝塞尔曲线;
  • (P_1, P_2)之间的连续点(Q_1),描述一条线性贝塞尔曲线;
  • (P_2, P_3)之间的连续点(Q_2),描述一条线性贝塞尔曲线;
  • (P_3, P_4)之间的连续点(Q_3),描述一条线性贝塞尔曲线;
  • (Q_0, Q_1)之间的连续点(R_0),描述一条二次贝塞尔曲线;
  • (Q_1, Q_2)之间的连续点(R_1),描述一条二次贝塞尔曲线;
  • (Q_2, Q_3)之间的连续点(R_2),描述一条二次贝塞尔曲线;
  • (R_0, R_1)之间的连续点(S_0),描述一条三次贝塞尔曲线;
  • (R_1, R_2)之间的连续点(S_1),描述一条三次贝塞尔曲线;
  • (S_0, S_1)之间的连续点(B(t)),描述一条四次贝塞尔曲线。
  1. 高阶曲线
    由上文可知,为构建更高阶的曲线,需要引入更多的中间点。同理可推得五次曲线。

构建贝塞尔曲线公式

  1. 一次曲线(线性):
    设(P_0)的坐标为((\alpha, \beta)),(P_1)的坐标为((\lambda, \mu)),引入中间点(Q_0)的坐标为((x, y)),则有:
    [\frac{x - \alpha}{\lambda - x} = \frac{t}{1 - t} ]
    可推得:
    [x = (1 - t)\alpha + t\lambda \tag1 ]
    同理,可得:
    [\frac{y - \beta}{\mu - y} = \frac{t}{1 - t} ]
    可推得:
    [y = (1 - t)\beta + t\mu \tag2 ]
    整理可得:
    [\left( \begin{matrix} x \ y \end{matrix} \right) =(1 - t) \left( \begin{matrix} \alpha \ \beta \end{matrix} \right) + t \left( \begin{matrix} \lambda \ \mu \end{matrix} \right) \tag3 ]
    可将式((3))简写为:
    [B(t) = (1 - t) P_0 + t P_1, t \in [0, 1] \tag4 ]
    得到一次贝塞尔曲线公式。

  2. 二次曲线
    设(P_0, P_1)上的中间点为(Q_0),(P_1, P_2)上的中间点为(Q_1),(Q_0, Q_1)上的中间点为(R_0),(R_0)即构建曲线的连续点。
    带入式((4))可得:
    [\begin{matrix} Q_0 = (1 - t) P_0 + t P_1 \ Q_1 = (1 - t) P_1 + t P_2 \ R_0 = (1 - t) Q_0 + t Q_1 \end{matrix} \tag5 ]
    将式((5))中的(Q_0)和(Q_1)代入(R_0)中,可得二次贝塞尔曲线公式:
    [B(t) = (1 - t) ^ 2 P_0 + 2 t (1 - t) P_1 + t ^ 2 P_2, t \in [0, 1] \tag6 ]

  3. 三次曲线
    同理,通过引入中间点(Q_0, Q_1, Q_2, R_0, R_1, S_0),代入使用式((6)),可得三次贝塞尔曲线公式:
    [B(t) = (1 - t) ^ 3 P_0 + 3 t (1 - t) ^ 2 P_1 + 3 t ^ 2 (1 - t) P_2 + t ^ 3 P_3, t \in [0, 1] \tag7 ]

  4. 高阶曲线
    可以迭代得到四次、五次贝塞尔曲线的公式:
    [B(t) = (1 - t) ^ 4 P_0 + 4 t (1 - t) ^ 3 P_1 + 6 t ^ 2 (1 - t) ^ 2 P_2 + 4 t ^ 3 (1 - t) P_3 + t ^ 4 P_4, t \in [0, 1] \tag8 ]
    [B(t) = (1 - t) ^ 5 P_0 + 5 t (1 - t) ^ 4 P_1 + 10 t ^ 2 ( 1 - t) ^ 3 P_2 + 10 t ^ 3 (1 - t) ^ 2 P_3 + 5 t ^ 4 (1 - t) P_4 + t ^ 5 P_5, t \in [0, 1] \tag9 ]

三、推导

一般化

观察上文中(1)至(5)阶贝塞尔曲线,发现其各项中的常数系数满足组合数规律,故对于(n)阶贝塞尔曲线,给出定点(P_0, P_1, P_2, ..., P_n),其贝塞尔曲线可用下式表示:
[B(t) = \left( \begin{matrix} n \ 0 \end{matrix} \right) (1 - t) ^ n t ^ 0 P_0 + \left( \begin{matrix} n \ 1 \end{matrix} \right) (1 - t) ^ {n - 1} t ^ 1 P_1 + \cdots + \left( \begin{matrix} n \ n - 1 \end{matrix} \right) (1 - t) ^ 1 t ^ {n - 1} P_{n - 1} + \left( \begin{matrix} n \ n \end{matrix} \right) (1 - t) ^ 0 t ^ n P_n, t \in [0, 1] \tag{10} ]
可化简为:
[B(t) = \sum_{i = 0}^\infty \left( \begin{matrix} n \ i \end{matrix} \right) (1 - t) ^ {n - i} t ^ i P_i, t \in [0, 1] \tag{11} ]
式中组合数:
[\left( \begin{matrix} n \ i \end{matrix} \right) = \frac{n !}{i ! \cdot (n - i) !} ]

多项式表达

同时,式((11))也可表示为:
[B(t) = \sum_{i = 0}^\infty b_{i, n}(t) P_i, t \in [0, 1] \tag{12} ]
其中多项式:
[b_{i, n}(t) = \left( \begin{matrix} n \ i \end{matrix} \right) (1 - t) ^ {n - i} t ^ i, i = 0, 1, 2, \cdots, n \tag{13} ]
式((13))被称作(n)阶Bernsteain多项式

Bernsteain多项式
假设开展一个实验,其成功的概率为(u)。若连续进行这个实验(n)次,成功的次数恰好为(i)次,那么其成功概率是多少呢?
能够确定成功概率为:(b_{i, n}(t) = \left( \begin{matrix} n \ i \end{matrix} \right) (1 - t) ^ {n - i} t ^ i, i = 0, 1, 2, \cdots, n)。
这便是Bernsteain多项式。

四、应用(Matlab实现)

实现目标

  1. 能够进行控制点坐标的输入。
  2. 计算贝塞尔曲线。
  3. 绘制贝塞尔曲线及其控制点。

脚本编写

main.m(主函数,调用输入函数、贝塞尔曲线计算函数及绘制贝塞尔曲线)

%% 初始化
clc
clear
%% 输入
n = input("请输入控制点个数:\n");
P = pos_input(n);
%% 调用贝塞尔曲线计算函数
P = P';  % 坐标矩阵转置,便于曲线运算及绘图
[t, p] = bezier_curve(P, n - 1);  % 阶数为控制点个数 - 1
%% 绘制贝塞尔曲线
plot(t, p, '-b');  % 绘制贝塞尔曲线
hold on;
plot(P(1,:), P(2,:), '-ro');  % 绘制控制点
title(sprintf('贝塞尔曲线 (阶数: %d)', n - 1));
xlabel('X');
ylabel('Y');
grid on;
legend('贝塞尔曲线', '控制点');
hold off;

bezier_curve.m(贝塞尔曲线函数,计算n阶贝塞尔曲线)

function [Px, Py] = bezier_curve(control_points, order)
    % 计算贝塞尔曲线上的点
    t = linspace(0, 1, 1000);  % 在[0, 1]范围内生成点
    curve = zeros(2, numel(t));  % 初始化曲线矩阵,numel函数用于获取数组元素的数目
    for i = 0 : order
        curve = curve + nchoosek(order, i) * ((1 - t) .^ (order - i)) .* ...
        (t .^ i) .* control_points(:, i + 1);  % 该计算公式即上文中式(11),nchoosek函数用于计算组合数
    end
    Px = curve(1, :);
    Py = curve(2, :);
end

pos_input.m(输入函数,输入控制点坐标)

function P = pos_input(I)
   % 输入贝塞尔曲线控制点 
    P = ones(I, 2);  % 初始化坐标矩阵 
        for i = 1 : I
            P(i, :) = input("请输入输入坐标点P" + num2str(i - 1) + "(以一维矩阵形式输入): \n");
        end
end

图像结果

六阶贝塞尔曲线

十四阶贝塞尔曲线

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号