德布尔方法构造三次NURBS曲线

德布尔方法构造三次NURBS曲线
几何画板及绘图内容加载中,请稍等……
2020-01-01 22:24
① 本范例演示了如何利用德布尔(de Boor)递推算法构造一条三次非均匀有理B样条(NURBS)曲线,并展示其控制点、权重及曲线形状。② 核心数学概念包括NURBS曲线、B样条基函数、德布尔算法、控制点与权重、参数化曲线。③ 作图要点:从构造摘要可见,使用了Join、Sequence、Element、Min、PolyLine、Zip、Translate、If、Segment、Text等GeoGebra命令,定义了多个控制点P0至P9及对应权重w0至w9,并设置参数t0及中间点d1至d10,通过递推生成曲线上的点,最终绘制出三次NURBS曲线。④ 适合大学本科计算机辅助几何设计、数值分析或数学建模课程,也可用于高中进阶数学中理解参数曲线与样条思想。

GeoGebra 命令及参数

  1. First({P_{0}, P_{1}, P_{2}, P_{3}, P_{4}, P_{5}, P_{6}, P_{7}, P_{8}, P_{9}}, n + 1) → P
  2. First({w_{0}, w_{1}, w_{2}, w_{3}, w_{4}, w_{5}, w_{6}, w_{7}, w_{8}, w_{9}}, n + 1) → weights
  3. First({d_{1}, d_{2}, d_{3}, d_{4}, d_{5}, d_{6}, d_{7}, d_{8}, d_{9}, d_{10}, d_{11}, d_{12}, d_{13}, d_{14}, d_{15}}, m) → Δknots_{input}
  4. Join({Sequence[0, j, 1, k - 1], If[Sum[Take[Δknots_{input}, k, m + 1 - k]] > 0, Take[Δknots_{input}, k, m + 1 - k], Join[{If[m - k ≥ k, Take[Δknots_{input}, k, m - k], {}], {1}}]], Sequence[0, j, 1, k - 1]}) → Δknots_{tidyends}
  5. Sequence(Sum[First[Join[{{t_{0}}, Δknots_{tidyends}}], i]], i, 1, 1 + m) → knots
  6. Element(knots, 1) → knot_0
  7. Element(knots, 1 + m) → knot_m
  8. Sequence(Dilate[Element[P, 1 + i], Element[weights, 1 + i], Azathoth], i, 0, n) → P_w
  9. Sequence(KDpos + KDioffset + (0, (i * KDiystep_i) + ((tri(k) - tri(k - i) - i) * KDiystep_j)), i, 0, k - 1) → KDibases
  10. Sequence(KDpos + KDuoffset + (0, KDublossomheight + (i * KDuystep_i) + ((tri(k) - tri(k - i) - i) * KDuystep_j)), i, 0, k - 1) → KDubases
  11. Min(m - k, Length[KeepIf[x ≤ u, knots]] - 1) → Ki_u
  12. Sequence(Sequence[(u - Element[knots, 1 + Ki_0 + i + j]) / (Element[knots, 1 + Ki_0 + j + k] - Element[knots, 1 + Ki_0 + i + j]), j, 0, k - 1 - i], i, 0, k - 1) → Kublossom
  13. Sequence(Sequence[KDirulerbase + ((KDiscale * i), (KDirulerticklength * j)), j, 0, 1], i, k - 1, m + 1 - k) → KDirulervertices
  14. PolyLine(Zip[Element[Element[KDirulervertices, Element[a, 1]], Element[a, 2]], a, {{1, 2}, {1, 1}, {Length[KDirulervertices], 1}, {Length[KDirulervertices], 2}}]) → KDirulermain
  15. Zip(Segment[Element[a, 1], Element[a, 2]], a, Sequence[Element[KDirulervertices, i], i, 2, Length[KDirulervertices] - 1]) → KDirulerinnerticks
  16. Sequence(Sequence[Element[KDibases, 1 + i] + ((KDiscale * (Ki_0 + i + j)), (KDiystep_j * j)), j, 0, k - 1 - i], i, 0, k - 1) → KDi_a
  17. Sequence(Sequence[Element[KDibases, 1 + i] + ((KDiscale * (Ki_0 + j + k)), (KDiystep_j * j)), j, 0, k - 1 - i], i, 0, k - 1) → KDi_b
  18. Zip(Zip[Segment[aj, bj], aj, ai, bj, bi], ai, KDi_a, bi, KDi_b) → KDis_{ab}
  19. Sequence(Translate[PolyLine[KDuoffset + ((KDiuscale * (Element[knots, 1 + i] - knot_0)), KDublossomheight + KDtticklength), KDuoffset + ((KDiuscale * (Element[knots, 1 + i] - knot_0)), (-KDtticklength)), KDaoffset + ((KDiscale * i), KDaheight + (KDiufantickheight * KDiufanheight)), KDaoffset + ((KDiscale * i), KDaheight)], KDpos], i, 0, m) → KDiufan
  20. Sequence(Sequence[Element[KDubases, 1 + i] + ((KDiuscale * (Element[knots, 1 + Ki_0 + i + j] - knot_0)), (KDuystep_j * j)), j, 0, k - 1 - i], i, 0, k - 1) → KDu_a
  21. Sequence(Sequence[Element[KDubases, 1 + i] + ((KDiuscale * (Element[knots, 1 + Ki_0 + j + k] - knot_0)), (KDuystep_j * j)), j, 0, k - 1 - i], i, 0, k - 1) → KDu_b
  22. PolyLine(KDpos + KDaoffset + ((-0.5 * KDiscale), 0) + {(0, 0), (0, KDaheight), (((m + 1) * KDiscale), KDaheight), (((m + 1) * KDiscale), 0), (0, 0)}) → KDabox
  23. Zip(Segment[a, a + (0, KDaheight)], a, Sequence[KDpos + KDaoffset + ((KDiscale * (i + 0.5)), 0), i, 0, m - 1]) → KDaboxdividers
  24. Sequence(Text[Element[knots, 1 + i], KDpos + KDaoffset + (-0.15, (0.35 * KDaheight)) + ((KDiscale * i), 0)], i, 0, m) → KDatext
  25. Translate(PolyLine[KDuoffset + ((KDiuscale * (u - knot_0)), KDublossomheight + KDuticklength), KDuoffset + ((KDiuscale * (u - knot_0)), (-KDtticklength)), KDaoffset + ((KDiscale * (Ki_u + Element[Element[Kublossom, Length[Kublossom]], 1])), KDaheight + (KDiufantickheight * KDiufanheight)), KDaoffset + ((KDiscale * (Ki_u + Element[Element[Kublossom, Length[Kublossom]], 1])), KDaheight + ((0.1 * KDiufantickheight) * KDiufanheight))], KDpos) → KDucrank
  26. Sequence(Segment[Element[P, 1 + i], Element[P_w, 1 + i]], i, 0, n) → wlines
  27. PolyLine(P) → cp
  28. PolyLine(P_w) → cp_{w,full}
  29. Zip(Segment[Element[P_w, 1 + a], Element[P_w, 1 + a + 1]], a, KeepIf[x ≥ 0, Sequence[If[Sum[abs(Take[weights - 1, 1 + i, 1 + i + 1])] > 0, i, -1], i, 0, n - 1]]) → cp_{w,selective}
  30. Zip(Zip[aj + ((bj - aj) * uj), aj, ai, bj, bi, uj, ui], ai, KDi_a, bi, KDi_b, ui, Kublossom) → KDi_m
  31. Zip(Zip[aj + ((bj - aj) * uj), aj, ai, bj, bi, uj, ui], ai, KDu_a, bi, KDu_b, ui, Kublossom) → KDu_m
  32. Zip(Zip[Segment[aj, bj], aj, ai, bj, bi], ai, KDu_a, bi, KDu_m) → KDus_{am}
  33. Zip(Zip[Segment[aj, bj], aj, ai, bj, bi], ai, KDu_b, bi, KDu_m) → KDus_{bm}
  34. First(KDu_m, k) → KDu_{m,sansfinal}
  35. Element(KDu_m, k) → KDu_{m,final}
  36. Sequence({x(Element[P_w, 1 + Ki_0 + j]), y(Element[P_w, 1 + Ki_0 + j]), Element[weights, 1 + Ki_0 + j]}, j, 0, k) → Lerp_{h,0}
  37. Sequence(Element[Lerp_{h,0}, 1 + j] + ((Element[Lerp_{h,0}, 1 + j + 1] - Element[Lerp_{h,0}, 1 + j]) * Element[Element[Kublossom, 1], 1 + j]), j, 0, k - 1) → Lerp_{h,1}
  38. Sequence(Element[Lerp_{h,1}, 1 + j] + ((Element[Lerp_{h,1}, 1 + j + 1] - Element[Lerp_{h,1}, 1 + j]) * Element[Element[Kublossom, 2], 1 + j]), j, 0, k - 2) → Lerp_{h,2}
  39. Sequence(Element[Lerp_{h,2}, 1 + j] + ((Element[Lerp_{h,2}, 1 + j + 1] - Element[Lerp_{h,2}, 1 + j]) * Element[Element[Kublossom, 3], 1 + j]), j, 0, k - 3) → Lerp_{h,3}
  40. Sequence(Element[Lerp_{h,3}, 1 + j] + ((Element[Lerp_{h,3}, 1 + j + 1] - Element[Lerp_{h,3}, 1 + j]) * Element[Element[Kublossom, 4], 1 + j]), j, 0, k - 4) → Lerp_{h,4}
  41. Sequence(Element[Lerp_{h,4}, 1 + j] + ((Element[Lerp_{h,4}, 1 + j + 1] - Element[Lerp_{h,4}, 1 + j]) * Element[Element[Kublossom, 5], 1 + j]), j, 0, k - 5) → Lerp_{h,5}
  42. Sequence(Element[Lerp_{h,5}, 1 + j] + ((Element[Lerp_{h,5}, 1 + j + 1] - Element[Lerp_{h,5}, 1 + j]) * Element[Element[Kublossom, 6], 1 + j]), j, 0, k - 6) → Lerp_{h,6}
  43. Sequence(Element[Lerp_{h,6}, 1 + j] + ((Element[Lerp_{h,6}, 1 + j + 1] - Element[Lerp_{h,6}, 1 + j]) * Element[Element[Kublossom, 7], 1 + j]), j, 0, k - 7) → Lerp_{h,7}
  44. First({Lerp_{h,0}, Lerp_{h,1}, Lerp_{h,2}, Lerp_{h,3}, Lerp_{h,4}, Lerp_{h,5}, Lerp_{h,6}, Lerp_{h,7}}, k + 1) → Blossom_h
  45. Sequence(PointList[Sequence[First[Element[Element[Blossom_h, 1 + i], 1 + j], 2], j, 0, k - i]], i, 0, k) → Lerp_w
  46. First(Lerp_w, k) → Lerp_{w,sansfinal}
  47. Sequence(Sequence[Segment[Element[Element[Lerp_w, 1 + i], 1 + j], Element[Element[Lerp_w, 1 + i + 1], 1 + j]], j, 0, k - 1 - i], i, 0, k - 1) → Lerpspan_{am}
  48. Sequence(Sequence[Segment[Element[Element[Lerp_w, 1 + i], 1 + j + 1], Element[Element[Lerp_w, 1 + i + 1], 1 + j]], j, 0, k - 1 - i], i, 0, k - 1) → Lerpspan_{bm}
  49. Element(Element[Blossom_h, 1 + k], 1) → C_h
  50. If(Element[C_h, 3] ≠ 0, Dilate[C_w, 1 / Element[C_h, 3], Azathoth], C_w) → C
  51. Segment(Azathoth, If[Element[C_h, 3] ≤ 1, C, C_w]) → Cwline
  52. Text("Spans", (1.05, -5.38)) → SpansText
  53. Text("Degree", (1.05, -4.38)) → DegreeText
  54. Text("Weights", (1.05, -6.5 - (0.5 * n_{max}) - 0.38)) → WeightsText
  55. Text("First knot and adjustable knot differences", (3.95, -11.38)) → KnotSpansText
  56. Text("The curve is discontinuous.", (9.56, -11.38)) → DiscontinuityWarning
  57. Text("A non-monotonic knot vector is invalid.", (13.25, -11.38)) → NonmonotonicityWarning

AI 绘图提示语参考

绘制一个由10个控制点定义的三次非均匀有理B样条曲线,每个控制点都有对应的权重。首先定义控制点P0到P9和权重w0到w9,然后使用de Boor递归算法生成曲线上的点,最后绘制曲线及其控制点和权重。
以上提示语为根据原始绘图命令整理而来,仅供参考。