两条n次B样条曲线(次数相同),已知分别的控制点和节点矢量,两条曲线G0连续,将合并成一条B样条曲线的方法
要将两条 n 次 B 样条曲线(degree = n)合并为一条新的 n 次 B 样条曲线,前提是它们在连接处满足 G⁰ 连续(即几何位置连续:终点 = 起点),我们可以采用以下策略:
合并思路(保持次数不变)
由于 B 样条的局部支撑性和节点向量结构,直接“拼接”两条独立参数化的曲线无法得到一条单一的 B 样条(除非重新参数化)。
但如果我们 将两条曲线重新定义在同一个参数区间上,并通过 节点插入(knot insertion) 使它们在连接处具有兼容的节点结构,就可以构造一条新的 B 样条。
然而,最实用且广泛使用的方法是:
将两条曲线视为分段定义,通过扩展节点向量和控制点,构造一条新的 B 样条曲线,其参数域覆盖原两条曲线,并在连接处重复 n+1 个节点以形成“拼接点”。
但这会导致曲线在连接处仅为 C⁻¹(不光滑),不过只要控制点首尾重合(G⁰),整体形状是连续的。
更标准的做法是:
方法:统一参数域 + 控制点拼接 + 节点向量拼接(需归一化)
- 假设第一条曲线定义在 [a,b],第二条在 [b,c]。
- 将两条曲线都重参数化到 [0,1] 和 [1,2]。
- 构造新节点向量:
- 对第一条曲线节点 U 映射到 [0,1]
- 对第二条曲线节点 V 映射到 [1,2]
- 合并为 W=[u0′,...,up′,v0′+1,...,vq′+1]
- 新控制点 = P + Q(去掉重复点 Q[0] 如果 P.back() == Q[0])
但注意:B 样条要求节点向量非递减,且首尾各有 n+1 个重复节点(clamped)。
实用简化方案(推荐)
如果两条曲线都是 clamped(首尾节点重复 n+1 次),且 G⁰ 连续(P.back() == Q.front()),那么可以:
- 新控制点:
R = P + Q[1..end] - 新节点向量:将第一条的内部节点保留,第二条节点整体平移,使连接处有 n 个重复节点(实现 C⁰ 拼接)
但严格来说,要保证新曲线精确重现原两条曲线,必须进行 节点插入 使两条曲线在拼接点具有相同的多重度(multiplicity = n),这会增加控制点数量。
更可靠方法:使用 曲线拼接(curve merging) via knot insertion
步骤如下:
- 确保两条曲线都是 clamped(标准形式)。
- 在第一条曲线的末端插入节点,使其末端节点重数为 n(通常已是 n+1,无需操作)。
- 在第二条曲线的起始端同样处理。
- 构造新节点向量:
- 取第一条的节点(去掉最后 n+1 个重复节点中的 n 个?)
- 拼接第二条节点(整体偏移)
- 控制点直接拼接(去掉重复点)
但实现复杂。
最简单可行方案(工程常用)
将两条 clamped B 样条曲线拼接成一条新的 clamped B 样条,通过在连接处引入一个“断点”(knot with multiplicity = n)。
这样:
- 新曲线在 [0,1] 上等于第一条
- 在 [1,2] 上等于第二条(经仿射变换)
- 整体为一条 B 样条
实现步骤:
设 degree = n
- 曲线1:控制点 P[0..m],节点 U[0..m+n+1],通常 U[0..n] = 0, U[m+1..m+n+1] = 1
- 曲线2:控制点 Q[0..k],节点 V[0..k+n+1],V[0..n] = 0, V[k+1..k+n+1] = 1
我们构造新曲线:
- 新控制点 R = P + Q[1..k] (因为 Q[0] == P[m])
- 新节点向量 W 长度 = len(R) + n + 1 = (m+1 + k) + n + 1 = m + k + n + 2
构造 W:
- 前半部分:U[0 .. m+n+1 - (n+1)] = U[0 .. m] (去掉最后 n+1 个 1)
- 中间插入 n 个 1(作为拼接点,multiplicity = n → C⁰)
- 后半部分:V[n+1 .. end] + 1 → 即把 V 的内部和末端节点平移到 [1,2]
