B样条基函数:从数学原理到Python实现

B样条基函数是计算机图形学、CAD系统和科学计算中的核心数学工具,它通过巧妙的递归结构实现了局部支撑性和可控连续性的完美平衡。本文将深入探讨B样条基函数的数学原理,并提供完整的Python实现。

数学理论基础

B样条基函数 Ni,p(u)N_{i,p}(u)Ni,p(u) 由Cox-de Boor递推公式定义,其中 iii 表示基函数索引,ppp 表示阶数,uuu 为参数变量。
在这里插入图片描述

零阶基函数定义

零阶基函数是构建高阶基函数的基础:

Ni,0(u)={ 1若 ui≤u<ui+10否则N_{i,0}(u) = \begin{cases} 1 & \text{若 } u_i \leq u < u_{i+1} \\ 0 & \text{否则} \end{cases}Ni,0(u)={ 10 uiu<ui+1否则

高阶递推公式

对于 p≥1p \geq 1p1,基函数通过递归方式构建:

Ni,p(u)=u−uiui+p−uiNi,p−1(u)+ui+p+1−uui+p+1−ui+1Ni+1,p−1(u)N_{i,p}(u) = \frac{u - u_i}{u_{i+p} - u_i} N_{i,p-1}(u) + \frac{u_{i+p+1} - u}{u_{i+p+1} - u_{i+1}} N_{i+1,p-1}(u)Ni,p(u)=ui+puiuuiNi,p1(u)+ui+p+1ui+1ui+p+1uNi+1,p1(u)

这个递推关系确保了基函数具有局部支撑性,每个 Ni,p(u)N_{i,p}(u)Ni,p(u) 仅在区间 [ui,ui+p+1)[u_i, u_{i+p+1})[ui,ui+p+1) 内非零。

符号推导实现

首先使用Sympy进行符号推导,生成精确的数学表达式:

import sympy as sp
import numpy as np
import matplotlib.pyplot as plt
from sympy import Piecewise, Eq, And

class BSplineSymbolic:
    def __init__(self):
        self.u = sp.symbols('u', real=True)
    
    def basis_zero_order(self, i, knots):
        u_i, u_i1 = knots[i], knots[i+1]
        if u_i == u_i1:
            return 0
        return Piecewise(
            (1, And(u_i <= self.u, self.u < u_i1)),
            (0, True)
        )
    
    def basis_recursive(self, i, p, knots):
        if p == 0:
            return self.basis_zero_order(i, knots)
        
        u_i, u_i_p = knots[i], knots[i+p]
        u_i1, u_i_p1 = knots[i+1], knots[i+p+1]
        
        denom1 = u_i_p - u_i
        term1 = ((self.u - u_i) / denom1 * self.basis_recursive(i, p-1, knots) 
                 if denom1 != 0 else 0)
        
        denom2 = u_i_p1 - u_i1
        term2 = ((u_i_p1 - self.u) / denom2 * self.basis_recursive(i+1, p-1, knots) 
                 if denom2 != 0 else 0)
        
        return term1 + term2
    
    def simplify_basis(self, basis_expr):
        return sp.simplify(basis_expr)
    
    def plot_basis_symbolic(self, basis_expr, u_range=(0, 3), points=1000):
        u_vals = np.linspace(u_range[0], u_range[1], points)
        f = sp.lambdify(self.u, basis_expr, 'numpy')
        y_vals = f(u_vals)
        
        plt.figure(figsize=(10, 6))
        plt.plot(u_vals, y_vals, 'b-', linewidth=2)
        plt.xlabe
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值