本节摘要:SOURCE 2.2:参数曲线 C(u)、曲面 S(u,v) 是自由造型的数学骨架;G0/G1/G2 连续性是美学与功能的契约。
自由曲面的本质是"数学定义的表面",其核心是参数化表达。一条曲线写成一个参数函数 C(u),一个曲面写成双参数函数 S(u,v)。参数化带来三个关键优势:
反例是隐式表达(如 x^2+y^2=r^2):求点方便但求切向、拼接麻烦,工业 CAD 因此普遍采用参数化表达。
当多张曲面拼接时,接缝处的光滑程度由连续性等级度量:
| 等级 | 含义 | 工程场景 |
|---|---|---|
| G0 | 位置连续 | 分块拼接 |
| G1 | 切向连续 | 外观过渡 |
| G2 | 曲率连续 | 车身、翼型 |
G2 与 G1 的本质区别:G1 只保证两条曲线在接点处切线同向,但曲率可能突变——高光反射会出现"折线";G2 保证曲率连续,高光过渡平滑,这是汽车 A 级曲面、飞机翼型、高端消费品的硬性要求。
用一维类比理解:G0 是两段道路在路口相接,G1 是转弯时方向不变,G2 是方向盘转动的速率也连续——驾驶体验的差别一眼可感。
| 方法 | 输入 | 输出 | 特点 |
|---|---|---|---|
| 拉伸/旋转 | 草图 + 方向/轴 | 规则曲面 | 最简单,覆盖大部分机械件 |
| 扫掠(Sweep) | 截面 + 路径 | 管道类曲面 | 截面沿路径运动 |
| 放样(Loft) | 多条截面曲线 | 渐变曲面 | 过渡自然,控制复杂 |
| 边界曲面 | 四边/多边轮廓 | 填充曲面 | 补面首选,须注意连续性 |
构造路径:放样(Loft) 过截面曲线;扫掠(Sweep) 沿路径扫 profile;边界曲面 填四边。
以手机外壳为例,它的背板通常由多张曲面拼接而成:中框是拉伸面、四角是变半径圆角面、背板是自由曲面。拼接策略决定质量:
# 曲面拼接质量检查:用曲率连续性评估接缝 def check_continuity(surf_a, surf_b, edge, tol=1e-3): """在公共边采样,比较位置/切向/曲率""" result = {"G0": True, "G1": True, "G2": True} for u in linspace(0, 1, 20): p1, t1, k1 = surf_a.evaluate(edge.u(u)) # 位置、切线、曲率 p2, t2, k2 = surf_b.evaluate(edge.v(u)) if norm(p1 - p2) > tol: # 位置差 result["G0"] = False if angle(t1, t2) > 1e-2: # 切向夹角 result["G1"] = False if abs(k1 - k2) > 0.05 * max(abs(k1), abs(k2)): result["G2"] = False # 曲率差 return result # 检查结果可指导"是否需要在接缝处补一条 G2 桥接曲面" print(check_continuity(back_plate, corner_fillet, seam))
真实 CAD 中的"反射线分析""斑马纹分析"就是这种检查的可视化版本:接缝处的条纹若发生转折,说明连续性不达标。
逆向工程(RE)是曲面建模的重要来源:三维扫描得到点云,再拟合出 NURBS 曲面。这一过程的关键风险是过拟合:
实用策略是分块拟合 + 连续性约束:把点云按曲率特征分区,每区独立拟合,再用 G1/G2 约束拼接,最后用偏差云图(点到曲面距离)验证拟合误差。汽车 A 级曲面要求反射线光滑——这依赖 G2 而非仅 G1。逆向工程从点云拟合 NURBS 时,须控制控制点数量防振荡。
理解 NURBS 之前,先理解它的前身 Bézier 曲线。一条 n 次 Bézier 曲线由 n+1 个控制点定义,最著名的性质是:曲线经过首末控制点,但不经过中间控制点——中间控制点像磁铁一样"吸引"曲线。三次 Bézier(四个控制点)是工程中最常用的形式。
de Casteljau 算法是求取 Bézier 曲线上任意点的经典递推方法:在控制多边形各边上按参数 u 取分点,再连新线取分点,递归直到只剩一个点——那个点就是曲线上的点。
def de_casteljau(pts, u): """给定控制点列表与参数 u,返回曲线上点坐标""" pts = [p for p in pts] # 复制一份,逐层递推 while len(pts) > 1: nxt = [] for i in range(len(pts) - 1): x = (1 - u) * pts[i][0] + u * pts[i + 1][0] y = (1 - u) * pts[i][1] + u * pts[i + 1][1] nxt.append((x, y)) pts = nxt # 每轮少一个点 return pts[0] # 最终点落在曲线上 # 例:四个控制点定义一条流畅的曲线 ctrl = [(0, 0), (1, 3), (3, 3), (4, 0)] for u in [0.0, 0.25, 0.5, 0.75, 1.0]: print(f"u={u}: 曲线点 {de_casteljau(ctrl, u)}")
凸包性质让 Bézier 曲线"不会失控":整条曲线一定落在控制多边形的最小凸包内。这个性质用于求交算法的快速预判——如果两个曲面的控制多边形凸包不相交,曲面就必然不相交,可以直接剪枝,大幅加速布尔运算。
普通 B 样条无法精确表达圆——因为圆是有理曲线。NURBS 通过给每个控制点附加权重 w_i 解决了这个问题:
| 权重 | 效果 | 工程例子 |
|---|---|---|
| w = 1 | 等同普通 B 样条 | 一般自由曲线 |
| w > 1 | 曲线更靠近该控制点 | 逼近尖角/折线 |
| 0 < w < 1 | 曲线远离该控制点 | 圆润过渡 |
| 特殊权重组合 | 精确圆锥曲线 | 圆、椭圆、抛物线 |
权重赋予设计师"局部拉扯"的能力:同一组控制点,只调整一个权重就能把曲线从"饱满"变为"圆润",而不必移动控制点。这正是"有理"二字的含义——用比值(有理数)表达的加权平均。
有了参数曲面 S(u,v),CAD 内核还要回答两个高频问题:面上某点的坐标(求值)与某点的法向(决定光照、加工、装配贴合方向)。求值对 u、v 求偏导得到切向量,叉积即法向量:
def surface_point_and_normal(surf, u, v): # 伪代码:surf.eval_partial 返回点与关于 u/v 的偏导 p, du, dv = surf.eval_partial(u, v) n = cross(du, dv) # 两个切向量叉积 = 法向 return p, normalize(n)
法向的方向在 CAD 中至关重要:B-rep 要求所有面的法向指向实体外侧,装配贴合面要求两个零件的法向相对,渲染光照要求法向连续——法向错误会导致体积计算为负、装配翻转、渲染黑斑。一个"法向反了"的面,是一切下游异常的常见源头。
工程师在 CAD 里评估曲面质量,靠的是三类可视化工具,它们本质都是"连续性的可视化":
| 工具 | 观察什么 | 对应数学 |
|---|---|---|
| 斑马纹 | 条纹是否连续光滑 | G1/G2 连续性 |
| 反射线 | 高光边界是否折转 | 曲率变化率 |
| 高斯曲率云图 | 颜色过渡是否自然 | 主曲率分布 |
车身 A 级曲面、手机外壳、风洞模型,都必须通过这三类检查才能定稿。"看着顺眼"的背后,是 G2 连续的数学保证。
工程上处理大点云的实用流程是"分区治理":
汽车 A 级曲面要求反射线光滑——这依赖 G2 而非仅 G1。逆向工程从点云拟合 NURBS 时,须控制控制点数量防振荡。
每张曲面都有参数化方向(uv 方向),它影响后续一切操作:纹理贴图、加工刀路、有限元网格的排列方向。若两张相邻曲面的 uv 方向不一致,缝合后可能出现扭曲;CAM 加工时刀路方向若与曲面参数方向冲突,可能出现抬刀过多或表面残留。
⚠️ 常见坑:忽视参数化方向导致纹理/加工刀路异常。
💡 关键直觉:曲面质量 = 数学连续 + 物理可制造。