CMOS传输门异或门设计:从原理到版图实战
2026/10/6 5:38:56
首先:贝塞尔曲线 ⊂ B - 样条曲线 ⊂ NURBS 曲线,三者是层层包含、逐步泛化的关系,NURBS 曲线是前两者的通用形式,能够兼容表示贝塞尔曲线和 B - 样条曲线。
逼近样条曲线(Spline)是一组分段光滑、在连接点处满足一定连续性条件(通常是 C¹、C² 连续)的曲线段的集合,最初源于工程绘图中用「样条尺」绘制的光滑曲线,后来被数学建模为参数化曲线,核心目的是用简单的数学表达式拟合复杂的光滑轮廓。
参数化样条曲线的通用形式:
其中:
三种曲线的核心区别就是基函数的类型和约束条件不同。
核心定义:一种无节点(或说节点固定)的参数化多项式曲线,由一组控制顶点P0,P1,…,Pn(n为阶数,通常说的 n 次贝塞尔曲线)定义,基函数为伯恩斯坦多项式(Bernstein Polynomial)。
数学表达式(n 次贝塞尔曲线):
关键约束(局限性):
核心定义:对贝塞尔曲线的泛化,引入节点向量(Knot Vector),基函数为B 样条基函数(由德布尔 - 考克斯递推公式定义),支持分段定义曲线,解决了贝塞尔曲线无局部控制性的问题。
数学表达式:
关键约束(相对于贝塞尔曲线的改进):
贝塞尔曲线 ⊂ B-样条曲线 ⊂ NURBS曲线具体对应关系:
| 曲线类型 | 能否被后续曲线兼容表示 | 兼容条件(核心) |
|---|---|---|
| 贝塞尔曲线 | 能被 B - 样条曲线表示 | 1. 节点向量采用「夹紧节点」(首末节点重复k次);2. 节点数m=n+k(n为贝塞尔控制顶点数 - 1,k为 B 样条阶数 = 贝塞尔阶数) |
| 贝塞尔曲线 | 能被 NURBS 曲线表示 | 满足 B - 样条兼容条件 + 所有权因子wi=1 |
| B - 样条曲线 | 能被 NURBS 曲线表示 | 所有权因子wi=1(有理部分退化为 1,即为普通 B - 样条) |
geomdl是专门用于几何建模(曲线、曲面)的 Python 库,完美支持贝塞尔、B - 样条、NURBS 曲线的定义和转换,先安装:
pipinstallgeomdlfromgeomdlimportBSpline,NURBS,Bezierfromgeomdlimportutilitiesfromgeomdl.visualizationimportVisMPL# =============================================# 示例1:定义贝塞尔曲线(3次,4个控制顶点)# =============================================print("=== 步骤1:定义3次贝塞尔曲线 ===")bezier_curve=Bezier.Curve()# 设置阶数(3次,对应4个控制顶点)bezier_curve.degree=3# 设置控制顶点(二维平面点,可改为三维)control_points_bezier=[(0.0,0.0),# P0(1.0,3.0),# P1(3.0,4.0),# P2(5.0,2.0)# P3]bezier_curve.ctrlpts=control_points_bezier# 自动生成参数区间(贝塞尔默认[0,1])bezier_curve.knotvector=utilities.generate_knot_vector(bezier_curve.degree,len(bezier_curve.ctrlpts))# 采样曲线点(用于可视化,增加采样数使曲线更光滑)bezier_curve.sample_size=100# =============================================# 示例2:贝塞尔曲线 → B-样条曲线(按转换规则)# =============================================print("\n=== 步骤2:贝塞尔曲线转换为B-样条曲线 ===")bspline_curve=BSpline.Curve()# 1. 复用贝塞尔的阶数bspline_curve.degree=bezier_curve.degree# 2. 复用贝塞尔的控制顶点bspline_curve.ctrlpts=bezier_curve.ctrlpts# 3. 构造夹紧节点向量(与贝塞尔的knotvector一致,geomdl已自动支持)bspline_curve.knotvector=bezier_curve.knotvector# 采样曲线点bspline_curve.sample_size=100# =============================================# 示例3:B-样条曲线 → NURBS曲线(按转换规则)# =============================================print("\n=== 步骤3:B-样条曲线转换为NURBS曲线 ===")nurbs_curve=NURBS.Curve()# 1. 复用B-样条的阶数nurbs_curve.degree=bspline_curve.degree# 2. 复用B-样条的控制顶点nurbs_curve.ctrlpts=bspline_curve.ctrlpts# 3. 复用B-样条的节点向量nurbs_curve.knotvector=bspline_curve.knotvector# 4. 分配权因子w_i=1(所有控制顶点权值为1)nurbs_curve.weights=[1.0for_inrange(len(nurbs_curve.ctrlpts))]# 采样曲线点nurbs_curve.sample_size=100# =============================================# 示例4:验证三者的一致性(输出关键信息)# =============================================print("\n=== 步骤4:验证三者的核心参数一致性 ===")print(f"贝塞尔曲线阶数:{bezier_curve.degree}")print(f"B-样条曲线阶数:{bspline_curve.degree}")print(f"NURBS曲线阶数:{nurbs_curve.degree}")print(f"贝塞尔控制顶点数:{len(bezier_curve.ctrlpts)}")print(f"B-样条控制顶点数:{len(bspline_curve.ctrlpts)}")print(f"NURBS控制顶点数:{len(nurbs_curve.ctrlpts)}")print(f"贝塞尔节点向量:{bezier_curve.knotvector}")print(f"B-样条节点向量:{bspline_curve.knotvector}")print(f"NURBS节点向量:{nurbs_curve.knotvector}")print(f"NURBS权因子:{nurbs_curve.weights}")# =============================================# 示例5:可视化三条曲线(重合,验证转换正确性)# =============================================print("\n=== 步骤5:可视化三条曲线(将弹出绘图窗口) ===")# 合并三条曲线用于批量可视化fromgeomdlimportMultiCurve multi_curve=MultiCurve()multi_curve.add(bezier_curve)multi_curve.add(bspline_curve)multi_curve.add(nurbs_curve)# 设置可视化样式multi_curve.vis=VisMPL.VisCurve2D()multi_curve.render()# =============================================# 示例6:NURBS曲线的扩展(修改权因子,体现其优势)# =============================================print("\n=== 步骤6:修改NURBS权因子,展示其灵活性 ===")# 复制原NURBS曲线,修改第二个控制顶点的权因子nurbs_curve_modified=NURBS.Curve()nurbs_curve_modified.degree=nurbs_curve.degree nurbs_curve_modified.ctrlpts=nurbs_curve.ctrlpts nurbs_curve_modified.knotvector=nurbs_curve.knotvector# 修改第二个控制顶点的权因子为5.0(其余保持1.0)nurbs_curve_modified.weights=[1.0,5.0,1.0,1.0]nurbs_curve_modified.sample_size=100# 可视化修改后的NURBS曲线(与原曲线对比)multi_curve_modified=MultiCurve()multi_curve_modified.add(nurbs_curve)multi_curve_modified.add(nurbs_curve_modified)multi_curve_modified.vis=VisMPL.VisCurve2D()multi_curve_modified.render()