声明:本学习笔记使用基于GNU TeXmacs的专业编辑工具和python环境实现,内容来自于网络整理学习,内嵌代码由AI辅助并手动调试通过,尽管为了上传做了手动处理,奈何兼容性欠佳,无法实现原开发环境浏览效果。
1. 伯恩斯坦基函数
1.1 数学定义
伯恩斯坦基函数是贝塞尔曲线的数学基础。对于非负整数 n 和整数 i(0≤i≤n),第 i 个 n 次伯恩斯坦基函数定义为:
Bi,n(t)=ti(1-t)n-i
其中:
-
阶数(degree) n:曲线次数
-
索引(index) i:基函数编号
-
参数(parameter) t:取值范围 [0,1]
-
二项式系数(binomial coefficient) =n!i!(n-i)!
1.2 公式推导
伯恩斯坦基函数由二项式定理推导而来。二项式定理指出:
(a+b)n=∑i=0naibn-i
令 a=t,b=1-t,则:
1=(t+(1-t))n=∑i=0nti(1-t)n-i
这正是伯恩斯坦基函数的和,表明它们是单位分割的基函数。
伯恩斯坦基函数还具有递推关系:
Bi,n(t)=(1-t)Bi,n-1(t)+tBi-1,n-1(t)
1.3 代码实现
|
>>> |
import numpy as np |
|
>>> |
def bernstein_basis_numeric(n, i, t): |
|
>>> |
def plot_bernstein_polynomials(): # 创建图形 for i in range(n+1): # 绘制图形 # 设置图形属性 # 验证单位分割性质 fig.suptitle(f'{n}次伯恩斯坦基函数', fontsize=16, fontweight='bold') |
1.4 结果输出
|
>>> |
# 执行绘图 |

图1:4次伯恩斯坦基函数。每个基函数在 [0,1] 区间上非负,且所有基函数的和为1,满足单位分割性质。
2. 标准(多项式)贝塞尔曲线
2.1 数学定义
给定 n+1 个控制点 P0,P1,…,Pn∈ℝd(通常 d=2 或 3),n 次标准贝塞尔曲线定义为:
C(t)=∑i=0nBi,n(t)Pi=∑i=0nti(1-t)n-iPi
其中 t∈[0,1]。
2.2 公式推导
2.2.1 从线性插值推导(德卡斯特里奥算法)
德卡斯特里奥算法提供了一种递归计算贝塞尔曲线点的方法:
对于 t∈[0,1],在线段 PiPi+1 上取点 Pi1(t)=(1-t)Pi+tPi+1
在线段 Pi1Pi+11 上取点 Pi2(t)=(1-t)Pi1+tPi+11
重复此过程 n 次,得到 P0n(t),即曲线上的点 C(t)
2.2.2 从二项式定理推导
利用二项式定理 (a+b)n=∑i=0naibn-i,令 a=t,b=1-t,得到:
1=(t+(1-t))n=∑i=0nti(1-t)n-i
每个控制点乘以相应的伯恩斯坦基函数,得到曲线方程。
2.3 数学性质
2.3.1 端点性质
端点插值:
C(0)=P0,C(1)=Pn
曲线始终通过第一个和最后一个控制点。
端点切线:
C'(0)=n(P1-P0),C'(1)=n(Pn-Pn-1)
曲线在端点的切线方向由相邻控制点决定。
端点曲率:
C''(0)=n(n-1)(P2-2P1+P0)
曲线在端点的曲率由前三个控制点决定。
2.3.2 凸包性质
凸包是包含所有点的最小凸多边形。对于任意 t∈[0,1],C(t) 位于控制点的凸包内。
证明:由于伯恩斯坦基函数非负且和为1,C(t) 是控制点的凸组合。
2.3.3 仿射不变性
对于任何仿射变换 T:
T(∑i=0nBi,n(t)Pi)=∑i=0nBi,n(t)T(Pi)
2.3.4 变差缩减性
任何直线与贝塞尔曲线的交点数不超过该直线与控制多边形的交点数。
2.4 代码实现
|
>>> |
def compute_bezier_curve(control_points, t_values=None): 参数: 返回: if t_values is None: curve_points = np.zeros((len(t_values), control_points.shape[1])) for i, t in enumerate(t_values): return curve_points |
|
>>> |
def de_casteljau_algorithm(control_points, t): 参数: 返回: for r in range(1, n+1): return points[0] |
|
>>> |
def plot_bezier_curve_example(): titles = ['二次贝塞尔曲线 (n=2)', '三次贝塞尔曲线 (n=3)', '四次贝塞尔曲线 (n=4)'] # 创建图形 for idx, (control_points, title) in enumerate(zip(control_points_list, titles)): # 计算曲线点 # 绘制控制多边形 # 绘制控制点标签 # 绘制贝塞尔曲线 # 使用德卡斯特里奥算法计算曲线上的点 ax.set_title(title, fontsize=14, fontweight='bold') fig.suptitle('标准贝塞尔曲线示例', fontsize=16, fontweight='bold') |
2.5 结果输出
|
>>> |
# 执行绘图 |

537 msec
图2:不同阶数的标准贝塞尔曲线。从左到右:二次、三次、四次贝塞尔曲线。曲线始终位于控制多边形形成的凸包内。
3. 有理贝塞尔曲线
3.1 数学定义
有理贝塞尔曲线是标准贝塞尔曲线的推广,每个控制点 Pi 关联一个权重 wi>0。n 次有理贝塞尔曲线定义为:
R(t)=∑i=0nwiBi,n(t)Pi∑i=0nwiBi,n(t)=∑i=0nRi,n(t)Pi
其中有理伯恩斯坦基函数:
Ri,n(t)=wiBi,n(t)∑j=0nwjBj,n(t)
3.2 公式推导
有理贝塞尔曲线可以通过齐次坐标推导。在齐次坐标中,每个控制点表示为 P∼i=(wixi,wiyi,wizi,wi)。曲线在齐次坐标下为:
R∼(t)=∑i=0nBi,n(t)P∼i
通过透视除法得到欧几里得坐标:
R(t)=(x∼(t)w∼(t),y∼(t)w∼(t),z∼(t)w∼(t))
当所有权重相等时,有理贝塞尔曲线退化为标准贝塞尔曲线。
3.3 数学性质
投影不变性:在投影变换下保持不变
端点插值:R(0)=P0,R(1)=Pn(假设 w0,wn>0)
凸包性:曲线位于控制点的凸包内
权重影响:wi 增大时,曲线被拉向控制点 Pi
精确表示圆锥曲线:可以精确表示圆、椭圆、抛物线、双曲线
3.4 代码实现
|
>>> |
def compute_rational_bezier_curve(control_points, weights, t_values=None): 参数: 返回: if t_values is None: curve_points = np.zeros((len(t_values), control_points.shape[1])) for i, t in enumerate(t_values): for j in range(n+1): if denominator != 0: return curve_points |
|
>>> |
def plot_rational_bezier_comparison(): # 定义权重配置 # 创建图形 for idx, config in enumerate(weight_configs): # 计算曲线 # 绘制控制多边形 # 绘制控制点(大小表示权重) # 绘制曲线 ax.set_title(config['label'], fontsize=12, fontweight='bold') fig.suptitle('有理贝塞尔曲线与标准贝塞尔曲线比较', fontsize=16, fontweight='bold') |
|
>>> |
def plot_rational_bezier_circle(): |
3.5 结果输出
|
>>> |
# 执行绘图 |

681 msec
图3:不同权重配置的有理贝塞尔曲线。权重越大,曲线越接近对应控制点。
|
>>> |
# 执行绘图 |

299 msec
图4:有理贝塞尔曲线可以精确表示圆弧,而标准贝塞尔曲线只能近似表示。
4. 连续性分析
4.1 数学定义
4.1.1 参数连续性 (Ck 连续)
C连续性关注的是参数域上的导数是否连续,即曲线在参数空间中的变化是否平滑。
-
C连续性是严格的数学定义,要求参数化的导数完全匹配。
-
适用于需要严格控制参数化行为的场景(如动画路径规划、机器人轨迹设计等)。
对于两条贝塞尔曲线:
-
曲线1:C1(t)=∑i=0nBi,n(t)Pi,t∈[0,1]
-
曲线2:C2(t)=∑i=0mBi,m(t)Qi,t∈[0,1]
C0 连续(位置连续):
C1(1)=C2(0)⇒Pn=Q0
C1 连续(切线连续):
-
Pn=Q0(位置连续)
-
C1'(1)=C2'(0)⇒n(Pn-Pn-1)=m(Q1-Q0)
C2 连续(曲率连续):
-
C1 连续条件
-
C1''(1)=C2''(0)
4.1.2 几何连续性 (Gk 连续)
G连续性关注的是几何形状上的光滑程度,不要求参数化导数完全一致,只需几何特性(如切线方向、曲率)连续即可。
-
G连续性是几何意义上的定义,更注重视觉上的平滑效果。
-
适用于对参数化不敏感的场景(如工业设计、字体设计等)。
G1 连续(切线方向连续):
-
C1(1)=C2(0)
-
C1'(1) 与 C2'(0) 方向相同(大小可不同)
G2 连续(曲率连续):
-
G1 连续
-
曲率在连接点处连续
4.2 公式推导
4.2.1 导数公式
贝塞尔曲线的导数:
一阶导数:
C'(t)=n∑i=0n-1Bi,n-1(t)(Pi+1-Pi)
二阶导数:
C''(t)=n(n-1)∑i=0n-2Bi,n-2(t)(Pi+2-2Pi+1+Pi)
4.2.2 曲率公式
对于平面曲线 C(t)=(x(t),y(t)),曲率为:
κ(t)=|x'(t)y''(t)-y'(t)x''(t)|[x'(t)2+y'(t)2]3/2
4.3 代码实现
|
>>> |
def compute_bezier_derivative(control_points, t, order=1): 参数: 返回: if order == 0: if n < order: # 计算导数控制点 # 使用德卡斯特里奥算法计算导数值 |
52 msec
|
>>> |
def compute_curvature(control_points, t): 参数: 返回: x1, y1 = deriv1[0], deriv1[1] # 计算曲率 return numerator / denominator if denominator != 0 else 0 |
36 msec
|
>>> |
def analyze_continuity(curve1_points, curve2_points): |
|
>>> |
def plot_continuity_examples(): # 示例2:G1连续 # 示例3:C1连续 # 示例4:C2连续 # 创建图形 examples = [ for curve1, curve2, title, ax in examples: # 绘制控制多边形 # 绘制曲线 # 标记连接点 ax.set_title(title, fontsize=12, fontweight='bold') fig.suptitle('贝塞尔曲线连续性示例', fontsize=16, fontweight='bold') |
4.4 结果输出
|
>>> |
# 执行连续性分析 fig_examples = plot_continuity_examples() |

651 msec
图5:贝塞尔曲线连续性分析。显示了曲线拼接、曲率变化、导数大小和连续性判断结果。
|
>>> |
fig_examples = plot_continuity_examples() |

557 msec
图6:不同连续性级别的贝塞尔曲线拼接示例。
5. 曲线性质分析
5.1 凸包性证明
5.1.1 数学证明
凸包性证明基于伯恩斯坦基函数的性质:
非负性:Bi,n(t)≥0,对 t∈[0,1]
单位分割:∑i=0nBi,n(t)=1
因此,对于任意 t∈[0,1]:
C(t)=∑i=0nBi,n(t)Pi
是控制点 Pi 的凸组合,故 C(t) 位于控制点的凸包内。
5.2 变差缩减性
5.2.1 数学定义
对于任何直线 L,设 NC 为 L 与贝塞尔曲线 C 的交点数,NP 为 L 与控制多边形 P 的交点数,则:
NC≤NP
5.3 代码实现
|
>>> |
def line_intersection(p1, p2, line_slope, line_intercept): |
28 msec
|
>>> |
def point_in_hull(point, hull_points): |
28 msec
|
>>> |
def verify_convex_hull(control_points): |
92 msec
|
>>> |
def analyze_endpoint_properties(control_points): |
5.4 结果输出
|
>>> |
# 执行性质验证 |

474 msec
图7:贝塞尔曲线的凸包性和变差缩减性验证。左图显示曲线位于控制点的凸包内,右图验证变差缩减性。
|
>>> |
fig_endpoints = analyze_endpoint_properties(control_points) |

222 msec
图8:贝塞尔曲线端点性质验证。显示了端点插值、端点切线和端点曲率性质。
6. 应用案例
6.1 图形设计
使用标准贝塞尔曲线,计算简单
|
>>> |
def bezier_application_graphics_design(): # 左上:简单形状 – 心形 for points in heart_points: ax.set_xlim(-1.5, 1.5) # 右上:Logo设计 – 波浪 for points in wave_points: ax.set_xlim(-0.2, 3.2) # 左下:装饰图案 – 花瓣 # 旋转创建多个花瓣 for points in petal_points: ax.set_xlim(-1.2, 1.2) # 右下:图标设计 – 云朵 for points in cloud_points: ax.fill_between([-0.2, 1.5], -0.2, -0.2, color='lightblue', alpha=0.3) fig.suptitle('图形设计应用:标准贝塞尔曲线', fontsize=16, fontweight='bold') |
|
>>> |
# 执行图形设计案例 |

6.2 字体设计
使用有理贝塞尔曲线精确表示圆弧
|
>>> |
def bezier_application_font_design(): |
|
>>> |
# 执行字体设计案例 |

6.3 动画路径
C¹/G¹连续性确保运动平滑
|
>>> |
def cubic_bezier(p0, p1, p2, p3, t): |
|
>>> |
def compute_c1_continuity_control_points(prev_curve, next_p2, next_p3): # C¹连续条件 return np.array([Q0, Q1, Q2, Q3]) |
|
>>> |
def generate_smooth_animation_path(key_points, continuity_type='C1'): # 为每个关键点生成初始控制点 # 第一段的控制点 # 中间段的控制点 tangent = (next – prev) / 2 P2 = curr – tangent / 3 control_sets[-1].extend([P2, P3]) # 最后一段的控制点 # 构建曲线 curve_points = compute_c1_continuity_control_points(prev_curve, next_p2, next_p3) curves.append(curve_points) return curves |
|
>>> |
def bezier_application_animation_path(): # 创建演示图形(静态展示) # 定义关键点 # 左上:C¹连续性路径 # 绘制C¹路径 # 绘制控制多边形 # 标记控制点 # 标记关键点 # 标记连接点处的C¹连续性 # 绘制切线向量 ax.set_title('C¹连续性动画路径', fontsize=12, fontweight='bold') # 右上:G¹连续性路径 # 绘制G¹路径 # 绘制控制多边形 # 标记关键点 ax.set_title('G¹连续性动画路径', fontsize=12, fontweight='bold') # 中图:差异值曲线 for i in range(len(c1_curves)): c1_points = np.vstack(c1_points) ax3.plot(x_coords, y_diff, 'g-', linewidth=2) # 左下:连续性条件对比 # 显示连续性条件 text += "G¹连续性条件:\\n" text += "动画应用建议:\\n" ax.text(0.1, 0.5, text, fontsize=11, verticalalignment='center', # 右下:应用场景 # 显示应用场景 text += "2. UI动画:\\n" text += "3. 数据可视化:\\n" text += "4. 影视特效:\\n" ax.text(0.1, 0.5, text, fontsize=11, verticalalignment='center', # 中下:差异值原因解释 # 显示差异值原因解释 text += "2. 差异最大值:\\n" text += "3. 实际影响:\\n" ax.text(0.1, 0.5, text, fontsize=11, verticalalignment='center', fig.suptitle('动画路径应用:C¹/G¹连续性确保运动平滑', fontsize=16, fontweight='bold') return fig |
|
>>> |
# 执行动画路径案例 |

6.4 CAD/CAM
有理贝塞尔曲线保持投影不变性
引申阅读:
投影不变性(Projection Invariance)是计算机图形学和几何建模中的一个重要概念,尤其在 CAD/CAM 和计算机视觉领域中具有重要意义。它的核心思想是:某些几何属性或关系在经过投影变换后仍然保持不变。
投影不变性的定义
在数学和几何中,投影变换是一种将三维空间中的点映射到二维平面的操作(例如透视投影或平行投影)。投影不变性指的是:
某些几何特性(如点、线、曲线的拓扑结构、交比等)在投影变换前后保持一致。
换句话说,无论从哪个角度观察物体,这些特性都不会改变。
投影不变性的具体表现
1. 点的投影不变性
-
一个点在三维空间中的位置经过投影变换后,仍然是一个点。
-
例如:三维空间中的点 P(x,y,z) 经过透视投影后变成二维平面上的点 P'(x',y'),但其“点”的本质不变。
2. 直线的投影不变性
-
三维空间中的一条直线经过投影变换后,在二维平面上仍然是直线。
-
例如:一条直线在不同视角下的投影始终是一条直线,不会变成曲线。
3. 曲线的投影不变性
-
特殊类型的曲线(如有理贝塞尔曲线)在投影变换后仍能保持其形状特征。
-
例如:圆锥曲线(椭圆、抛物线、双曲线)经过投影后可能变形,但它们仍然是圆锥曲线族的一员。
4. 交比的投影不变性
-
交比(Cross Ratio)是四个共线点之间的一种比例关系,它是投影变换中最基本的不变量。
-
例如:四个点 A,B,C,D 在一条直线上,它们的交比为:
(A,B;C,D)=AC⋅BDAD⋅BC
这个值在任何投影变换下都保持不变。
为什么有理贝塞尔曲线具有投影不变性?
有理贝塞尔曲线(Rational Bézier Curve)之所以具有投影不变性,是因为它引入了权重因子,使得曲线在齐次坐标系中表示。以下是关键原因:
1. 齐次坐标表示
-
有理贝塞尔曲线使用齐次坐标 (x,y,w) 表示点,其中 w 是权重。
-
投影变换本质上是对齐次坐标的线性变换,因此有理贝塞尔曲线的形式在投影后依然成立。
2. 权重的作用
-
权重允许曲线更灵活地逼近复杂的几何形状(如圆弧、椭圆等)。
-
在投影过程中,权重会随着坐标一起变换,但曲线的整体形状特性得以保留。
3. 数学推导
设有理贝塞尔曲线的控制点为 Pi=(xi,yi,wi),则曲线方程为:
C(t)=∑i=0nwiBi,n(t)Pi∑i=0nwiBi,n(t)
当对该曲线进行投影变换时,分子和分母都会受到相同的线性变换影响,因此曲线的比例关系保持不变。
实际应用场景
1. CAD/CAM 设计
-
在三维建模中,设计师经常需要将三维模型投影到二维图纸上进行查看或加工。
-
有理贝塞尔曲线的投影不变性保证了设计意图在不同视角下的一致性。
2. 计算机视觉
-
在摄像机成像中,三维场景通过透视投影映射到二维图像。
-
投影不变性帮助识别和重建三维结构。
3. 动画与渲染
-
在三维动画制作中,物体的运动轨迹需要在不同视角下看起来自然。
-
有理贝塞尔曲线可以确保动画路径在投影后仍然平滑。
示例说明
假设我们有一个三维椭圆弧,用有理贝塞尔曲线表示。当我们从不同角度观察这个椭圆时:
-
椭圆可能会被压扁或拉伸,但它仍然是一个椭圆。
-
如果换成普通的多项式贝塞尔曲线,椭圆会被扭曲成其他形状(如卵形或不规则曲线)。
这就是有理贝塞尔曲线的优势所在——它能更好地保持几何形状的本质特性。
总结
投影不变性是几何建模中一种重要的数学性质,它确保了某些几何特性在投影变换后依然成立。对于有理贝塞尔曲线而言,这种性质来源于其齐次坐标表示和权重机制,使其在 CAD/CAM、计算机视觉等领域具有广泛的应用价值。
|
>>> |
def compute_rational_bezier_curve_3d(control_points, weights, t_values=None): if t_values is None: curve_points = np.zeros((len(t_values), control_points.shape[1])) for i, t in enumerate(t_values): for j in range(n+1): if denominator != 0: return curve_points |
|
>>> |
def compute_bezier_curve_3d(control_points, t_values=None): if t_values is None: curve_points = np.zeros((len(t_values), control_points.shape[1])) for i, t in enumerate(t_values): return curve_points |
|
>>> |
def apply_perspective_projection(points, camera_pos, focal_length): for point in points: # 透视投影 return np.array(projected_points) |
|
>>> |
def bezier_application_cad_cam(): # 创建图形 # 1. 三维曲线设计 # 定义三维控制点 # 计算三维贝塞尔曲线 # 绘制三维曲线 ax1.set_xlabel('X', fontsize=11) # 2. 有理贝塞尔曲线在CAD中的应用 # 椭圆参数 # 精确椭圆(用于比较) # 使用8段有理贝塞尔曲线拼接椭圆 # 控制点 # 中间控制点 # 权重 # 计算曲线 # 绘制曲线 # 前两段显示控制多边形 ax2.set_xlim(-2.5, 2.5) # 3. 投影不变性演示 # 定义三维曲线 # 标准贝塞尔曲线 # 有理贝塞尔曲线 # 绘制原始曲线 # 应用透视变换 # 投影到2D平面 ax3.set_xlabel('X', fontsize=11) # 4. 投影结果比较 ax4.plot(projected_standard[:, 0], projected_standard[:, 1], ax4.set_xlabel('投影X', fontsize=11) # 5. CAM刀具路径生成 # 定义加工轮廓 # 使用贝塞尔曲线平滑刀具路径 curve_tool = compute_bezier_curve_3d( ax5.plot(curve_tool[:, 0], curve_tool[:, 1], 'g-', linewidth=2, alpha=0.7) # 绘制原始轮廓点 ax5.set_xlabel('X (mm)', fontsize=11) # 6. 工程曲面设计 # 创建曲面控制网格 # 创建控制点网格 # 绘制控制网格 # 绘制控制点 ax6.set_xlabel('X', fontsize=11) fig.suptitle('CAD/CAM应用:' \\ |
|
>>> |
# 执行CAD/CAM案例 |

7. 总结
7.1 标准贝塞尔曲线关键特性
数学基础:基于伯恩斯坦基函数,具有良好的数值稳定性
几何直观:通过控制点直接控制曲线形状
凸包性:曲线始终位于控制点的凸包内
端点插值:曲线通过第一个和最后一个控制点
变差缩减性:曲线波动不超过控制多边形波动
仿射不变性:对控制点的仿射变换等价于对曲线的相同变换
7.2 有理贝塞尔曲线优势
投影不变性:在投影变换下保持不变
权重控制:通过权重参数提供额外控制自由度
精确表示:可以精确表示圆锥曲线
向后兼容:当所有权重相等时,退化为标准贝塞尔曲线
7.3 连续性条件
位置连续(C⁰):Pn=Q0
切线方向连续(G¹):Pn-1,Pn=Q0,Q1 三点共线
切线连续(C¹):n(Pn-Pn-1)=m(Q1-Q0)
曲率连续(G²/C²):需要满足二阶导数条件
网硕互联帮助中心




评论前必须登录!
注册