{"id":76494,"date":"2026-02-22T15:26:10","date_gmt":"2026-02-22T07:26:10","guid":{"rendered":"https:\/\/www.wsisp.com\/helps\/76494.html"},"modified":"2026-02-22T15:26:10","modified_gmt":"2026-02-22T07:26:10","slug":"%e8%b4%9d%e5%a1%9e%e5%b0%94%e6%9b%b2%e7%ba%bf%ef%bc%9a%e6%95%b0%e5%ad%a6%e6%8e%a8%e5%af%bc%e4%b8%8epython%e5%ae%9e%e7%8e%b0","status":"publish","type":"post","link":"https:\/\/www.wsisp.com\/helps\/76494.html","title":{"rendered":"\u8d1d\u585e\u5c14\u66f2\u7ebf\uff1a\u6570\u5b66\u63a8\u5bfc\u4e0ePython\u5b9e\u73b0"},"content":{"rendered":"<p id=\"auto-1\">\u58f0\u660e&#xff1a;\u672c\u5b66\u4e60\u7b14\u8bb0\u4f7f\u7528\u57fa\u4e8eGNU TeXmacs\u7684\u4e13\u4e1a\u7f16\u8f91\u5de5\u5177\u548cpython\u73af\u5883\u5b9e\u73b0&#xff0c;\u5185\u5bb9\u6765\u81ea\u4e8e\u7f51\u7edc\u6574\u7406\u5b66\u4e60&#xff0c;\u5185\u5d4c\u4ee3\u7801\u7531AI\u8f85\u52a9\u5e76\u624b\u52a8\u8c03\u8bd5\u901a\u8fc7&#xff0c;\u5c3d\u7ba1\u4e3a\u4e86\u4e0a\u4f20\u505a\u4e86\u624b\u52a8\u5904\u7406&#xff0c;\u5948\u4f55\u517c\u5bb9\u6027\u6b20\u4f73&#xff0c;\u65e0\u6cd5\u5b9e\u73b0\u539f\u5f00\u53d1\u73af\u5883\u6d4f\u89c8\u6548\u679c\u3002<\/p>\n<h4 id=\"auto-2\">1. \u4f2f\u6069\u65af\u5766\u57fa\u51fd\u6570<\/h4>\n<h5 id=\"auto-3\">1.1 \u6570\u5b66\u5b9a\u4e49<\/h5>\n<p>\u4f2f\u6069\u65af\u5766\u57fa\u51fd\u6570\u662f\u8d1d\u585e\u5c14\u66f2\u7ebf\u7684\u6570\u5b66\u57fa\u7840\u3002\u5bf9\u4e8e\u975e\u8d1f\u6574\u6570\u00a0n\u00a0\u548c\u6574\u6570\u00a0i&#xff08;0\u2264i\u2264n&#xff09;&#xff0c;\u7b2c\u00a0i\u00a0\u4e2a\u00a0n\u00a0\u6b21\u4f2f\u6069\u65af\u5766\u57fa\u51fd\u6570\u5b9a\u4e49\u4e3a&#xff1a;<\/p>\n<p>Bi,n(t)&#061;ti\u2062(1-t)n-i<\/p>\n<p>\u5176\u4e2d&#xff1a;<\/p>\n<ul>\n<li>\n<p>\u9636\u6570&#xff08;degree&#xff09;\u00a0n&#xff1a;\u66f2\u7ebf\u6b21\u6570<\/p>\n<\/li>\n<li>\n<p>\u7d22\u5f15&#xff08;index&#xff09;\u00a0i&#xff1a;\u57fa\u51fd\u6570\u7f16\u53f7<\/p>\n<\/li>\n<li>\n<p>\u53c2\u6570&#xff08;parameter&#xff09;\u00a0t&#xff1a;\u53d6\u503c\u8303\u56f4\u00a0[0,1]<\/p>\n<\/li>\n<li>\n<p>\u4e8c\u9879\u5f0f\u7cfb\u6570&#xff08;binomial coefficient&#xff09;\u00a0&#061;n!i!(n-i)!<\/p>\n<\/li>\n<\/ul>\n<h5 id=\"auto-4\">1.2 \u516c\u5f0f\u63a8\u5bfc<\/h5>\n<p>\u4f2f\u6069\u65af\u5766\u57fa\u51fd\u6570\u7531\u4e8c\u9879\u5f0f\u5b9a\u7406\u63a8\u5bfc\u800c\u6765\u3002\u4e8c\u9879\u5f0f\u5b9a\u7406\u6307\u51fa&#xff1a;<\/p>\n<p>(a&#043;b)n&#061;\u2211i&#061;0nai\u2062bn-i<\/p>\n<p>\u4ee4\u00a0a&#061;t&#xff0c;b&#061;1-t&#xff0c;\u5219&#xff1a;<\/p>\n<p>1&#061;(t&#043;(1-t))n&#061;\u2211i&#061;0nti\u2062(1-t)n-i<\/p>\n<p>\u8fd9\u6b63\u662f\u4f2f\u6069\u65af\u5766\u57fa\u51fd\u6570\u7684\u548c&#xff0c;\u8868\u660e\u5b83\u4eec\u662f\u5355\u4f4d\u5206\u5272\u7684\u57fa\u51fd\u6570\u3002<\/p>\n<p>\u4f2f\u6069\u65af\u5766\u57fa\u51fd\u6570\u8fd8\u5177\u6709\u9012\u63a8\u5173\u7cfb&#xff1a;<\/p>\n<p>Bi,n(t)&#061;(1-t)\u2062Bi,n-1(t)&#043;t\u2062Bi-1,n-1(t)<\/p>\n<h5 id=\"auto-5\">1.3 \u4ee3\u7801\u5b9e\u73b0<\/h5>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>import numpy as np<br \/>\nimport matplotlib.pyplot as plt<br \/>\nfrom scipy.special import comb<br \/>\nimport sympy as sp<br \/>\n# \u8bbe\u7f6e\u5168\u5c40\u5b57\u4f53\u4e3a\u652f\u6301\u4e2d\u6587\u7684\u5b57\u4f53<br \/>\nplt.rcParams[&#039;font.sans-serif&#039;] &#061; [&#039;Microsoft YaHei&#039;]  # \u4f7f\u7528\u9ed1\u4f53<br \/>\nplt.rcParams[&#039;axes.unicode_minus&#039;] &#061; False    # \u89e3\u51b3\u8d1f\u53f7\u663e\u793a\u95ee\u9898<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>def bernstein_basis_numeric(n, i, t):<br \/>\n    &#034;&#034;&#034;<br \/>\n    \u8ba1\u7b97\u4f2f\u6069\u65af\u5766\u57fa\u51fd\u6570\u7684\u6570\u503c<br \/>\n    &#034;&#034;&#034;<br \/>\n    return comb(n, i) * (t**i) * ((1-t)**(n-i))<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>def plot_bernstein_polynomials():<br \/>\n    &#034;&#034;&#034;<br \/>\n    \u7ed8\u5236\u4f2f\u6069\u65af\u5766\u591a\u9879\u5f0f<br \/>\n    &#034;&#034;&#034;<br \/>\n    n &#061; 4  # \u9636\u6570<br \/>\n    t &#061; np.linspace(0, 1, 200)<\/p>\n<p>    # \u521b\u5efa\u56fe\u5f62<br \/>\n    fig, axes &#061; plt.subplots(2, 3, figsize&#061;(12, 8))<br \/>\n    axes &#061; axes.flatten()<\/p>\n<p>    for i in range(n&#043;1):<br \/>\n        # \u8ba1\u7b97\u57fa\u51fd\u6570\u503c<br \/>\n        B &#061; bernstein_basis_numeric(n, i, t)<\/p>\n<p>        # \u7ed8\u5236\u56fe\u5f62<br \/>\n        ax &#061; axes[i]<br \/>\n        ax.plot(t, B, &#039;b-&#039;, linewidth&#061;2.5, label&#061;f&#039;$B_{{{i},{n}}}(t)$&#039;)<br \/>\n        ax.fill_between(t, 0, B, alpha&#061;0.2)<\/p>\n<p>        # \u8bbe\u7f6e\u56fe\u5f62\u5c5e\u6027<br \/>\n        ax.set_xlabel(&#039;t&#039;, fontsize&#061;12)<br \/>\n        ax.set_ylabel(&#039;\u503c&#039;, fontsize&#061;12)<br \/>\n        ax.set_title(f&#039;$B_{{{i},{n}}}(t)$&#039;, fontsize&#061;14)<br \/>\n        ax.grid(True, alpha&#061;0.3)<br \/>\n        ax.set_xlim(0, 1)<br \/>\n        ax.set_ylim(0, 1)<\/p>\n<p>    # \u9a8c\u8bc1\u5355\u4f4d\u5206\u5272\u6027\u8d28<br \/>\n    ax_sum &#061; axes[5]<br \/>\n    sum_B &#061; np.sum([bernstein_basis_numeric(n, i, t) for i in range(n&#043;1)], axis&#061;0)<br \/>\n    ax_sum.plot(t, sum_B, &#039;r-&#039;, linewidth&#061;2.5, label&#061;&#039;\u548c&#039;)<br \/>\n    ax_sum.axhline(y&#061;1, color&#061;&#039;k&#039;, linestyle&#061;&#039;&#8211;&#039;, alpha&#061;0.5)<br \/>\n    ax_sum.set_xlabel(&#039;t&#039;, fontsize&#061;12)<br \/>\n    ax_sum.set_ylabel(r&#039;$\\\\sum B_{i,n}(t)$&#039;, fontsize&#061;12)<br \/>\n    ax_sum.set_title(&#039;\u5355\u4f4d\u5206\u5272\u6027\u8d28&#039;, fontsize&#061;14)<br \/>\n    ax_sum.grid(True, alpha&#061;0.3)<br \/>\n    ax_sum.set_xlim(0, 1)<br \/>\n    ax_sum.set_ylim(0.99, 1.01)<\/p>\n<p>    fig.suptitle(f&#039;{n}\u6b21\u4f2f\u6069\u65af\u5766\u57fa\u51fd\u6570&#039;, fontsize&#061;16, fontweight&#061;&#039;bold&#039;)<br \/>\n    fig.tight_layout()<br \/>\n    return fig<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u00a0\n<\/p>\n<h5 id=\"auto-6\">1.4 \u7ed3\u679c\u8f93\u51fa<\/h5>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p># \u6267\u884c\u7ed8\u56fe<br \/>\nfig_bernstein &#061; plot_bernstein_polynomials()<br \/>\nfig_bernstein<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"452\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/02\/20260222072608-699aaf906c644.png\" width=\"689\" \/><\/p>\n<p>\u56fe1&#xff1a;4\u6b21\u4f2f\u6069\u65af\u5766\u57fa\u51fd\u6570\u3002\u6bcf\u4e2a\u57fa\u51fd\u6570\u5728\u00a0[0,1]\u00a0\u533a\u95f4\u4e0a\u975e\u8d1f&#xff0c;\u4e14\u6240\u6709\u57fa\u51fd\u6570\u7684\u548c\u4e3a1&#xff0c;\u6ee1\u8db3\u5355\u4f4d\u5206\u5272\u6027\u8d28\u3002<\/p>\n<h4 id=\"auto-7\">2. \u6807\u51c6&#xff08;\u591a\u9879\u5f0f&#xff09;\u8d1d\u585e\u5c14\u66f2\u7ebf<\/h4>\n<h5 id=\"auto-8\">2.1 \u6570\u5b66\u5b9a\u4e49<\/h5>\n<p>\u7ed9\u5b9a\u00a0n&#043;1\u00a0\u4e2a\u63a7\u5236\u70b9\u00a0P0,P1,\u2026,Pn\u2208\u211dd&#xff08;\u901a\u5e38\u00a0d&#061;2\u00a0\u6216\u00a03&#xff09;&#xff0c;n\u00a0\u6b21\u6807\u51c6\u8d1d\u585e\u5c14\u66f2\u7ebf\u5b9a\u4e49\u4e3a&#xff1a;<\/p>\n<p>C(t)&#061;\u2211i&#061;0nBi,n(t)\u2062Pi&#061;\u2211i&#061;0nti\u2062(1-t)n-i\u2062Pi<\/p>\n<p>\u5176\u4e2d\u00a0t\u2208[0,1]\u3002<\/p>\n<h5 id=\"auto-9\">2.2 \u516c\u5f0f\u63a8\u5bfc<\/h5>\n<\/p>\n<h6>2.2.1 \u4ece\u7ebf\u6027\u63d2\u503c\u63a8\u5bfc&#xff08;\u5fb7\u5361\u65af\u7279\u91cc\u5965\u7b97\u6cd5&#xff09;<\/h6>\n<\/p>\n<p>\u5fb7\u5361\u65af\u7279\u91cc\u5965\u7b97\u6cd5\u63d0\u4f9b\u4e86\u4e00\u79cd\u9012\u5f52\u8ba1\u7b97\u8d1d\u585e\u5c14\u66f2\u7ebf\u70b9\u7684\u65b9\u6cd5&#xff1a;<\/p>\n<\/p>\n<li>\n<p>\u5bf9\u4e8e\u00a0t\u2208[0,1]&#xff0c;\u5728\u7ebf\u6bb5\u00a0Pi\u2062Pi&#043;1\u00a0\u4e0a\u53d6\u70b9\u00a0Pi1(t)&#061;(1-t)\u2062Pi&#043;t\u2062Pi&#043;1<\/p>\n<\/li>\n<li>\n<p>\u5728\u7ebf\u6bb5\u00a0Pi1\u2062Pi&#043;11\u00a0\u4e0a\u53d6\u70b9\u00a0Pi2(t)&#061;(1-t)\u2062Pi1&#043;t\u2062Pi&#043;11<\/p>\n<\/li>\n<li>\n<p>\u91cd\u590d\u6b64\u8fc7\u7a0b\u00a0n\u00a0\u6b21&#xff0c;\u5f97\u5230\u00a0P0n(t)&#xff0c;\u5373\u66f2\u7ebf\u4e0a\u7684\u70b9\u00a0C(t)<\/p>\n<\/li>\n<\/p>\n<h6>2.2.2 \u4ece\u4e8c\u9879\u5f0f\u5b9a\u7406\u63a8\u5bfc<\/h6>\n<\/p>\n<p>\u5229\u7528\u4e8c\u9879\u5f0f\u5b9a\u7406\u00a0(a&#043;b)n&#061;\u2211i&#061;0nai\u2062bn-i&#xff0c;\u4ee4\u00a0a&#061;t&#xff0c;b&#061;1-t&#xff0c;\u5f97\u5230&#xff1a;<\/p>\n<p>1&#061;(t&#043;(1-t))n&#061;\u2211i&#061;0nti\u2062(1-t)n-i<\/p>\n<p>\u6bcf\u4e2a\u63a7\u5236\u70b9\u4e58\u4ee5\u76f8\u5e94\u7684\u4f2f\u6069\u65af\u5766\u57fa\u51fd\u6570&#xff0c;\u5f97\u5230\u66f2\u7ebf\u65b9\u7a0b\u3002<\/p>\n<h5 id=\"auto-12\">2.3 \u6570\u5b66\u6027\u8d28<\/h5>\n<\/p>\n<h6>2.3.1 \u7aef\u70b9\u6027\u8d28<\/h6>\n<\/p>\n<\/p>\n<li>\n<p>\u7aef\u70b9\u63d2\u503c&#xff1a;<\/p>\n<\/li>\n<p>C(0)&#061;P0,C(1)&#061;Pn<\/p>\n<p>\u66f2\u7ebf\u59cb\u7ec8\u901a\u8fc7\u7b2c\u4e00\u4e2a\u548c\u6700\u540e\u4e00\u4e2a\u63a7\u5236\u70b9\u3002<\/p>\n<\/p>\n<li>\n<p>\u7aef\u70b9\u5207\u7ebf&#xff1a;<\/p>\n<\/li>\n<p>C&#039;(0)&#061;n\u2062(P1-P0),C&#039;(1)&#061;n\u2062(Pn-Pn-1)<\/p>\n<p>\u66f2\u7ebf\u5728\u7aef\u70b9\u7684\u5207\u7ebf\u65b9\u5411\u7531\u76f8\u90bb\u63a7\u5236\u70b9\u51b3\u5b9a\u3002<\/p>\n<\/p>\n<li>\n<p>\u7aef\u70b9\u66f2\u7387&#xff1a;<\/p>\n<\/li>\n<p>C&#039;&#039;(0)&#061;n\u2062(n-1)\u2062(P2-2\u2062P1&#043;P0)<\/p>\n<p>\u66f2\u7ebf\u5728\u7aef\u70b9\u7684\u66f2\u7387\u7531\u524d\u4e09\u4e2a\u63a7\u5236\u70b9\u51b3\u5b9a\u3002<\/p>\n<\/p>\n<h6>2.3.2 \u51f8\u5305\u6027\u8d28<\/h6>\n<\/p>\n<p>\u51f8\u5305\u662f\u5305\u542b\u6240\u6709\u70b9\u7684\u6700\u5c0f\u51f8\u591a\u8fb9\u5f62\u3002\u5bf9\u4e8e\u4efb\u610f\u00a0t\u2208[0,1]&#xff0c;C(t)\u00a0\u4f4d\u4e8e\u63a7\u5236\u70b9\u7684\u51f8\u5305\u5185\u3002<\/p>\n<p>\u8bc1\u660e&#xff1a;\u7531\u4e8e\u4f2f\u6069\u65af\u5766\u57fa\u51fd\u6570\u975e\u8d1f\u4e14\u548c\u4e3a1&#xff0c;C(t)\u00a0\u662f\u63a7\u5236\u70b9\u7684\u51f8\u7ec4\u5408\u3002<\/p>\n<\/p>\n<h6>2.3.3 \u4eff\u5c04\u4e0d\u53d8\u6027<\/h6>\n<\/p>\n<p>\u5bf9\u4e8e\u4efb\u4f55\u4eff\u5c04\u53d8\u6362\u00a0T&#xff1a;<\/p>\n<p>T(\u2211i&#061;0nBi,n(t)\u2062Pi)&#061;\u2211i&#061;0nBi,n(t)\u2062T(Pi)<\/p>\n<\/p>\n<h6>2.3.4 \u53d8\u5dee\u7f29\u51cf\u6027<\/h6>\n<\/p>\n<p>\u4efb\u4f55\u76f4\u7ebf\u4e0e\u8d1d\u585e\u5c14\u66f2\u7ebf\u7684\u4ea4\u70b9\u6570\u4e0d\u8d85\u8fc7\u8be5\u76f4\u7ebf\u4e0e\u63a7\u5236\u591a\u8fb9\u5f62\u7684\u4ea4\u70b9\u6570\u3002<\/p>\n<h5 id=\"auto-17\">2.4 \u4ee3\u7801\u5b9e\u73b0<\/h5>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>def compute_bezier_curve(control_points, t_values&#061;None):<br \/>\n    &#034;&#034;&#034;<br \/>\n    \u8ba1\u7b97\u6807\u51c6\u8d1d\u585e\u5c14\u66f2\u7ebf<\/p>\n<p>    \u53c2\u6570:<br \/>\n    control_points: \u63a7\u5236\u70b9\u6570\u7ec4&#xff0c;\u5f62\u72b6\u4e3a (n&#043;1, 2) \u6216 (n&#043;1, 3)<br \/>\n    t_values: \u53c2\u6570\u503c\u6570\u7ec4&#xff0c;\u9ed8\u8ba4\u4e3a [0, 1] \u533a\u95f4\u4e0a\u7684100\u4e2a\u70b9<\/p>\n<p>    \u8fd4\u56de:<br \/>\n    \u66f2\u7ebf\u70b9\u6570\u7ec4<br \/>\n    &#034;&#034;&#034;<br \/>\n    control_points &#061; np.array(control_points)<br \/>\n    n &#061; len(control_points) &#8211; 1<\/p>\n<p>    if t_values is None:<br \/>\n        t_values &#061; np.linspace(0, 1, 100)<\/p>\n<p>    curve_points &#061; np.zeros((len(t_values), control_points.shape[1]))<\/p>\n<p>    for i, t in enumerate(t_values):<br \/>\n        for j in range(n&#043;1):<br \/>\n            basis &#061; bernstein_basis_numeric(n, j, t)<br \/>\n            curve_points[i] &#043;&#061; basis * control_points[j]<\/p>\n<p>    return curve_points<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>def de_casteljau_algorithm(control_points, t):<br \/>\n    &#034;&#034;&#034;<br \/>\n    \u5fb7\u5361\u65af\u7279\u91cc\u5965\u7b97\u6cd5<\/p>\n<p>    \u53c2\u6570:<br \/>\n    control_points: \u63a7\u5236\u70b9\u6570\u7ec4<br \/>\n    t: \u53c2\u6570\u503c<\/p>\n<p>    \u8fd4\u56de:<br \/>\n    \u66f2\u7ebf\u5728\u53c2\u6570t\u5904\u7684\u70b9<br \/>\n    &#034;&#034;&#034;<br \/>\n    points &#061; control_points.copy()<br \/>\n    n &#061; len(points) &#8211; 1<\/p>\n<p>    for r in range(1, n&#043;1):<br \/>\n        for i in range(n-r&#043;1):<br \/>\n            points[i] &#061; (1-t) * points[i] &#043; t * points[i&#043;1]<\/p>\n<p>    return points[0]<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>def plot_bezier_curve_example():<br \/>\n    &#034;&#034;&#034;<br \/>\n    \u7ed8\u5236\u6807\u51c6\u8d1d\u585e\u5c14\u66f2\u7ebf\u793a\u4f8b<br \/>\n    &#034;&#034;&#034;<br \/>\n    # \u5b9a\u4e49\u63a7\u5236\u70b9<br \/>\n    control_points_list &#061; [<br \/>\n        np.array([[0, 0], [1, 2], [3, 0]]),  # \u4e8c\u6b21\u8d1d\u585e\u5c14\u66f2\u7ebf<br \/>\n        np.array([[0, 0], [1, 3], [2, -1], [4, 2]]),  # \u4e09\u6b21\u8d1d\u585e\u5c14\u66f2\u7ebf<br \/>\n        np.array([[0, 0], [1, 2], [2, -1], [3, 3], [5, 0]])  # \u56db\u6b21\u8d1d\u585e\u5c14\u66f2\u7ebf<br \/>\n    ]<\/p>\n<p>    titles &#061; [&#039;\u4e8c\u6b21\u8d1d\u585e\u5c14\u66f2\u7ebf (n&#061;2)&#039;, &#039;\u4e09\u6b21\u8d1d\u585e\u5c14\u66f2\u7ebf (n&#061;3)&#039;, &#039;\u56db\u6b21\u8d1d\u585e\u5c14\u66f2\u7ebf (n&#061;4)&#039;]<\/p>\n<p>    # \u521b\u5efa\u56fe\u5f62<br \/>\n    fig, axes &#061; plt.subplots(1, 3, figsize&#061;(15, 5))<\/p>\n<p>    for idx, (control_points, title) in enumerate(zip(control_points_list, titles)):<br \/>\n        ax &#061; axes[idx]<\/p>\n<p>        # \u8ba1\u7b97\u66f2\u7ebf\u70b9<br \/>\n        curve_points &#061; compute_bezier_curve(control_points)<\/p>\n<p>        # \u7ed8\u5236\u63a7\u5236\u591a\u8fb9\u5f62<br \/>\n        ax.plot(control_points[:, 0], control_points[:, 1],<br \/>\n                &#039;ro-&#039;, linewidth&#061;1.5, markersize&#061;8, label&#061;&#039;\u63a7\u5236\u591a\u8fb9\u5f62&#039;)<\/p>\n<p>        # \u7ed8\u5236\u63a7\u5236\u70b9\u6807\u7b7e<br \/>\n        for i, point in enumerate(control_points):<br \/>\n            ax.text(point[0]&#043;0.05, point[1]&#043;0.05, f&#039;$P_{i}$&#039;,<br \/>\n                   fontsize&#061;12, fontweight&#061;&#039;bold&#039;)<\/p>\n<p>        # \u7ed8\u5236\u8d1d\u585e\u5c14\u66f2\u7ebf<br \/>\n        ax.plot(curve_points[:, 0], curve_points[:, 1],<br \/>\n                &#039;b-&#039;, linewidth&#061;2.5, label&#061;&#039;\u8d1d\u585e\u5c14\u66f2\u7ebf&#039;)<\/p>\n<p>        # \u4f7f\u7528\u5fb7\u5361\u65af\u7279\u91cc\u5965\u7b97\u6cd5\u8ba1\u7b97\u66f2\u7ebf\u4e0a\u7684\u70b9<br \/>\n        t_values &#061; [0.25, 0.5, 0.75]<br \/>\n        for t in t_values:<br \/>\n            point &#061; de_casteljau_algorithm(control_points, t)<br \/>\n            ax.scatter(point[0], point[1], s&#061;80, c&#061;&#039;green&#039;,<br \/>\n                      edgecolors&#061;&#039;black&#039;, linewidth&#061;2, zorder&#061;5)<br \/>\n            ax.text(point[0]&#043;0.05, point[1]&#043;0.05, f&#039;t&#061;{t}&#039;,<br \/>\n                   fontsize&#061;10, fontweight&#061;&#039;bold&#039;)<\/p>\n<p>        ax.set_title(title, fontsize&#061;14, fontweight&#061;&#039;bold&#039;)<br \/>\n        ax.set_xlabel(&#039;x&#039;, fontsize&#061;12)<br \/>\n        ax.set_ylabel(&#039;y&#039;, fontsize&#061;12)<br \/>\n        ax.grid(True, alpha&#061;0.3)<br \/>\n        ax.legend(loc&#061;&#039;best&#039;)<br \/>\n        ax.axis(&#039;equal&#039;)<\/p>\n<p>    fig.suptitle(&#039;\u6807\u51c6\u8d1d\u585e\u5c14\u66f2\u7ebf\u793a\u4f8b&#039;, fontsize&#061;16, fontweight&#061;&#039;bold&#039;)<br \/>\n    fig.tight_layout()<br \/>\n    return fig<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u00a0\n<\/p>\n<h5 id=\"auto-18\">2.5 \u7ed3\u679c\u8f93\u51fa<\/h5>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p># \u6267\u884c\u7ed8\u56fe<br \/>\nfig_bezier &#061; plot_bezier_curve_example()<br \/>\nfig_bezier<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"222\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/02\/20260222072608-699aaf908f532.png\" width=\"678\" \/><\/p>\n<\/p>\n<p>537 msec<\/p>\n<\/p>\n<p>\u56fe2&#xff1a;\u4e0d\u540c\u9636\u6570\u7684\u6807\u51c6\u8d1d\u585e\u5c14\u66f2\u7ebf\u3002\u4ece\u5de6\u5230\u53f3&#xff1a;\u4e8c\u6b21\u3001\u4e09\u6b21\u3001\u56db\u6b21\u8d1d\u585e\u5c14\u66f2\u7ebf\u3002\u66f2\u7ebf\u59cb\u7ec8\u4f4d\u4e8e\u63a7\u5236\u591a\u8fb9\u5f62\u5f62\u6210\u7684\u51f8\u5305\u5185\u3002<\/p>\n<h4 id=\"auto-19\">3. \u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf<\/h4>\n<h5 id=\"auto-20\">3.1 \u6570\u5b66\u5b9a\u4e49<\/h5>\n<p>\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u662f\u6807\u51c6\u8d1d\u585e\u5c14\u66f2\u7ebf\u7684\u63a8\u5e7f&#xff0c;\u6bcf\u4e2a\u63a7\u5236\u70b9\u00a0Pi\u00a0\u5173\u8054\u4e00\u4e2a\u6743\u91cd\u00a0wi&gt;0\u3002n\u00a0\u6b21\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u5b9a\u4e49\u4e3a&#xff1a;<\/p>\n<p>R(t)&#061;\u2211i&#061;0nwi\u2062Bi,n(t)\u2062Pi\u2211i&#061;0nwi\u2062Bi,n(t)&#061;\u2211i&#061;0nRi,n(t)\u2062Pi<\/p>\n<p>\u5176\u4e2d\u6709\u7406\u4f2f\u6069\u65af\u5766\u57fa\u51fd\u6570&#xff1a;<\/p>\n<p>Ri,n(t)&#061;wi\u2062Bi,n(t)\u2211j&#061;0nwj\u2062Bj,n(t)<\/p>\n<h5 id=\"auto-21\">3.2 \u516c\u5f0f\u63a8\u5bfc<\/h5>\n<p>\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u53ef\u4ee5\u901a\u8fc7\u9f50\u6b21\u5750\u6807\u63a8\u5bfc\u3002\u5728\u9f50\u6b21\u5750\u6807\u4e2d&#xff0c;\u6bcf\u4e2a\u63a7\u5236\u70b9\u8868\u793a\u4e3a\u00a0P\u223ci&#061;(wi\u2062xi,wi\u2062yi,wi\u2062zi,wi)\u3002\u66f2\u7ebf\u5728\u9f50\u6b21\u5750\u6807\u4e0b\u4e3a&#xff1a;<\/p>\n<p>R\u223c(t)&#061;\u2211i&#061;0nBi,n(t)\u2062P\u223ci<\/p>\n<p>\u901a\u8fc7\u900f\u89c6\u9664\u6cd5\u5f97\u5230\u6b27\u51e0\u91cc\u5f97\u5750\u6807&#xff1a;<\/p>\n<p>R(t)&#061;(x\u223c(t)w\u223c(t),y\u223c(t)w\u223c(t),z\u223c(t)w\u223c(t))<\/p>\n<p>\u5f53\u6240\u6709\u6743\u91cd\u76f8\u7b49\u65f6&#xff0c;\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u9000\u5316\u4e3a\u6807\u51c6\u8d1d\u585e\u5c14\u66f2\u7ebf\u3002<\/p>\n<h5 id=\"auto-22\">3.3 \u6570\u5b66\u6027\u8d28<\/h5>\n<\/p>\n<li>\n<p>\u6295\u5f71\u4e0d\u53d8\u6027&#xff1a;\u5728\u6295\u5f71\u53d8\u6362\u4e0b\u4fdd\u6301\u4e0d\u53d8<\/p>\n<\/li>\n<li>\n<p>\u7aef\u70b9\u63d2\u503c&#xff1a;R(0)&#061;P0&#xff0c;R(1)&#061;Pn&#xff08;\u5047\u8bbe\u00a0w0,wn&gt;0&#xff09;<\/p>\n<\/li>\n<li>\n<p>\u51f8\u5305\u6027&#xff1a;\u66f2\u7ebf\u4f4d\u4e8e\u63a7\u5236\u70b9\u7684\u51f8\u5305\u5185<\/p>\n<\/li>\n<li>\n<p>\u6743\u91cd\u5f71\u54cd&#xff1a;wi\u00a0\u589e\u5927\u65f6&#xff0c;\u66f2\u7ebf\u88ab\u62c9\u5411\u63a7\u5236\u70b9\u00a0Pi<\/p>\n<\/li>\n<li>\n<p>\u7cbe\u786e\u8868\u793a\u5706\u9525\u66f2\u7ebf&#xff1a;\u53ef\u4ee5\u7cbe\u786e\u8868\u793a\u5706\u3001\u692d\u5706\u3001\u629b\u7269\u7ebf\u3001\u53cc\u66f2\u7ebf<\/p>\n<\/li>\n<h5 id=\"auto-23\">3.4 \u4ee3\u7801\u5b9e\u73b0<\/h5>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>def compute_rational_bezier_curve(control_points, weights, t_values&#061;None):<br \/>\n    &#034;&#034;&#034;<br \/>\n    \u8ba1\u7b97\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf<\/p>\n<p>    \u53c2\u6570:<br \/>\n    control_points: \u63a7\u5236\u70b9\u6570\u7ec4<br \/>\n    weights: \u6743\u91cd\u6570\u7ec4<br \/>\n    t_values: \u53c2\u6570\u503c\u6570\u7ec4<\/p>\n<p>    \u8fd4\u56de:<br \/>\n    \u66f2\u7ebf\u70b9\u6570\u7ec4<br \/>\n    &#034;&#034;&#034;<br \/>\n    control_points &#061; np.array(control_points)<br \/>\n    weights &#061; np.array(weights)<br \/>\n    n &#061; len(control_points) &#8211; 1<\/p>\n<p>    if t_values is None:<br \/>\n        t_values &#061; np.linspace(0, 1, 100)<\/p>\n<p>    curve_points &#061; np.zeros((len(t_values), control_points.shape[1]))<\/p>\n<p>    for i, t in enumerate(t_values):<br \/>\n        numerator &#061; np.zeros(control_points.shape[1])<br \/>\n        denominator &#061; 0.0<\/p>\n<p>        for j in range(n&#043;1):<br \/>\n            basis &#061; bernstein_basis_numeric(n, j, t)<br \/>\n            weighted_basis &#061; weights[j] * basis<br \/>\n            numerator &#043;&#061; weighted_basis * control_points[j]<br \/>\n            denominator &#043;&#061; weighted_basis<\/p>\n<p>        if denominator !&#061; 0:<br \/>\n            curve_points[i] &#061; numerator \/ denominator<\/p>\n<p>    return curve_points<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>def plot_rational_bezier_comparison():<br \/>\n    &#034;&#034;&#034;<br \/>\n    \u6bd4\u8f83\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u548c\u6807\u51c6\u8d1d\u585e\u5c14\u66f2\u7ebf<br \/>\n    &#034;&#034;&#034;<br \/>\n    # \u5b9a\u4e49\u63a7\u5236\u70b9<br \/>\n    control_points &#061; np.array([<br \/>\n        [0, 0],<br \/>\n        [1, 2],<br \/>\n        [2, -1],<br \/>\n        [3, 1],<br \/>\n        [4, 0]<br \/>\n    ])<\/p>\n<p>    # \u5b9a\u4e49\u6743\u91cd\u914d\u7f6e<br \/>\n    weight_configs &#061; [<br \/>\n        {&#039;weights&#039;: np.ones(5), &#039;label&#039;: &#039;\u6807\u51c6\u8d1d\u585e\u5c14\u66f2\u7ebf (\u6240\u6709\u6743\u91cd&#061;1)&#039;, &#039;color&#039;: &#039;b&#039;},<br \/>\n        {&#039;weights&#039;: np.array([1, 3, 1, 1, 1]), &#039;label&#039;: &#039;\u6709\u7406\u66f2\u7ebf (P\u2081\u6743\u91cd&#061;3)&#039;, &#039;color&#039;: &#039;r&#039;},<br \/>\n        {&#039;weights&#039;: np.array([1, 0.2, 1, 1, 1]), &#039;label&#039;: &#039;\u6709\u7406\u66f2\u7ebf (P\u2081\u6743\u91cd&#061;0.2)&#039;, &#039;color&#039;: &#039;g&#039;},<br \/>\n        {&#039;weights&#039;: np.array([1, 1, 5, 1, 1]), &#039;label&#039;: &#039;\u6709\u7406\u66f2\u7ebf (P\u2082\u6743\u91cd&#061;5)&#039;, &#039;color&#039;: &#039;m&#039;}<br \/>\n    ]<\/p>\n<p>    # \u521b\u5efa\u56fe\u5f62<br \/>\n    fig, axes &#061; plt.subplots(2, 2, figsize&#061;(12, 10))<br \/>\n    axes &#061; axes.flatten()<\/p>\n<p>    for idx, config in enumerate(weight_configs):<br \/>\n        ax &#061; axes[idx]<br \/>\n        weights &#061; config[&#039;weights&#039;]<\/p>\n<p>        # \u8ba1\u7b97\u66f2\u7ebf<br \/>\n        if np.all(weights &#061;&#061; 1):<br \/>\n            curve &#061; compute_bezier_curve(control_points)<br \/>\n        else:<br \/>\n            curve &#061; compute_rational_bezier_curve(control_points, weights)<\/p>\n<p>        # \u7ed8\u5236\u63a7\u5236\u591a\u8fb9\u5f62<br \/>\n        ax.plot(control_points[:, 0], control_points[:, 1],<br \/>\n                &#039;ko-&#039;, linewidth&#061;1, markersize&#061;6, alpha&#061;0.5)<\/p>\n<p>        # \u7ed8\u5236\u63a7\u5236\u70b9&#xff08;\u5927\u5c0f\u8868\u793a\u6743\u91cd&#xff09;<br \/>\n        for i, (point, weight) in enumerate(zip(control_points, weights)):<br \/>\n            ax.scatter(point[0], point[1], s&#061;weight*80,<br \/>\n                      alpha&#061;0.7, edgecolors&#061;&#039;black&#039;, linewidth&#061;1)<br \/>\n            ax.text(point[0]&#043;0.05, point[1]&#043;0.05, f&#039;w&#061;{weight}&#039;,<br \/>\n                   fontsize&#061;10, fontweight&#061;&#039;bold&#039;)<\/p>\n<p>        # \u7ed8\u5236\u66f2\u7ebf<br \/>\n        ax.plot(curve[:, 0], curve[:, 1],<br \/>\n                config[&#039;color&#039;] &#043; &#039;-&#039;, linewidth&#061;2.5, label&#061;config[&#039;label&#039;])<\/p>\n<p>        ax.set_title(config[&#039;label&#039;], fontsize&#061;12, fontweight&#061;&#039;bold&#039;)<br \/>\n        ax.set_xlabel(&#039;x&#039;, fontsize&#061;12)<br \/>\n        ax.set_ylabel(&#039;y&#039;, fontsize&#061;12)<br \/>\n        ax.grid(True, alpha&#061;0.3)<br \/>\n        ax.legend(loc&#061;&#039;best&#039;)<br \/>\n        ax.axis(&#039;equal&#039;)<\/p>\n<p>    fig.suptitle(&#039;\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u4e0e\u6807\u51c6\u8d1d\u585e\u5c14\u66f2\u7ebf\u6bd4\u8f83&#039;, fontsize&#061;16, fontweight&#061;&#039;bold&#039;)<br \/>\n    fig.tight_layout()<br \/>\n    return fig<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>def plot_rational_bezier_circle():<br \/>\n    &#034;&#034;&#034;<br \/>\n    \u4f7f\u7528\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u7ed8\u5236\u5706\u5f27<br \/>\n    &#034;&#034;&#034;<br \/>\n    # \u4f7f\u7528\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u8868\u793a90\u5ea6\u5706\u5f27<br \/>\n    theta &#061; np.pi \/ 4  # 45\u5ea6<br \/>\n    r &#061; 1.0  # \u534a\u5f84<br \/>\n    # \u63a7\u5236\u70b9\u5750\u6807<br \/>\n    P0 &#061; np.array([r, 0])<br \/>\n    P1 &#061; np.array([r, r * np.tan(theta\/2)])<br \/>\n    P2 &#061; np.array([r * np.cos(theta), r * np.sin(theta)])<br \/>\n    # \u6743\u91cd\u8ba1\u7b97&#xff08;\u7528\u4e8e\u7cbe\u786e\u8868\u793a\u5706\u5f27&#xff09;<br \/>\n    w0 &#061; 1.0<br \/>\n    w1 &#061; np.cos(theta\/2)<br \/>\n    w2 &#061; 1.0<br \/>\n    control_points &#061; np.array([P0, P1, P2])<br \/>\n    weights &#061; np.array([w0, w1, w2])<br \/>\n    # \u8ba1\u7b97\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf<br \/>\n    t_values &#061; np.linspace(0, 1, 100)<br \/>\n    curve &#061; compute_rational_bezier_curve(control_points, weights, t_values)<br \/>\n    # \u8ba1\u7b97\u6807\u51c6\u8d1d\u585e\u5c14\u66f2\u7ebf&#xff08;\u7528\u4e8e\u6bd4\u8f83&#xff09;<br \/>\n    std_curve &#061; compute_bezier_curve(control_points, t_values)<br \/>\n    # \u7cbe\u786e\u5706\u5f27<br \/>\n    arc_theta &#061; np.linspace(0, theta, 100)<br \/>\n    exact_arc &#061; np.column_stack([r * np.cos(arc_theta), r * np.sin(arc_theta)])<br \/>\n    # \u521b\u5efa\u56fe\u5f62<br \/>\n    fig, (ax1, ax2) &#061; plt.subplots(1, 2, figsize&#061;(12, 5))<br \/>\n    # \u5de6\u56fe&#xff1a;\u66f2\u7ebf\u6bd4\u8f83<br \/>\n    ax1.plot(exact_arc[:, 0], exact_arc[:, 1], &#039;g-&#039;,<br \/>\n             linewidth&#061;3, alpha&#061;0.7, label&#061;&#039;\u7cbe\u786e\u5706\u5f27&#039;)<br \/>\n    ax1.plot(curve[:, 0], curve[:, 1], &#039;b-&#039;,<br \/>\n             linewidth&#061;2, label&#061;&#039;\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf&#039;)<br \/>\n    ax1.plot(std_curve[:, 0], std_curve[:, 1], &#039;r&#8211;&#039;,<br \/>\n             linewidth&#061;2, alpha&#061;0.7, label&#061;&#039;\u6807\u51c6\u8d1d\u585e\u5c14\u66f2\u7ebf&#039;)<br \/>\n    # \u7ed8\u5236\u63a7\u5236\u591a\u8fb9\u5f62<br \/>\n    ax1.plot(control_points[:, 0], control_points[:, 1],<br \/>\n             &#039;ko-&#039;, linewidth&#061;1, markersize&#061;8, alpha&#061;0.5)<br \/>\n    # \u6807\u8bb0\u63a7\u5236\u70b9<br \/>\n    for i, (point, weight) in enumerate(zip(control_points, weights)):<br \/>\n        ax1.scatter(point[0], point[1], s&#061;weight*100,<br \/>\n                   alpha&#061;0.7, edgecolors&#061;&#039;black&#039;, linewidth&#061;1)<br \/>\n        ax1.text(point[0]&#043;0.05, point[1]&#043;0.05, f&#039;P{i}\\\\nw&#061;{weight:.3f}&#039;,<br \/>\n                fontsize&#061;10, fontweight&#061;&#039;bold&#039;)<br \/>\n    ax1.set_xlabel(&#039;x&#039;, fontsize&#061;12)<br \/>\n    ax1.set_ylabel(&#039;y&#039;, fontsize&#061;12)<br \/>\n    ax1.set_title(&#039;\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u8868\u793a\u5706\u5f27&#039;, fontsize&#061;14, fontweight&#061;&#039;bold&#039;)<br \/>\n    ax1.grid(True, alpha&#061;0.3)<br \/>\n    ax1.legend(loc&#061;&#039;best&#039;)<br \/>\n    ax1.axis(&#039;equal&#039;)<br \/>\n    ax1.set_xlim(-0.2, 1.2)<br \/>\n    ax1.set_ylim(-0.2, 1.2)<br \/>\n    # \u53f3\u56fe&#xff1a;\u8bef\u5dee\u5206\u6790<br \/>\n    # \u8ba1\u7b97\u8bef\u5dee<br \/>\n    error_rational &#061; np.linalg.norm(curve &#8211; exact_arc, axis&#061;1)<br \/>\n    error_standard &#061; np.linalg.norm(std_curve &#8211; exact_arc, axis&#061;1)<br \/>\n    ax2.plot(t_values, error_rational, &#039;b-&#039;, linewidth&#061;2,<br \/>\n             label&#061;&#039;\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u8bef\u5dee&#039;)<br \/>\n    ax2.plot(t_values, error_standard, &#039;r&#8211;&#039;, linewidth&#061;2,<br \/>\n             label&#061;&#039;\u6807\u51c6\u8d1d\u585e\u5c14\u66f2\u7ebf\u8bef\u5dee&#039;)<br \/>\n    ax2.set_xlabel(&#039;\u53c2\u6570 t&#039;, fontsize&#061;12)<br \/>\n    ax2.set_ylabel(&#039;\u8bef\u5dee&#039;, fontsize&#061;12)<br \/>\n    ax2.set_title(&#039;\u4e0e\u7cbe\u786e\u5706\u5f27\u7684\u8bef\u5dee\u6bd4\u8f83&#039;, fontsize&#061;14, fontweight&#061;&#039;bold&#039;)<br \/>\n    ax2.grid(True, alpha&#061;0.3)<br \/>\n    ax2.legend(loc&#061;&#039;best&#039;)<br \/>\n    fig.suptitle(&#039;\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u8868\u793a\u5706\u9525\u66f2\u7ebf&#039;, fontsize&#061;16, fontweight&#061;&#039;bold&#039;)<br \/>\n    fig.tight_layout()<br \/>\n    return fig<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u00a0\n<\/p>\n<h5 id=\"auto-24\">3.5 \u7ed3\u679c\u8f93\u51fa<\/h5>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p># \u6267\u884c\u7ed8\u56fe<br \/>\nfig_rational_comparison &#061; plot_rational_bezier_comparison()<br \/>\nfig_rational_comparison<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"571\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/02\/20260222072608-699aaf90ae506.png\" width=\"693\" \/><\/p>\n<\/p>\n<p>681 msec<\/p>\n<\/p>\n<p>\u56fe3&#xff1a;\u4e0d\u540c\u6743\u91cd\u914d\u7f6e\u7684\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u3002\u6743\u91cd\u8d8a\u5927&#xff0c;\u66f2\u7ebf\u8d8a\u63a5\u8fd1\u5bf9\u5e94\u63a7\u5236\u70b9\u3002<\/p>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p># \u6267\u884c\u7ed8\u56fe<br \/>\nfig_rational_circle &#061; plot_rational_bezier_circle()<br \/>\nfig_rational_circle<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"289\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/02\/20260222072608-699aaf90ca404.png\" width=\"687\" \/><\/p>\n<\/p>\n<p>299 msec<\/p>\n<\/p>\n<p>\u56fe4&#xff1a;\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u53ef\u4ee5\u7cbe\u786e\u8868\u793a\u5706\u5f27&#xff0c;\u800c\u6807\u51c6\u8d1d\u585e\u5c14\u66f2\u7ebf\u53ea\u80fd\u8fd1\u4f3c\u8868\u793a\u3002<\/p>\n<h4 id=\"auto-25\">4. \u8fde\u7eed\u6027\u5206\u6790<\/h4>\n<h5 id=\"auto-26\">4.1 \u6570\u5b66\u5b9a\u4e49<\/h5>\n<\/p>\n<h6>4.1.1 \u53c2\u6570\u8fde\u7eed\u6027 (Ck\u00a0\u8fde\u7eed)<\/h6>\n<\/p>\n<p>C\u8fde\u7eed\u6027\u5173\u6ce8\u7684\u662f\u53c2\u6570\u57df\u4e0a\u7684\u5bfc\u6570\u662f\u5426\u8fde\u7eed&#xff0c;\u5373\u66f2\u7ebf\u5728\u53c2\u6570\u7a7a\u95f4\u4e2d\u7684\u53d8\u5316\u662f\u5426\u5e73\u6ed1\u3002<\/p>\n<ul>\n<li>\n<p>C\u8fde\u7eed\u6027\u662f\u4e25\u683c\u7684\u6570\u5b66\u5b9a\u4e49&#xff0c;\u8981\u6c42\u53c2\u6570\u5316\u7684\u5bfc\u6570\u5b8c\u5168\u5339\u914d\u3002<\/p>\n<\/li>\n<li>\n<p>\u9002\u7528\u4e8e\u9700\u8981\u4e25\u683c\u63a7\u5236\u53c2\u6570\u5316\u884c\u4e3a\u7684\u573a\u666f&#xff08;\u5982\u52a8\u753b\u8def\u5f84\u89c4\u5212\u3001\u673a\u5668\u4eba\u8f68\u8ff9\u8bbe\u8ba1\u7b49&#xff09;\u3002<\/p>\n<\/li>\n<\/ul>\n<p>\u5bf9\u4e8e\u4e24\u6761\u8d1d\u585e\u5c14\u66f2\u7ebf&#xff1a;<\/p>\n<ul>\n<li>\n<p>\u66f2\u7ebf1&#xff1a;C1(t)&#061;\u2211i&#061;0nBi,n(t)\u2062Pi&#xff0c;t\u2208[0,1]<\/p>\n<\/li>\n<li>\n<p>\u66f2\u7ebf2&#xff1a;C2(t)&#061;\u2211i&#061;0mBi,m(t)\u2062Qi&#xff0c;t\u2208[0,1]<\/p>\n<\/li>\n<\/ul>\n<li>\n<p>C0\u00a0\u8fde\u7eed&#xff08;\u4f4d\u7f6e\u8fde\u7eed&#xff09;&#xff1a;<\/p>\n<\/li>\n<p>C1(1)&#061;C2(0)\u21d2Pn&#061;Q0<\/p>\n<\/p>\n<li>\n<p>C1\u00a0\u8fde\u7eed&#xff08;\u5207\u7ebf\u8fde\u7eed&#xff09;&#xff1a;<\/p>\n<ul>\n<li>\n<p>Pn&#061;Q0&#xff08;\u4f4d\u7f6e\u8fde\u7eed&#xff09;<\/p>\n<\/li>\n<li>\n<p>C1&#039;(1)&#061;C2&#039;(0)\u21d2n\u2062(Pn-Pn-1)&#061;m\u2062(Q1-Q0)<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>C2\u00a0\u8fde\u7eed&#xff08;\u66f2\u7387\u8fde\u7eed&#xff09;&#xff1a;<\/p>\n<ul>\n<li>\n<p>C1\u00a0\u8fde\u7eed\u6761\u4ef6<\/p>\n<\/li>\n<li>\n<p>C1&#039;&#039;(1)&#061;C2&#039;&#039;(0)<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/p>\n<h6>4.1.2 \u51e0\u4f55\u8fde\u7eed\u6027 (Gk\u00a0\u8fde\u7eed)<\/h6>\n<\/p>\n<p>G\u8fde\u7eed\u6027\u5173\u6ce8\u7684\u662f\u51e0\u4f55\u5f62\u72b6\u4e0a\u7684\u5149\u6ed1\u7a0b\u5ea6&#xff0c;\u4e0d\u8981\u6c42\u53c2\u6570\u5316\u5bfc\u6570\u5b8c\u5168\u4e00\u81f4&#xff0c;\u53ea\u9700\u51e0\u4f55\u7279\u6027&#xff08;\u5982\u5207\u7ebf\u65b9\u5411\u3001\u66f2\u7387&#xff09;\u8fde\u7eed\u5373\u53ef\u3002<\/p>\n<ul>\n<li>\n<p>G\u8fde\u7eed\u6027\u662f\u51e0\u4f55\u610f\u4e49\u4e0a\u7684\u5b9a\u4e49&#xff0c;\u66f4\u6ce8\u91cd\u89c6\u89c9\u4e0a\u7684\u5e73\u6ed1\u6548\u679c\u3002<\/p>\n<\/li>\n<li>\n<p>\u9002\u7528\u4e8e\u5bf9\u53c2\u6570\u5316\u4e0d\u654f\u611f\u7684\u573a\u666f&#xff08;\u5982\u5de5\u4e1a\u8bbe\u8ba1\u3001\u5b57\u4f53\u8bbe\u8ba1\u7b49&#xff09;\u3002<\/p>\n<\/li>\n<\/ul>\n<li>\n<p>G1\u00a0\u8fde\u7eed&#xff08;\u5207\u7ebf\u65b9\u5411\u8fde\u7eed&#xff09;&#xff1a;<\/p>\n<ul>\n<li>\n<p>C1(1)&#061;C2(0)<\/p>\n<\/li>\n<li>\n<p>C1&#039;(1)\u00a0\u4e0e\u00a0C2&#039;(0)\u00a0\u65b9\u5411\u76f8\u540c&#xff08;\u5927\u5c0f\u53ef\u4e0d\u540c&#xff09;<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>G2\u00a0\u8fde\u7eed&#xff08;\u66f2\u7387\u8fde\u7eed&#xff09;&#xff1a;<\/p>\n<ul>\n<li>\n<p>G1\u00a0\u8fde\u7eed<\/p>\n<\/li>\n<li>\n<p>\u66f2\u7387\u5728\u8fde\u63a5\u70b9\u5904\u8fde\u7eed<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<h5 id=\"auto-29\">4.2 \u516c\u5f0f\u63a8\u5bfc<\/h5>\n<\/p>\n<h6>4.2.1 \u5bfc\u6570\u516c\u5f0f<\/h6>\n<\/p>\n<p>\u8d1d\u585e\u5c14\u66f2\u7ebf\u7684\u5bfc\u6570&#xff1a;<\/p>\n<p>\u4e00\u9636\u5bfc\u6570&#xff1a;<\/p>\n<p>C&#039;(t)&#061;n\u2062\u2211i&#061;0n-1Bi,n-1(t)\u2062(Pi&#043;1-Pi)<\/p>\n<p>\u4e8c\u9636\u5bfc\u6570&#xff1a;<\/p>\n<p>C&#039;&#039;(t)&#061;n\u2062(n-1)\u2062\u2211i&#061;0n-2Bi,n-2(t)\u2062(Pi&#043;2-2\u2062Pi&#043;1&#043;Pi)<\/p>\n<\/p>\n<h6>4.2.2 \u66f2\u7387\u516c\u5f0f<\/h6>\n<\/p>\n<p>\u5bf9\u4e8e\u5e73\u9762\u66f2\u7ebf\u00a0C(t)&#061;(x(t),y(t))&#xff0c;\u66f2\u7387\u4e3a&#xff1a;<\/p>\n<p>\u03ba(t)&#061;|x&#039;(t)\u2062y&#039;&#039;(t)-y&#039;(t)\u2062x&#039;&#039;(t)|[x&#039;(t)2&#043;y&#039;(t)2]3\/2<\/p>\n<h5 id=\"auto-32\">4.3 \u4ee3\u7801\u5b9e\u73b0<\/h5>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>def compute_bezier_derivative(control_points, t, order&#061;1):<br \/>\n    &#034;&#034;&#034;<br \/>\n    \u8ba1\u7b97\u8d1d\u585e\u5c14\u66f2\u7ebf\u7684\u5bfc\u6570<\/p>\n<p>    \u53c2\u6570:<br \/>\n    control_points: \u63a7\u5236\u70b9\u6570\u7ec4<br \/>\n    t: \u53c2\u6570\u503c<br \/>\n    order: \u5bfc\u6570\u9636\u6570 (0: \u4f4d\u7f6e, 1: \u4e00\u9636\u5bfc\u6570, 2: \u4e8c\u9636\u5bfc\u6570)<\/p>\n<p>    \u8fd4\u56de:<br \/>\n    \u6307\u5b9a\u9636\u6570\u7684\u5bfc\u6570<br \/>\n    &#034;&#034;&#034;<br \/>\n    control_points &#061; np.array(control_points)<br \/>\n    n &#061; len(control_points) &#8211; 1<\/p>\n<p>    if order &#061;&#061; 0:<br \/>\n        # \u4f4d\u7f6e<br \/>\n        return de_casteljau_algorithm(control_points, t)<\/p>\n<p>    if n &lt; order:<br \/>\n        # \u9636\u6570\u4e0d\u591f<br \/>\n        return np.zeros_like(control_points[0])<\/p>\n<p>    # \u8ba1\u7b97\u5bfc\u6570\u63a7\u5236\u70b9<br \/>\n    points &#061; control_points.copy()<br \/>\n    for r in range(order):<br \/>\n        m &#061; n &#8211; r<br \/>\n        new_points &#061; np.zeros((m, control_points.shape[1]))<br \/>\n        for i in range(m):<br \/>\n            # \u5bfc\u6570\u516c\u5f0f: C^{(r)}(t) \u7684\u63a7\u5236\u70b9\u662f\u539f\u59cb\u63a7\u5236\u70b9\u7684r\u9636\u5dee\u5206<br \/>\n            new_points[i] &#061; m * (points[i&#043;1] &#8211; points[i])<br \/>\n        points &#061; new_points<\/p>\n<p>    # \u4f7f\u7528\u5fb7\u5361\u65af\u7279\u91cc\u5965\u7b97\u6cd5\u8ba1\u7b97\u5bfc\u6570\u503c<br \/>\n    return de_casteljau_algorithm(points, t)<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>52 msec<\/p>\n<\/p>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>def compute_curvature(control_points, t):<br \/>\n    &#034;&#034;&#034;<br \/>\n    \u8ba1\u7b97\u8d1d\u585e\u5c14\u66f2\u7ebf\u7684\u66f2\u7387<\/p>\n<p>    \u53c2\u6570:<br \/>\n    control_points: \u63a7\u5236\u70b9\u6570\u7ec4 (\u4e8c\u7ef4)<br \/>\n    t: \u53c2\u6570\u503c<\/p>\n<p>    \u8fd4\u56de:<br \/>\n    \u66f2\u7387\u503c<br \/>\n    &#034;&#034;&#034;<br \/>\n    # \u8ba1\u7b97\u4e00\u9636\u548c\u4e8c\u9636\u5bfc\u6570<br \/>\n    deriv1 &#061; compute_bezier_derivative(control_points, t, 1)<br \/>\n    deriv2 &#061; compute_bezier_derivative(control_points, t, 2)<\/p>\n<p>    x1, y1 &#061; deriv1[0], deriv1[1]<br \/>\n    x2, y2 &#061; deriv2[0], deriv2[1]<\/p>\n<p>    # \u8ba1\u7b97\u66f2\u7387<br \/>\n    numerator &#061; abs(x1*y2 &#8211; y1*x2)<br \/>\n    denominator &#061; (x1**2 &#043; y1**2)**1.5<\/p>\n<p>    return numerator \/ denominator if denominator !&#061; 0 else 0<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>36 msec<\/p>\n<\/p>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>def analyze_continuity(curve1_points, curve2_points):<br \/>\n    &#034;&#034;&#034;<br \/>\n    \u5206\u6790\u4e24\u6761\u8d1d\u585e\u5c14\u66f2\u7ebf\u7684\u8fde\u7eed\u6027<br \/>\n    \u53c2\u6570:<br \/>\n    curve1_points: \u7b2c\u4e00\u6761\u66f2\u7ebf\u7684\u63a7\u5236\u70b9<br \/>\n    curve2_points: \u7b2c\u4e8c\u6761\u66f2\u7ebf\u7684\u63a7\u5236\u70b9<br \/>\n    &#034;&#034;&#034;<br \/>\n    curve1_points &#061; np.array(curve1_points);curve2_points &#061; np.array(curve2_points)<br \/>\n    # \u8ba1\u7b97\u8fde\u63a5\u70b9\u4f4d\u7f6e<br \/>\n    C1_end &#061; compute_bezier_derivative(curve1_points, 1.0, 0)<br \/>\n    C2_start &#061; compute_bezier_derivative(curve2_points, 0.0, 0)<br \/>\n    # \u8ba1\u7b97\u5bfc\u6570<br \/>\n    C1_end_deriv1 &#061; compute_bezier_derivative(curve1_points, 1.0, 1)<br \/>\n    C2_start_deriv1 &#061; compute_bezier_derivative(curve2_points, 0.0, 1)<br \/>\n    C1_end_deriv2 &#061; compute_bezier_derivative(curve1_points, 1.0, 2)<br \/>\n    C2_start_deriv2 &#061; compute_bezier_derivative(curve2_points, 0.0, 2)<br \/>\n    # \u8ba1\u7b97\u66f2\u7387<br \/>\n    curvature1_end &#061; compute_curvature(curve1_points, 1.0)<br \/>\n    curvature2_start &#061; compute_curvature(curve2_points, 0.0)<br \/>\n    # \u5224\u65ad\u8fde\u7eed\u6027<br \/>\n    C0_continuous &#061; np.allclose(C1_end, C2_start, rtol&#061;1e-10, atol&#061;1e-10)<br \/>\n    # G1\u8fde\u7eed&#xff1a;\u5207\u7ebf\u65b9\u5411\u76f8\u540c<br \/>\n    if np.linalg.norm(C1_end_deriv1) &gt; 1e-10 and np.linalg.norm(C2_start_deriv1) &gt; 1e-10:<br \/>\n        unit_deriv1 &#061; C1_end_deriv1 \/ np.linalg.norm(C1_end_deriv1)<br \/>\n        unit_deriv2 &#061; C2_start_deriv1 \/ np.linalg.norm(C2_start_deriv1)<br \/>\n        G1_continuous &#061; np.dot(unit_deriv1, unit_deriv2) &gt; 0.999<br \/>\n    else:<br \/>\n        G1_continuous &#061; False<br \/>\n    # C1\u8fde\u7eed&#xff1a;\u5bfc\u6570\u76f8\u7b49<br \/>\n    C1_continuous &#061; np.allclose(C1_end_deriv1, C2_start_deriv1, rtol&#061;1e-10, atol&#061;1e-10)<br \/>\n    # G2\u8fde\u7eed&#xff1a;\u66f2\u7387\u8fde\u7eed<br \/>\n    G2_continuous &#061; np.allclose(curvature1_end, curvature2_start, rtol&#061;1e-5, atol&#061;1e-5)<br \/>\n    # C2\u8fde\u7eed&#xff1a;\u4e8c\u9636\u5bfc\u6570\u76f8\u7b49<br \/>\n    C2_continuous &#061; np.allclose(C1_end_deriv2, C2_start_deriv2, rtol&#061;1e-10, atol&#061;1e-10)<br \/>\n    # \u521b\u5efa\u56fe\u5f62<br \/>\n    fig, axes &#061; plt.subplots(2, 2, figsize&#061;(12, 10))<br \/>\n    # \u5de6\u4e0a&#xff1a;\u66f2\u7ebf\u62fc\u63a5<br \/>\n    ax &#061; axes[0, 0]<br \/>\n    # \u8ba1\u7b97\u66f2\u7ebf<br \/>\n    curve1 &#061; compute_bezier_curve(curve1_points);curve2 &#061; compute_bezier_curve(curve2_points)<br \/>\n    # \u7ed8\u5236\u63a7\u5236\u591a\u8fb9\u5f62<br \/>\n    ax.plot(curve1_points[:, 0], curve1_points[:, 1], &#039;ro-&#039;, linewidth&#061;1.5, markersize&#061;8, alpha&#061;0.7, label&#061;&#039;\u66f2\u7ebf1\u63a7\u5236\u591a\u8fb9\u5f62&#039;)<br \/>\n    ax.plot(curve2_points[:, 0], curve2_points[:, 1], &#039;bo-&#039;, linewidth&#061;1.5, markersize&#061;8, alpha&#061;0.7, label&#061;&#039;\u66f2\u7ebf2\u63a7\u5236\u591a\u8fb9\u5f62&#039;)<br \/>\n    # \u7ed8\u5236\u66f2\u7ebf<br \/>\n    ax.plot(curve1[:, 0], curve1[:, 1], &#039;r-&#039;, linewidth&#061;2.5, label&#061;&#039;\u66f2\u7ebf1&#039;)<br \/>\n    ax.plot(curve2[:, 0], curve2[:, 1], &#039;b-&#039;, linewidth&#061;2.5, label&#061;&#039;\u66f2\u7ebf2&#039;)<br \/>\n    # \u6807\u8bb0\u8fde\u63a5\u70b9<br \/>\n    joint_point &#061; C1_end<br \/>\n    ax.scatter(joint_point[0], joint_point[1], s&#061;150, color&#061;&#039;green&#039;, edgecolors&#061;&#039;black&#039;, linewidth&#061;2, zorder&#061;5, label&#061;&#039;\u8fde\u63a5\u70b9&#039;)<br \/>\n    # \u7ed8\u5236\u5207\u7ebf<br \/>\n    scale &#061; 0.3<br \/>\n    ax.arrow(joint_point[0], joint_point[1], C1_end_deriv1[0]*scale, C1_end_deriv1[1]*scale, head_width&#061;0.05, head_length&#061;0.1, fc&#061;&#039;red&#039;, ec&#061;&#039;red&#039;, linewidth&#061;2, label&#061;&#039;\u66f2\u7ebf1\u7ec8\u70b9\u5207\u7ebf&#039;)<br \/>\n    ax.arrow(joint_point[0], joint_point[1], C2_start_deriv1[0]*scale, C2_start_deriv1[1]*scale, head_width&#061;0.05, head_length&#061;0.1, fc&#061;&#039;blue&#039;, ec&#061;&#039;blue&#039;, linewidth&#061;2, label&#061;&#039;\u66f2\u7ebf2\u8d77\u70b9\u5207\u7ebf&#039;)<br \/>\n    ax.set_title(&#039;\u66f2\u7ebf\u62fc\u63a5&#039;, fontsize&#061;14, fontweight&#061;&#039;bold&#039;)<br \/>\n    ax.set_xlabel(&#039;x&#039;, fontsize&#061;12);ax.set_ylabel(&#039;y&#039;, fontsize&#061;12)<br \/>\n    ax.grid(True, alpha&#061;0.3);ax.legend(loc&#061;&#039;best&#039;);ax.axis(&#039;equal&#039;)<br \/>\n    # \u53f3\u4e0a&#xff1a;\u66f2\u7387\u5206\u6790<br \/>\n    ax &#061; axes[0, 1];t_values &#061; np.linspace(0, 1, 100)<br \/>\n    curvature1 &#061; [compute_curvature(curve1_points, t) for t in t_values]<br \/>\n    curvature2 &#061; [compute_curvature(curve2_points, t) for t in t_values]<br \/>\n    ax.plot(t_values, curvature1, &#039;r-&#039;, linewidth&#061;2, label&#061;&#039;\u66f2\u7ebf1\u66f2\u7387&#039;)<br \/>\n    ax.plot(t_values, curvature2, &#039;b-&#039;, linewidth&#061;2, label&#061;&#039;\u66f2\u7ebf2\u66f2\u7387&#039;)<br \/>\n    # \u6807\u8bb0\u8fde\u63a5\u70b9\u5904\u7684\u66f2\u7387<br \/>\n    ax.scatter([1.0], [curvature1_end], s&#061;100, c&#061;&#039;red&#039;, edgecolors&#061;&#039;black&#039;, linewidth&#061;2, zorder&#061;5)<br \/>\n    ax.scatter([0.0], [curvature2_start], s&#061;100, c&#061;&#039;blue&#039;, edgecolors&#061;&#039;black&#039;, linewidth&#061;2, zorder&#061;5)<br \/>\n    ax.set_title(&#039;\u66f2\u7387\u5206\u6790&#039;, fontsize&#061;14, fontweight&#061;&#039;bold&#039;)<br \/>\n    ax.set_xlabel(&#039;\u53c2\u6570 t&#039;, fontsize&#061;12)<br \/>\n    ax.set_ylabel(r&#039;\u66f2\u7387 $\\\\kappa$&#039;, fontsize&#061;12)<br \/>\n    ax.grid(True, alpha&#061;0.3)<br \/>\n    ax.legend(loc&#061;&#039;best&#039;)<br \/>\n    # \u5de6\u4e0b&#xff1a;\u5bfc\u6570\u5206\u6790<br \/>\n    ax &#061; axes[1, 0]<br \/>\n    # \u8ba1\u7b97\u5bfc\u6570\u5927\u5c0f<br \/>\n    deriv1_mag &#061; [np.linalg.norm(compute_bezier_derivative(curve1_points, t, 1)) for t in t_values]<br \/>\n    deriv2_mag &#061; [np.linalg.norm(compute_bezier_derivative(curve2_points, t, 1)) for t in t_values]<br \/>\n    ax.plot(t_values, deriv1_mag, &#039;r-&#039;, linewidth&#061;2, label&#061;&#039;\u66f2\u7ebf1\u5bfc\u6570\u5927\u5c0f&#039;)<br \/>\n    ax.plot(t_values, deriv2_mag, &#039;b-&#039;, linewidth&#061;2, label&#061;&#039;\u66f2\u7ebf2\u5bfc\u6570\u5927\u5c0f&#039;)<br \/>\n    ax.set_title(&#039;\u4e00\u9636\u5bfc\u6570\u5927\u5c0f&#039;, fontsize&#061;14, fontweight&#061;&#039;bold&#039;)<br \/>\n    ax.set_xlabel(&#039;\u53c2\u6570 t&#039;, fontsize&#061;12)<br \/>\n    ax.set_ylabel(&#039;$|C\\\\&#039;(t)|$&#039;, fontsize&#061;12)<br \/>\n    ax.grid(True, alpha&#061;0.3)<br \/>\n    ax.legend(loc&#061;&#039;best&#039;)<br \/>\n    # \u53f3\u4e0b&#xff1a;\u8fde\u7eed\u6027\u7ed3\u679c<br \/>\n    ax &#061; axes[1, 1]<br \/>\n    ax.axis(&#039;off&#039;)<br \/>\n    # \u663e\u793a\u8fde\u7eed\u6027\u7ed3\u679c<br \/>\n    result_text &#061; &#034;\u8fde\u7eed\u6027\u5206\u6790\u7ed3\u679c:\\\\n\\\\n&#034;<br \/>\n    result_text &#043;&#061; f&#034;\u4f4d\u7f6e\u8fde\u7eed (C0): {&#039;\u6ee1\u8db3&#039; if C0_continuous else &#039;\u4e0d\u6ee1\u8db3&#039;}\\\\n&#034;<br \/>\n    result_text &#043;&#061; f&#034;\u5207\u7ebf\u65b9\u5411\u8fde\u7eed (G1): {&#039;\u6ee1\u8db3&#039; if G1_continuous else &#039;\u4e0d\u6ee1\u8db3&#039;}\\\\n&#034;<br \/>\n    result_text &#043;&#061; f&#034;\u5207\u7ebf\u8fde\u7eed (C1): {&#039;\u6ee1\u8db3&#039; if C1_continuous else &#039;\u4e0d\u6ee1\u8db3&#039;}\\\\n&#034;<br \/>\n    result_text &#043;&#061; f&#034;\u66f2\u7387\u8fde\u7eed (G2): {&#039;\u6ee1\u8db3&#039; if G2_continuous else &#039;\u4e0d\u6ee1\u8db3&#039;}\\\\n&#034;<br \/>\n    result_text &#043;&#061; f&#034;\u4e8c\u9636\u5bfc\u6570\u8fde\u7eed (C2): {&#039;\u6ee1\u8db3&#039; if C2_continuous else &#039;\u4e0d\u6ee1\u8db3&#039;}\\\\n\\\\n&#034;<br \/>\n    result_text &#043;&#061; &#034;\u8be6\u7ec6\u6570\u503c:\\\\n&#034;<br \/>\n    result_text &#043;&#061; f&#034;\u66f2\u7ebf1\u7ec8\u70b9\u4f4d\u7f6e: {C1_end}\\\\n&#034;<br \/>\n    result_text &#043;&#061; f&#034;\u66f2\u7ebf2\u8d77\u70b9\u4f4d\u7f6e: {C2_start}\\\\n\\\\n&#034;<br \/>\n    result_text &#043;&#061; f&#034;\u66f2\u7ebf1\u7ec8\u70b9\u5207\u7ebf: {C1_end_deriv1}\\\\n&#034;<br \/>\n    result_text &#043;&#061; f&#034;\u66f2\u7ebf2\u8d77\u70b9\u5207\u7ebf: {C2_start_deriv1}\\\\n\\\\n&#034;<br \/>\n    result_text &#043;&#061; f&#034;\u66f2\u7ebf1\u7ec8\u70b9\u66f2\u7387: {curvature1_end:.6f}\\\\n&#034;<br \/>\n    result_text &#043;&#061; f&#034;\u66f2\u7ebf2\u8d77\u70b9\u66f2\u7387: {curvature2_start:.6f}\\\\n\\\\n&#034;<br \/>\n    result_text &#043;&#061; f&#034;\u66f2\u7ebf1\u7ec8\u70b9\u4e8c\u9636\u5bfc\u6570: {C1_end_deriv2}\\\\n&#034;<br \/>\n    result_text &#043;&#061; f&#034;\u66f2\u7ebf2\u8d77\u70b9\u4e8c\u9636\u5bfc\u6570: {C2_start_deriv2}&#034;<br \/>\n    ax.text(0.1, 0.5, result_text, fontsize&#061;11, verticalalignment&#061;&#039;center&#039;, bbox&#061;dict(boxstyle&#061;&#039;round&#039;, facecolor&#061;&#039;wheat&#039;, alpha&#061;0.8))<br \/>\n    fig.suptitle(&#039;\u8d1d\u585e\u5c14\u66f2\u7ebf\u8fde\u7eed\u6027\u5206\u6790&#039;, fontsize&#061;16, fontweight&#061;&#039;bold&#039;)<br \/>\n    fig.tight_layout()<br \/>\n    return fig<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>def plot_continuity_examples():<br \/>\n    &#034;&#034;&#034;<br \/>\n    \u7ed8\u5236\u8fde\u7eed\u6027\u793a\u4f8b<br \/>\n    &#034;&#034;&#034;<br \/>\n    # \u793a\u4f8b1&#xff1a;C0\u8fde\u7eed<br \/>\n    curve1_c0 &#061; np.array([[0, 0], [1, 2], [2, 1]])<br \/>\n    curve2_c0 &#061; np.array([[2, 1], [3, 0], [4, 2]])<\/p>\n<p>    # \u793a\u4f8b2&#xff1a;G1\u8fde\u7eed<br \/>\n    curve1_g1 &#061; np.array([[0, 0], [1, 2], [2, 1]])<br \/>\n    curve2_g1 &#061; np.array([[2, 1], [3, 0.5], [4, 2]])  # P2, Q0, Q1\u5171\u7ebf<\/p>\n<p>    # \u793a\u4f8b3&#xff1a;C1\u8fde\u7eed<br \/>\n    curve1_c1 &#061; np.array([[0, 0], [1, 2], [2, 1]])<br \/>\n    # \u6ee1\u8db3 C1&#039;(1) &#061; C2&#039;(0)<br \/>\n    # n&#061;2, m&#061;2, \u9700\u8981 P2-P1 &#061; Q1-Q0<br \/>\n    Q0 &#061; np.array([2, 1])  # &#061; P2<br \/>\n    Q1 &#061; Q0 &#043; (curve1_c1[2] &#8211; curve1_c1[1])<br \/>\n    Q2 &#061; np.array([4, 1])<br \/>\n    curve2_c1 &#061; np.array([Q0, Q1, Q2])<\/p>\n<p>    # \u793a\u4f8b4&#xff1a;C2\u8fde\u7eed<br \/>\n    curve1_c2 &#061; np.array([[0, 0], [1, 1], [2, 2], [3, 1]])<br \/>\n    # \u6ee1\u8db3 C1&#039;&#039;(1) &#061; C2&#039;&#039;(0)<br \/>\n    # \u8fd9\u91cc\u7b80\u5316\u5904\u7406&#xff0c;\u4f7f\u7528\u76f8\u540c\u63a7\u5236\u70b9<br \/>\n    curve2_c2 &#061; np.array([[3, 1], [4, 0], [5, 1], [6, 2]])<\/p>\n<p>    # \u521b\u5efa\u56fe\u5f62<br \/>\n    fig, axes &#061; plt.subplots(2, 2, figsize&#061;(12, 10))<\/p>\n<p>    examples &#061; [<br \/>\n        (curve1_c0, curve2_c0, &#034;C0\u8fde\u7eed&#xff08;\u4ec5\u4f4d\u7f6e\u8fde\u7eed&#xff09;&#034;, axes[0, 0]),<br \/>\n        (curve1_g1, curve2_g1, &#034;G1\u8fde\u7eed&#xff08;\u5207\u7ebf\u65b9\u5411\u8fde\u7eed&#xff09;&#034;, axes[0, 1]),<br \/>\n        (curve1_c1, curve2_c1, &#034;C1\u8fde\u7eed&#xff08;\u5207\u7ebf\u8fde\u7eed&#xff09;&#034;, axes[1, 0]),<br \/>\n        (curve1_c2, curve2_c2, &#034;C2\u8fde\u7eed&#xff08;\u66f2\u7387\u8fde\u7eed&#xff09;&#034;, axes[1, 1])<br \/>\n    ]<\/p>\n<p>    for curve1, curve2, title, ax in examples:<br \/>\n        # \u8ba1\u7b97\u66f2\u7ebf<br \/>\n        curve1_pts &#061; compute_bezier_curve(curve1)<br \/>\n        curve2_pts &#061; compute_bezier_curve(curve2)<\/p>\n<p>        # \u7ed8\u5236\u63a7\u5236\u591a\u8fb9\u5f62<br \/>\n        ax.plot(curve1[:, 0], curve1[:, 1], &#039;ro-&#039;,<br \/>\n                linewidth&#061;1.5, markersize&#061;6, alpha&#061;0.7)<br \/>\n        ax.plot(curve2[:, 0], curve2[:, 1], &#039;bo-&#039;,<br \/>\n                linewidth&#061;1.5, markersize&#061;6, alpha&#061;0.7)<\/p>\n<p>        # \u7ed8\u5236\u66f2\u7ebf<br \/>\n        ax.plot(curve1_pts[:, 0], curve1_pts[:, 1], &#039;r-&#039;,<br \/>\n                linewidth&#061;2.5, alpha&#061;0.8)<br \/>\n        ax.plot(curve2_pts[:, 0], curve2_pts[:, 1], &#039;b-&#039;,<br \/>\n                linewidth&#061;2.5, alpha&#061;0.8)<\/p>\n<p>        # \u6807\u8bb0\u8fde\u63a5\u70b9<br \/>\n        joint_point &#061; curve1[-1]<br \/>\n        ax.scatter(joint_point[0], joint_point[1], s&#061;100,<br \/>\n                  color&#061;&#039;green&#039;, edgecolors&#061;&#039;black&#039;, linewidth&#061;2)<\/p>\n<p>        ax.set_title(title, fontsize&#061;12, fontweight&#061;&#039;bold&#039;)<br \/>\n        ax.set_xlabel(&#039;x&#039;, fontsize&#061;10)<br \/>\n        ax.set_ylabel(&#039;y&#039;, fontsize&#061;10)<br \/>\n        ax.grid(True, alpha&#061;0.3)<br \/>\n        ax.axis(&#039;equal&#039;)<\/p>\n<p>    fig.suptitle(&#039;\u8d1d\u585e\u5c14\u66f2\u7ebf\u8fde\u7eed\u6027\u793a\u4f8b&#039;, fontsize&#061;16, fontweight&#061;&#039;bold&#039;)<br \/>\n    fig.tight_layout()<br \/>\n    return fig<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h5 id=\"auto-33\">4.4 \u7ed3\u679c\u8f93\u51fa<\/h5>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p># \u6267\u884c\u8fde\u7eed\u6027\u5206\u6790<br \/>\nfig_continuity &#061; analyze_continuity(<br \/>\n    np.array([[0, 0], [1, 2], [2, 1]]),<br \/>\n    np.array([[2, 1], [3, 0.5], [4, 2]])<br \/>\n)<\/p>\n<p>fig_examples &#061; plot_continuity_examples()<br \/>\nfig_continuity<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"567\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/02\/20260222072608-699aaf90debd7.png\" width=\"687\" \/><\/p>\n<\/p>\n<p>651 msec<\/p>\n<\/p>\n<p>\u56fe5&#xff1a;\u8d1d\u585e\u5c14\u66f2\u7ebf\u8fde\u7eed\u6027\u5206\u6790\u3002\u663e\u793a\u4e86\u66f2\u7ebf\u62fc\u63a5\u3001\u66f2\u7387\u53d8\u5316\u3001\u5bfc\u6570\u5927\u5c0f\u548c\u8fde\u7eed\u6027\u5224\u65ad\u7ed3\u679c\u3002<\/p>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>fig_examples &#061; plot_continuity_examples()<br \/>\nfig_examples<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"564\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/02\/20260222072609-699aaf9106c0f.png\" width=\"687\" \/><\/p>\n<\/p>\n<p>557 msec<\/p>\n<\/p>\n<p>\u56fe6&#xff1a;\u4e0d\u540c\u8fde\u7eed\u6027\u7ea7\u522b\u7684\u8d1d\u585e\u5c14\u66f2\u7ebf\u62fc\u63a5\u793a\u4f8b\u3002<\/p>\n<h4 id=\"auto-34\">5. \u66f2\u7ebf\u6027\u8d28\u5206\u6790<\/h4>\n<h5 id=\"auto-35\">5.1 \u51f8\u5305\u6027\u8bc1\u660e<\/h5>\n<\/p>\n<h6>5.1.1 \u6570\u5b66\u8bc1\u660e<\/h6>\n<\/p>\n<p>\u51f8\u5305\u6027\u8bc1\u660e\u57fa\u4e8e\u4f2f\u6069\u65af\u5766\u57fa\u51fd\u6570\u7684\u6027\u8d28&#xff1a;<\/p>\n<\/p>\n<li>\n<p>\u975e\u8d1f\u6027&#xff1a;Bi,n(t)\u22650&#xff0c;\u5bf9\u00a0t\u2208[0,1]<\/p>\n<\/li>\n<li>\n<p>\u5355\u4f4d\u5206\u5272&#xff1a;\u2211i&#061;0nBi,n(t)&#061;1<\/p>\n<\/li>\n<p>\u56e0\u6b64&#xff0c;\u5bf9\u4e8e\u4efb\u610f\u00a0t\u2208[0,1]&#xff1a;<\/p>\n<p>C(t)&#061;\u2211i&#061;0nBi,n(t)\u2062Pi<\/p>\n<p>\u662f\u63a7\u5236\u70b9\u00a0Pi\u00a0\u7684\u51f8\u7ec4\u5408&#xff0c;\u6545\u00a0C(t)\u00a0\u4f4d\u4e8e\u63a7\u5236\u70b9\u7684\u51f8\u5305\u5185\u3002<\/p>\n<h5 id=\"auto-37\">5.2 \u53d8\u5dee\u7f29\u51cf\u6027<\/h5>\n<\/p>\n<h6>5.2.1 \u6570\u5b66\u5b9a\u4e49<\/h6>\n<\/p>\n<p>\u5bf9\u4e8e\u4efb\u4f55\u76f4\u7ebf\u00a0L&#xff0c;\u8bbe\u00a0NC\u00a0\u4e3a\u00a0L\u00a0\u4e0e\u8d1d\u585e\u5c14\u66f2\u7ebf\u00a0C\u00a0\u7684\u4ea4\u70b9\u6570&#xff0c;NP\u00a0\u4e3a\u00a0L\u00a0\u4e0e\u63a7\u5236\u591a\u8fb9\u5f62\u00a0P\u00a0\u7684\u4ea4\u70b9\u6570&#xff0c;\u5219&#xff1a;<\/p>\n<p>NC\u2264NP<\/p>\n<h5 id=\"auto-39\">5.3 \u4ee3\u7801\u5b9e\u73b0<\/h5>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>def line_intersection(p1, p2, line_slope, line_intercept):<br \/>\n    &#034;&#034;&#034;\u8ba1\u7b97\u7ebf\u6bb5\u4e0e\u76f4\u7ebf\u7684\u4ea4\u70b9&#034;&#034;&#034;<br \/>\n    x1, y1 &#061; p1<br \/>\n    x2, y2 &#061; p2<br \/>\n    # \u7ebf\u6bb5\u65b9\u7a0b\u53c2\u6570\u5f62\u5f0f<br \/>\n    dx &#061; x2 &#8211; x1<br \/>\n    dy &#061; y2 &#8211; y1<br \/>\n    if abs(dx) &lt; 1e-10:<br \/>\n        # \u5782\u76f4\u7ebf\u6bb5<br \/>\n        x &#061; x1<br \/>\n        y &#061; line_slope * x &#043; line_intercept<br \/>\n        if min(y1, y2) &lt;&#061; y &lt;&#061; max(y1, y2):<br \/>\n            return [(x, y)]<br \/>\n        return []<br \/>\n    # \u53c2\u6570t\u6ee1\u8db3 y1 &#043; t*dy &#061; line_slope*(x1 &#043; t*dx) &#043; line_intercept&#xff0c;\u89e3\u51fat<br \/>\n    t &#061; (line_slope*x1 &#043; line_intercept &#8211; y1) \/ (dy &#8211; line_slope*dx)<br \/>\n    if 0 &lt;&#061; t &lt;&#061; 1:<br \/>\n        x &#061; x1 &#043; t*dx<br \/>\n        y &#061; y1 &#043; t*dy<br \/>\n        return [(x, y)]<br \/>\n    return []<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>28 msec<\/p>\n<\/p>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>def point_in_hull(point, hull_points):<br \/>\n    &#034;&#034;&#034;\u68c0\u67e5\u70b9\u662f\u5426\u5728\u51f8\u5305\u5185&#xff08;\u5c04\u7ebf\u6cd5&#xff09;&#034;&#034;&#034;<br \/>\n    x, y &#061; point<br \/>\n    n &#061; len(hull_points) &#8211; 1<br \/>\n    inside &#061; False<br \/>\n    p1x, p1y &#061; hull_points[0]<br \/>\n    for i in range(1, n&#043;1):<br \/>\n        p2x, p2y &#061; hull_points[i % n]<br \/>\n        if y &gt; min(p1y, p2y):<br \/>\n            if y &lt;&#061; max(p1y, p2y):<br \/>\n                if x &lt;&#061; max(p1x, p2x):<br \/>\n                    if p1y !&#061; p2y:<br \/>\n                        xinters &#061; (y-p1y)*(p2x-p1x)\/(p2y-p1y)&#043;p1x<br \/>\n                    if p1x &#061;&#061; p2x or x &lt;&#061; xinters:<br \/>\n                        inside &#061; not inside<br \/>\n        p1x, p1y &#061; p2x, p2y<br \/>\n    return inside<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>28 msec<\/p>\n<\/p>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>def verify_convex_hull(control_points):<br \/>\n    &#034;&#034;&#034;<br \/>\n    \u9a8c\u8bc1\u8d1d\u585e\u5c14\u66f2\u7ebf\u7684\u51f8\u5305\u6027\u8d28<br \/>\n    &#034;&#034;&#034;<br \/>\n    control_points &#061; np.array(control_points)<br \/>\n    # \u8ba1\u7b97\u51f8\u5305<br \/>\n    from scipy.spatial import ConvexHull<br \/>\n    hull &#061; ConvexHull(control_points)<br \/>\n    # \u8ba1\u7b97\u8d1d\u585e\u5c14\u66f2\u7ebf<br \/>\n    t_values &#061; np.linspace(0, 1, 200)<br \/>\n    curve_points &#061; compute_bezier_curve(control_points, t_values)<br \/>\n    # \u521b\u5efa\u56fe\u5f62<br \/>\n    fig, axes &#061; plt.subplots(1, 2, figsize&#061;(12, 5))<br \/>\n    # \u5de6\u56fe&#xff1a;\u51f8\u5305\u6f14\u793a<br \/>\n    ax &#061; axes[0]<br \/>\n    # \u7ed8\u5236\u63a7\u5236\u591a\u8fb9\u5f62<br \/>\n    ax.plot(control_points[:, 0], control_points[:, 1], &#039;ro-&#039;, linewidth&#061;1.5, markersize&#061;8, alpha&#061;0.7, label&#061;&#039;\u63a7\u5236\u591a\u8fb9\u5f62&#039;)<br \/>\n    # \u7ed8\u5236\u51f8\u5305<br \/>\n    hull_points &#061; control_points[hull.vertices]<br \/>\n    hull_points &#061; np.vstack([hull_points, hull_points[0]])  # \u95ed\u5408<br \/>\n    ax.plot(hull_points[:, 0], hull_points[:, 1], &#039;g&#8211;&#039;, linewidth&#061;2, alpha&#061;0.7, label&#061;&#039;\u51f8\u5305&#039;)<br \/>\n    ax.fill(hull_points[:, 0], hull_points[:, 1], &#039;green&#039;, alpha&#061;0.2)<br \/>\n    # \u7ed8\u5236\u8d1d\u585e\u5c14\u66f2\u7ebf<br \/>\n    ax.plot(curve_points[:, 0], curve_points[:, 1], &#039;b-&#039;, linewidth&#061;2.5, label&#061;&#039;\u8d1d\u585e\u5c14\u66f2\u7ebf&#039;)<br \/>\n    # \u968f\u673a\u91c7\u6837\u66f2\u7ebf\u4e0a\u7684\u70b9<br \/>\n    np.random.seed(42)<br \/>\n    sample_t &#061; np.random.rand(50)<br \/>\n    sample_points &#061; np.array([de_casteljau_algorithm(control_points, t)<br \/>\n                             for t in sample_t])<br \/>\n    ax.scatter(sample_points[:, 0], sample_points[:, 1], s&#061;30, c&#061;&#039;orange&#039;, alpha&#061;0.6, label&#061;&#039;\u66f2\u7ebf\u91c7\u6837\u70b9&#039;)<br \/>\n    ax.set_title(&#039;\u51f8\u5305\u6027\u8d28\u6f14\u793a&#039;, fontsize&#061;14, fontweight&#061;&#039;bold&#039;)<br \/>\n    ax.set_xlabel(&#039;x&#039;, fontsize&#061;12)<br \/>\n    ax.set_ylabel(&#039;y&#039;, fontsize&#061;12)<br \/>\n    ax.grid(True, alpha&#061;0.3)<br \/>\n    ax.legend(loc&#061;&#039;best&#039;)<br \/>\n    ax.axis(&#039;equal&#039;)<br \/>\n    # \u53f3\u56fe&#xff1a;\u53d8\u5dee\u7f29\u51cf\u6027\u6f14\u793a<br \/>\n    ax &#061; axes[1]<br \/>\n    # \u7ed8\u5236\u63a7\u5236\u591a\u8fb9\u5f62<br \/>\n    ax.plot(control_points[:, 0], control_points[:, 1], &#039;ro-&#039;, linewidth&#061;1.5, markersize&#061;8, alpha&#061;0.7, label&#061;&#039;\u63a7\u5236\u591a\u8fb9\u5f62&#039;)<br \/>\n    # \u7ed8\u5236\u8d1d\u585e\u5c14\u66f2\u7ebf<br \/>\n    ax.plot(curve_points[:, 0], curve_points[:, 1], &#039;b-&#039;, linewidth&#061;2.5, label&#061;&#039;\u8d1d\u585e\u5c14\u66f2\u7ebf&#039;)<br \/>\n    # \u7ed8\u5236\u6d4b\u8bd5\u76f4\u7ebf<br \/>\n    x_min, x_max &#061; control_points[:, 0].min(), control_points[:, 0].max()<br \/>\n    y_min, y_max &#061; control_points[:, 1].min(), control_points[:, 1].max()<br \/>\n    # \u968f\u673a\u751f\u6210\u76f4\u7ebf<br \/>\n    np.random.seed(42)<br \/>\n    line_slope &#061; np.random.uniform(-2, 2)<br \/>\n    line_intercept &#061; np.random.uniform(y_min, y_max)<br \/>\n    line_x &#061; np.linspace(x_min &#8211; 1, x_max &#043; 1, 100)<br \/>\n    line_y &#061; line_slope * line_x &#043; line_intercept<br \/>\n    ax.plot(line_x, line_y, &#039;g&#8211;&#039;, linewidth&#061;2, alpha&#061;0.7, label&#061;&#039;\u6d4b\u8bd5\u76f4\u7ebf&#039;)<br \/>\n    # \u8ba1\u7b97\u63a7\u5236\u591a\u8fb9\u5f62\u4e0e\u76f4\u7ebf\u7684\u4ea4\u70b9&#xff08;\u7b80\u5316\u5904\u7406&#xff09;<br \/>\n    control_intersections &#061; []<br \/>\n    for i in range(len(control_points)-1):<br \/>\n        intersections &#061; line_intersection(<br \/>\n            control_points[i], control_points[i&#043;1],<br \/>\n            line_slope, line_intercept<br \/>\n        )<br \/>\n        control_intersections.extend(intersections)<br \/>\n    # \u4e0e\u8d1d\u585e\u5c14\u66f2\u7ebf\u7684\u8fd1\u4f3c\u4ea4\u70b9<br \/>\n    curve_intersections &#061; []<br \/>\n    for i in range(len(curve_points)-1):<br \/>\n        intersections &#061; line_intersection(<br \/>\n            curve_points[i], curve_points[i&#043;1],<br \/>\n            line_slope, line_intercept<br \/>\n        )<br \/>\n        curve_intersections.extend(intersections)<br \/>\n    # \u7ed8\u5236\u4ea4\u70b9<br \/>\n    if control_intersections:<br \/>\n        control_intersections &#061; np.array(control_intersections)<br \/>\n        ax.scatter(control_intersections[:, 0], control_intersections[:, 1], s&#061;100, c&#061;&#039;red&#039;, edgecolors&#061;&#039;black&#039;, linewidth&#061;2, label&#061;f&#039;\u63a7\u5236\u591a\u8fb9\u5f62\u4ea4\u70b9 ({len(control_intersections)}\u4e2a)&#039;)<br \/>\n    if curve_intersections:<br \/>\n        curve_intersections &#061; np.array(curve_intersections)<br \/>\n        ax.scatter(curve_intersections[:, 0], curve_intersections[:, 1], s&#061;100, c&#061;&#039;blue&#039;, marker&#061;&#039;s&#039;, edgecolors&#061;&#039;black&#039;, linewidth&#061;2,label&#061;f&#039;\u8d1d\u585e\u5c14\u66f2\u7ebf\u4ea4\u70b9 ({len(curve_intersections)}\u4e2a)&#039;)<br \/>\n    ax.set_title(&#039;\u53d8\u5dee\u7f29\u51cf\u6027\u6f14\u793a&#039;, fontsize&#061;14, fontweight&#061;&#039;bold&#039;)<br \/>\n    ax.set_xlabel(&#039;x&#039;, fontsize&#061;12)<br \/>\n    ax.set_ylabel(&#039;y&#039;, fontsize&#061;12)<br \/>\n    ax.grid(True, alpha&#061;0.3)<br \/>\n    ax.legend(loc&#061;&#039;best&#039;)<br \/>\n    ax.axis(&#039;equal&#039;)<br \/>\n    fig.suptitle(&#039;\u8d1d\u585e\u5c14\u66f2\u7ebf\u51e0\u4f55\u6027\u8d28\u9a8c\u8bc1&#039;, fontsize&#061;16, fontweight&#061;&#039;bold&#039;)<br \/>\n    fig.tight_layout()<br \/>\n    # \u8f93\u51fa\u9a8c\u8bc1\u7ed3\u679c<br \/>\n    print(&#034;\u51f8\u5305\u6027\u9a8c\u8bc1:&#034;)<br \/>\n    print(f&#034;  \u63a7\u5236\u70b9\u6570\u91cf: {len(control_points)}&#034;)<br \/>\n    print(f&#034;  \u51f8\u5305\u9876\u70b9\u6570\u91cf: {len(hull.vertices)}&#034;)<br \/>\n    print(f&#034;  \u66f2\u7ebf\u91c7\u6837\u70b9\u6570\u91cf: {len(sample_points)}&#034;)<br \/>\n    # \u68c0\u67e5\u91c7\u6837\u70b9\u662f\u5426\u5728\u51f8\u5305\u5185<br \/>\n    all_inside &#061; all(point_in_hull(point, hull_points) for point in sample_points)<br \/>\n    print(f&#034;  \u6240\u6709\u91c7\u6837\u70b9\u90fd\u5728\u51f8\u5305\u5185: {&#039;\u662f&#039; if all_inside else &#039;\u5426&#039;}&#034;)<br \/>\n    print(&#034;\\\\n\u53d8\u5dee\u7f29\u51cf\u6027\u9a8c\u8bc1:&#034;)<br \/>\n    print(f&#034;  \u76f4\u7ebf\u65b9\u7a0b: y &#061; {line_slope:.2f}x &#043; {line_intercept:.2f}&#034;)<br \/>\n    print(f&#034;  \u4e0e\u63a7\u5236\u591a\u8fb9\u5f62\u4ea4\u70b9\u6570: {len(control_intersections)}&#034;)<br \/>\n    print(f&#034;  \u4e0e\u8d1d\u585e\u5c14\u66f2\u7ebf\u4ea4\u70b9\u6570: {len(curve_intersections)}&#034;)<br \/>\n    print(f&#034;  \u4ea4\u70b9\u6570\u51cf\u5c11: {&#039;\u662f&#039; if len(curve_intersections) &lt;&#061; len(control_intersections) else &#039;\u5426&#039;}&#034;)<br \/>\n    return fig<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>92 msec<\/p>\n<\/p>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>def analyze_endpoint_properties(control_points):<br \/>\n    &#034;&#034;&#034;<br \/>\n    \u5206\u6790\u8d1d\u585e\u5c14\u66f2\u7ebf\u7684\u7aef\u70b9\u6027\u8d28<br \/>\n    &#034;&#034;&#034;<br \/>\n    control_points &#061; np.array(control_points)<br \/>\n    n &#061; len(control_points) &#8211; 1<br \/>\n    # \u8ba1\u7b97\u7aef\u70b9\u5904\u7684\u503c<br \/>\n    start_point &#061; compute_bezier_derivative(control_points, 0.0, 0)<br \/>\n    end_point &#061; compute_bezier_derivative(control_points, 1.0, 0)<br \/>\n    # \u8ba1\u7b97\u7aef\u70b9\u5bfc\u6570<br \/>\n    start_deriv &#061; compute_bezier_derivative(control_points, 0.0, 1)<br \/>\n    end_deriv &#061; compute_bezier_derivative(control_points, 1.0, 1)<br \/>\n    # \u8ba1\u7b97\u7aef\u70b9\u4e8c\u9636\u5bfc\u6570<br \/>\n    start_second_deriv &#061; compute_bezier_derivative(control_points, 0.0, 2)<br \/>\n    # \u7406\u8bba\u503c<br \/>\n    theoretical_start_deriv &#061; n * (control_points[1] &#8211; control_points[0])<br \/>\n    theoretical_end_deriv &#061; n * (control_points[-1] &#8211; control_points[-2])<br \/>\n    if n &gt;&#061; 2:<br \/>\n        theoretical_start_second_deriv &#061; n * (n-1) * (control_points[2] &#8211; 2*control_points[1] &#043; control_points[0])<br \/>\n    else:<br \/>\n        theoretical_start_second_deriv &#061; np.zeros_like(control_points[0])<br \/>\n    # \u521b\u5efa\u56fe\u5f62<br \/>\n    fig, axes &#061; plt.subplots(1, 2, figsize&#061;(12, 5))<br \/>\n    # \u5de6\u56fe&#xff1a;\u66f2\u7ebf\u548c\u7aef\u70b9<br \/>\n    ax &#061; axes[0]<br \/>\n    # \u8ba1\u7b97\u66f2\u7ebf<br \/>\n    curve_points &#061; compute_bezier_curve(control_points)<br \/>\n    # \u7ed8\u5236\u63a7\u5236\u591a\u8fb9\u5f62<br \/>\n    ax.plot(control_points[:, 0], control_points[:, 1], &#039;ro-&#039;, linewidth&#061;1.5, markersize&#061;8, alpha&#061;0.7, label&#061;&#039;\u63a7\u5236\u591a\u8fb9\u5f62&#039;)<br \/>\n    # \u7ed8\u5236\u63a7\u5236\u70b9\u6807\u7b7e<br \/>\n    for i, point in enumerate(control_points):<br \/>\n        ax.text(point[0]&#043;0.05, point[1]&#043;0.05, f&#039;P{i}&#039;, fontsize&#061;12, fontweight&#061;&#039;bold&#039;)<br \/>\n    # \u7ed8\u5236\u8d1d\u585e\u5c14\u66f2\u7ebf<br \/>\n    ax.plot(curve_points[:, 0], curve_points[:, 1], &#039;b-&#039;, linewidth&#061;2.5, label&#061;&#039;\u8d1d\u585e\u5c14\u66f2\u7ebf&#039;)<br \/>\n    # \u6807\u8bb0\u8d77\u70b9\u548c\u7ec8\u70b9<br \/>\n    ax.scatter([start_point[0], end_point[0]], [start_point[1], end_point[1]], s&#061;150, c&#061;[&#039;green&#039;, &#039;purple&#039;], edgecolors&#061;&#039;black&#039;, linewidth&#061;2, zorder&#061;5, label&#061;[&#039;\u8d77\u70b9&#039;, &#039;\u7ec8\u70b9&#039;])<br \/>\n    # \u7ed8\u5236\u7aef\u70b9\u5207\u7ebf<br \/>\n    scale &#061; 0.5<br \/>\n    ax.arrow(start_point[0], start_point[1], start_deriv[0]*scale\/n, start_deriv[1]*scale\/n, head_width&#061;0.08, head_length&#061;0.12, fc&#061;&#039;green&#039;, ec&#061;&#039;green&#039;, linewidth&#061;2, label&#061;&#039;\u8d77\u70b9\u5207\u7ebf&#039;)<br \/>\n    ax.arrow(end_point[0], end_point[1], end_deriv[0]*scale\/n, end_deriv[1]*scale\/n, head_width&#061;0.08, head_length&#061;0.12, fc&#061;&#039;purple&#039;, ec&#061;&#039;purple&#039;, linewidth&#061;2, label&#061;&#039;\u7ec8\u70b9\u5207\u7ebf&#039;)<br \/>\n    ax.set_title(&#039;\u8d1d\u585e\u5c14\u66f2\u7ebf\u7aef\u70b9\u6027\u8d28&#039;, fontsize&#061;14, fontweight&#061;&#039;bold&#039;)<br \/>\n    ax.set_xlabel(&#039;x&#039;, fontsize&#061;12)<br \/>\n    ax.set_ylabel(&#039;y&#039;, fontsize&#061;12)<br \/>\n    ax.grid(True, alpha&#061;0.3)<br \/>\n    ax.legend(loc&#061;&#039;best&#039;)<br \/>\n    ax.axis(&#039;equal&#039;)<br \/>\n    # \u53f3\u56fe&#xff1a;\u6027\u8d28\u9a8c\u8bc1\u7ed3\u679c<br \/>\n    ax &#061; axes[1]<br \/>\n    ax.axis(&#039;off&#039;)<br \/>\n    # \u663e\u793a\u9a8c\u8bc1\u7ed3\u679c<br \/>\n    result_text &#061; &#034;\u7aef\u70b9\u6027\u8d28\u9a8c\u8bc1:\\\\n\\\\n&#034;<br \/>\n    result_text &#043;&#061; f&#034;\u66f2\u7ebf\u6b21\u6570: n &#061; {n}\\\\n\\\\n&#034;<br \/>\n    result_text &#043;&#061; &#034;1. \u7aef\u70b9\u63d2\u503c\u6027\u8d28:\\\\n&#034;<br \/>\n    result_text &#043;&#061; f&#034;   C(0) &#061; [{start_point[0]:.4f}, {start_point[1]:.4f}]\\\\n&#034;<br \/>\n    result_text &#043;&#061; f&#034;   P0 &#061; [{control_points[0,0]:.4f}, {control_points[0,1]:.4f}]\\\\n&#034;<br \/>\n    result_text &#043;&#061; f&#034;   \u76f8\u7b49: {&#039;\u662f&#039; if np.allclose(start_point, control_points[0]) else &#039;\u5426&#039;}\\\\n\\\\n&#034;<br \/>\n    result_text &#043;&#061; f&#034;   C(1) &#061; [{end_point[0]:.4f}, {end_point[1]:.4f}]\\\\n&#034;<br \/>\n    result_text &#043;&#061; f&#034;   P\u2099 &#061; [{control_points[-1,0]:.4f}, {control_points[-1,1]:.4f}]\\\\n&#034;<br \/>\n    result_text &#043;&#061; f&#034;   \u76f8\u7b49: {&#039;\u662f&#039; if np.allclose(end_point, control_points[-1]) else &#039;\u5426&#039;}\\\\n\\\\n&#034;<br \/>\n    result_text &#043;&#061; &#034;2. \u7aef\u70b9\u5207\u7ebf\u6027\u8d28:\\\\n&#034;<br \/>\n    result_text &#043;&#061; f&#034;   C&#039;(0) &#061; [{start_deriv[0]:.4f}, {start_deriv[1]:.4f}]\\\\n&#034;<br \/>\n    result_text &#043;&#061; f&#034;   n(P\u2081-P0) &#061; [{theoretical_start_deriv[0]:.4f}, {theoretical_start_deriv[1]:.4f}]\\\\n&#034;<br \/>\n    result_text &#043;&#061; f&#034;   \u76f8\u7b49: {&#039;\u662f&#039; if np.allclose(start_deriv, theoretical_start_deriv) else &#039;\u5426&#039;}\\\\n\\\\n&#034;<br \/>\n    result_text &#043;&#061; f&#034;   C&#039;(1) &#061; [{end_deriv[0]:.4f}, {end_deriv[1]:.4f}]\\\\n&#034;<br \/>\n    result_text &#043;&#061; f&#034;   n(P\u2099-P\u2099\u208b\u2081) &#061; [{theoretical_end_deriv[0]:.4f}, {theoretical_end_deriv[1]:.4f}]\\\\n&#034;<br \/>\n    result_text &#043;&#061; f&#034;   \u76f8\u7b49: {&#039;\u662f&#039; if np.allclose(end_deriv, theoretical_end_deriv) else &#039;\u5426&#039;}\\\\n\\\\n&#034;<br \/>\n    if n &gt;&#061; 2:<br \/>\n        result_text &#043;&#061; &#034;3. \u7aef\u70b9\u4e8c\u9636\u5bfc\u6570:\\\\n&#034;<br \/>\n        result_text &#043;&#061; f&#034;   C&#039;&#039;(0) &#061; [{start_second_deriv[0]:.4f}, {start_second_deriv[1]:.4f}]\\\\n&#034;<br \/>\n        result_text &#043;&#061; f&#034;   n(n-1)(P\u2082-2P\u2081&#043;P0) &#061; [{theoretical_start_second_deriv[0]:.4f}, {theoretical_start_second_deriv[1]:.4f}]\\\\n&#034;<br \/>\n        result_text &#043;&#061; f&#034;   \u76f8\u7b49: {&#039;\u662f&#039; if np.allclose(start_second_deriv, theoretical_start_second_deriv) else &#039;\u5426&#039;}\\\\n&#034;<br \/>\n    ax.text(0.1, 0.5, result_text, fontsize&#061;11, verticalalignment&#061;&#039;center&#039;, bbox&#061;dict(boxstyle&#061;&#039;round&#039;, facecolor&#061;&#039;wheat&#039;, alpha&#061;0.8))<br \/>\n    fig.suptitle(&#039;\u8d1d\u585e\u5c14\u66f2\u7ebf\u7aef\u70b9\u6027\u8d28\u9a8c\u8bc1&#039;, fontsize&#061;16, fontweight&#061;&#039;bold&#039;)<br \/>\n    fig.tight_layout()<br \/>\n    return fig<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h5 id=\"auto-40\">5.4 \u7ed3\u679c\u8f93\u51fa<\/h5>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p># \u6267\u884c\u6027\u8d28\u9a8c\u8bc1<br \/>\ncontrol_points &#061; np.array([[0, 0], [1, 3], [3, -1], [4, 2]])<br \/>\nfig_convex &#061; verify_convex_hull(control_points)<br \/>\nfig_convex<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"546\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/02\/20260222072609-699aaf9123f01.png\" width=\"691\" \/><\/p>\n<\/p>\n<\/p>\n<p>474 msec<\/p>\n<\/p>\n<p>\u56fe7&#xff1a;\u8d1d\u585e\u5c14\u66f2\u7ebf\u7684\u51f8\u5305\u6027\u548c\u53d8\u5dee\u7f29\u51cf\u6027\u9a8c\u8bc1\u3002\u5de6\u56fe\u663e\u793a\u66f2\u7ebf\u4f4d\u4e8e\u63a7\u5236\u70b9\u7684\u51f8\u5305\u5185&#xff0c;\u53f3\u56fe\u9a8c\u8bc1\u53d8\u5dee\u7f29\u51cf\u6027\u3002<\/p>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>fig_endpoints &#061; analyze_endpoint_properties(control_points)<br \/>\nfig_endpoints<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"282\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/02\/20260222072609-699aaf9142c45.png\" width=\"587\" \/><\/p>\n<\/p>\n<p>222 msec<\/p>\n<\/p>\n<p>\u56fe8&#xff1a;\u8d1d\u585e\u5c14\u66f2\u7ebf\u7aef\u70b9\u6027\u8d28\u9a8c\u8bc1\u3002\u663e\u793a\u4e86\u7aef\u70b9\u63d2\u503c\u3001\u7aef\u70b9\u5207\u7ebf\u548c\u7aef\u70b9\u66f2\u7387\u6027\u8d28\u3002<\/p>\n<h4 id=\"auto-41\">6. \u5e94\u7528\u6848\u4f8b<\/h4>\n<h5 id=\"auto-42\">6.1 \u56fe\u5f62\u8bbe\u8ba1<\/h5>\n<p>\u4f7f\u7528\u6807\u51c6\u8d1d\u585e\u5c14\u66f2\u7ebf&#xff0c;\u8ba1\u7b97\u7b80\u5355<\/p>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>def bezier_application_graphics_design():<br \/>\n    &#034;&#034;&#034;<br \/>\n    \u8d1d\u585e\u5c14\u66f2\u7ebf\u5e94\u7528\u5b9e\u4f8b&#xff1a;\u56fe\u5f62\u8bbe\u8ba1<br \/>\n    \u4f7f\u7528\u6807\u51c6\u8d1d\u585e\u5c14\u66f2\u7ebf\u521b\u5efa\u7b80\u5355\u56fe\u5f62<br \/>\n    &#034;&#034;&#034;<br \/>\n    # \u521b\u5efa\u56fe\u5f62<br \/>\n    fig, axes &#061; plt.subplots(2, 2, figsize&#061;(12, 10))<\/p>\n<p>    # \u5de6\u4e0a&#xff1a;\u7b80\u5355\u5f62\u72b6 &#8211; \u5fc3\u5f62<br \/>\n    ax &#061; axes[0, 0]<br \/>\n    heart_points &#061; [<br \/>\n        np.array([[0, 0], [0.7, 1.0], [1, 0]]),<br \/>\n        np.array([[1, 0], [1.0, -0.5], [0.5, -1]]),<br \/>\n        np.array([[0.5, -1], [0, -1.5], [-0.5, -1]]),<br \/>\n        np.array([[-0.5, -1], [-1, -0.5], [-1, 0]]),<br \/>\n        np.array([[-1, 0], [-0.7, 1.0], [0, 0]])<br \/>\n    ]<\/p>\n<p>    for points in heart_points:<br \/>\n        curve &#061; compute_bezier_curve(points)<br \/>\n        ax.plot(curve[:, 0], curve[:, 1], &#039;r-&#039;, linewidth&#061;2)<br \/>\n        ax.plot(points[:, 0], points[:, 1], &#039;ko&#039;, markersize&#061;4, alpha&#061;0.5)<\/p>\n<p>    ax.set_xlim(-1.5, 1.5)<br \/>\n    ax.set_ylim(-1.5, 1.5)<br \/>\n    ax.set_title(&#039;\u5fc3\u5f62\u8bbe\u8ba1 (\u6807\u51c6\u8d1d\u585e\u5c14\u66f2\u7ebf)&#039;, fontsize&#061;12, fontweight&#061;&#039;bold&#039;)<br \/>\n    ax.grid(True, alpha&#061;0.3)<br \/>\n    ax.axis(&#039;equal&#039;)<\/p>\n<p>    # \u53f3\u4e0a&#xff1a;Logo\u8bbe\u8ba1 &#8211; \u6ce2\u6d6a<br \/>\n    ax &#061; axes[0, 1]<br \/>\n    wave_points &#061; [<br \/>\n        np.array([[0, 0], [0.5, 0.8], [1, 0]]),<br \/>\n        np.array([[1, 0], [1.5, -0.8], [2, 0]]),<br \/>\n        np.array([[2, 0], [2.5, 0.8], [3, 0]])<br \/>\n    ]<\/p>\n<p>    for points in wave_points:<br \/>\n        curve &#061; compute_bezier_curve(points)<br \/>\n        ax.plot(curve[:, 0], curve[:, 1], &#039;b-&#039;, linewidth&#061;3)<br \/>\n        ax.plot(points[:, 0], points[:, 1], &#039;go&#039;, markersize&#061;4, alpha&#061;0.5)<\/p>\n<p>    ax.set_xlim(-0.2, 3.2)<br \/>\n    ax.set_ylim(-1, 1)<br \/>\n    ax.set_title(&#039;\u6ce2\u6d6aLogo\u8bbe\u8ba1&#039;, fontsize&#061;12, fontweight&#061;&#039;bold&#039;)<br \/>\n    ax.grid(True, alpha&#061;0.3)<br \/>\n    ax.axis(&#039;equal&#039;)<\/p>\n<p>    # \u5de6\u4e0b&#xff1a;\u88c5\u9970\u56fe\u6848 &#8211; \u82b1\u74e3<br \/>\n    ax &#061; axes[1, 0]<br \/>\n    petal_points &#061; [<br \/>\n        np.array([[0, 0], [0.7, 0.5], [1, 0]]),<br \/>\n        np.array([[1, 0], [0.7, -0.5], [0, 0]])<br \/>\n    ]<\/p>\n<p>    # \u65cb\u8f6c\u521b\u5efa\u591a\u4e2a\u82b1\u74e3<br \/>\n    angles &#061; np.linspace(0, 2*np.pi, 6, endpoint&#061;False)<br \/>\n    for angle in angles:<br \/>\n        rotation_matrix &#061; np.array([<br \/>\n            [np.cos(angle), -np.sin(angle)],<br \/>\n            [np.sin(angle), np.cos(angle)]<br \/>\n        ])<\/p>\n<p>        for points in petal_points:<br \/>\n            rotated_points &#061; points &#064; rotation_matrix.T<br \/>\n            curve &#061; compute_bezier_curve(rotated_points)<br \/>\n            ax.plot(curve[:, 0], curve[:, 1], &#039;m-&#039;, linewidth&#061;2, alpha&#061;0.8)<\/p>\n<p>    ax.set_xlim(-1.2, 1.2)<br \/>\n    ax.set_ylim(-1.2, 1.2)<br \/>\n    ax.set_title(&#039;\u82b1\u74e3\u88c5\u9970\u56fe\u6848&#039;, fontsize&#061;12, fontweight&#061;&#039;bold&#039;)<br \/>\n    ax.grid(True, alpha&#061;0.3)<br \/>\n    ax.axis(&#039;equal&#039;)<\/p>\n<p>    # \u53f3\u4e0b&#xff1a;\u56fe\u6807\u8bbe\u8ba1 &#8211; \u4e91\u6735<br \/>\n    ax &#061; axes[1, 1]<br \/>\n    cloud_points &#061; [<br \/>\n        np.array([[0, 0], [0.3, 0.5], [0.7, 0.5], [1, 0]]),<br \/>\n        np.array([[0.3, 0], [0.5, 0.3], [0.7, 0]]),<br \/>\n        np.array([[0.7, 0], [0.9, 0.3], [1.1, 0]]),<br \/>\n        np.array([[0.9, 0], [1.1, 0.2], [1.3, 0]])<br \/>\n    ]<\/p>\n<p>    for points in cloud_points:<br \/>\n        curve &#061; compute_bezier_curve(points)<br \/>\n        ax.plot(curve[:, 0], curve[:, 1], &#039;c-&#039;, linewidth&#061;2)<br \/>\n        ax.plot(points[:, 0], points[:, 1], &#039;bo&#039;, markersize&#061;3, alpha&#061;0.5)<\/p>\n<p>    ax.fill_between([-0.2, 1.5], -0.2, -0.2, color&#061;&#039;lightblue&#039;, alpha&#061;0.3)<br \/>\n    ax.set_xlim(-0.2, 1.5)<br \/>\n    ax.set_ylim(-0.2, 0.7)<br \/>\n    ax.set_title(&#039;\u4e91\u6735\u56fe\u6807\u8bbe\u8ba1&#039;, fontsize&#061;12, fontweight&#061;&#039;bold&#039;)<br \/>\n    ax.grid(True, alpha&#061;0.3)<br \/>\n    ax.axis(&#039;equal&#039;)<\/p>\n<p>    fig.suptitle(&#039;\u56fe\u5f62\u8bbe\u8ba1\u5e94\u7528&#xff1a;\u6807\u51c6\u8d1d\u585e\u5c14\u66f2\u7ebf&#039;, fontsize&#061;16, fontweight&#061;&#039;bold&#039;)<br \/>\n    fig.tight_layout()<br \/>\n    return fig<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p># \u6267\u884c\u56fe\u5f62\u8bbe\u8ba1\u6848\u4f8b<br \/>\nfig_graphics &#061; bezier_application_graphics_design()<br \/>\nfig_graphics<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"564\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/02\/20260222072609-699aaf9158116.png\" width=\"676\" \/><\/p>\n<\/p>\n<h5 id=\"auto-43\">6.2 \u5b57\u4f53\u8bbe\u8ba1<\/h5>\n<p>\u4f7f\u7528\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u7cbe\u786e\u8868\u793a\u5706\u5f27<\/p>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>def bezier_application_font_design():<br \/>\n    &#034;&#034;&#034;<br \/>\n    \u8d1d\u585e\u5c14\u66f2\u7ebf\u5e94\u7528\u5b9e\u4f8b&#xff1a;\u5b57\u4f53\u8bbe\u8ba1<br \/>\n    \u4f7f\u7528\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u7cbe\u786e\u8868\u793a\u5706\u5f27\u548c\u590d\u6742\u66f2\u7ebf<br \/>\n    &#034;&#034;&#034;<br \/>\n    # \u521b\u5efa\u56fe\u5f62<br \/>\n    fig, axes &#061; plt.subplots(2, 3, figsize&#061;(15, 10))<br \/>\n    # \u5de6\u4e0a&#xff1a;\u5b57\u6bcd&#039;S&#039;\u8bbe\u8ba1<br \/>\n    ax &#061; axes[0, 0]<br \/>\n    # \u4f7f\u7528\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u7cbe\u786e\u8868\u793a\u5706\u5f27\u90e8\u5206<br \/>\n    # \u4e0a\u534a\u5706\u90e8\u5206<br \/>\n    theta &#061; np.pi \/ 4<br \/>\n    r &#061; 0.5<br \/>\n    P0 &#061; np.array([r * np.cos(theta), r * np.sin(theta)])<br \/>\n    P1 &#061; np.array([r * np.tan(theta\/2), r])<br \/>\n    P2 &#061; np.array([0, r])<br \/>\n    P3 &#061; np.array([-r * np.tan(theta\/2), r])<br \/>\n    P4 &#061; np.array([-r * np.cos(theta), r * np.sin(theta)])<br \/>\n    control_points1 &#061; np.array([P0, P1, P2, P3, P4])<br \/>\n    weights1 &#061; np.array([1, np.cos(theta\/2),1, np.cos(theta\/2), 1])<br \/>\n    curve1 &#061; compute_rational_bezier_curve(control_points1, weights1)<br \/>\n    # \u7ed8\u5236\u4e0a\u534a\u5706\u66f2\u7ebf\u53ca\u5176\u63a7\u5236\u70b9<br \/>\n    ax.plot(curve1[:, 0], curve1[:, 1], &#039;b-&#039;, linewidth&#061;3, label&#061;&#034;\u4e0a\u534a\u5706&#034;)<br \/>\n    ax.plot(control_points1[:, 0], control_points1[:, 1], &#039;ro-&#039;, linewidth&#061;1, markersize&#061;6, alpha&#061;0.7, label&#061;&#034;\u4e0a\u534a\u5706\u63a7\u5236\u70b9&#034;)<br \/>\n    # \u4e0b\u534a\u5706\u90e8\u5206<br \/>\n    P5 &#061; np.array([r * np.cos(theta), -r * np.sin(theta)])<br \/>\n    P6 &#061; np.array([r * np.tan(theta\/2), -r])<br \/>\n    P7 &#061; np.array([0, -r])<br \/>\n    P8 &#061; np.array([-r * np.tan(theta\/2), -r])<br \/>\n    P9 &#061; np.array([-r * np.cos(theta), -r * np.sin(theta)])<br \/>\n    control_points3 &#061; np.array([P5, P6, P7, P8, P9])<br \/>\n    curve3 &#061; compute_bezier_curve(control_points3)<br \/>\n    # \u7ed8\u5236\u4e0b\u534a\u5706\u66f2\u7ebf\u53ca\u5176\u63a7\u5236\u70b9<br \/>\n    ax.plot(curve3[:, 0], curve3[:, 1], &#039;m-&#039;, linewidth&#061;3, label&#061;&#034;\u4e0b\u534a\u5706&#034;)<br \/>\n    ax.plot(control_points3[:, 0], control_points3[:, 1], &#039;mo-&#039;, linewidth&#061;1, markersize&#061;6, alpha&#061;0.7, label&#061;&#034;\u4e0b\u534a\u5706\u63a7\u5236\u70b9&#034;)<br \/>\n    # \u4e2d\u95f4\u90e8\u5206<br \/>\n    control_points2 &#061; np.array([P4, [-r*np.cos(theta), 0], [r*np.cos(theta), 0], P5])<br \/>\n    curve2 &#061; compute_bezier_curve(control_points2)<br \/>\n    # \u7ed8\u5236\u4e2d\u95f4\u66f2\u7ebf\u53ca\u5176\u63a7\u5236\u70b9<br \/>\n    ax.plot(curve2[:, 0], curve2[:, 1], &#039;g-&#039;, linewidth&#061;3, label&#061;&#034;\u4e2d\u95f4\u8fc7\u6e21&#034;)<br \/>\n    ax.plot(control_points2[:, 0], control_points2[:, 1], &#039;go-&#039;, linewidth&#061;1, markersize&#061;6, alpha&#061;0.7, label&#061;&#034;\u4e2d\u95f4\u63a7\u5236\u70b9&#034;)<br \/>\n    ax.set_xlim(-0.1, 1)<br \/>\n    ax.set_ylim(-0.6, 0.6)<br \/>\n    ax.set_title(&#039;\u5b57\u6bcd&#034;S&#034;\u8bbe\u8ba1 (\u542b\u5706\u5f27)&#039;, fontsize&#061;12, fontweight&#061;&#039;bold&#039;)<br \/>\n    ax.grid(True, alpha&#061;0.3)<br \/>\n    ax.axis(&#039;equal&#039;)<br \/>\n    # \u4e2d\u4e0a&#xff1a;\u5b57\u6bcd&#039;A&#039;\u8bbe\u8ba1<br \/>\n    ax &#061; axes[0, 1]<br \/>\n    # \u5de6\u659c\u7ebf<br \/>\n    control_points_a1 &#061; np.array([[0, 0], [0.2, 0.8], [0.4, 1]])<br \/>\n    curve_a1 &#061; compute_bezier_curve(control_points_a1)<br \/>\n    # \u53f3\u659c\u7ebf<br \/>\n    control_points_a2 &#061; np.array([[0.4, 1], [0.6, 0.8], [0.8, 0]])<br \/>\n    curve_a2 &#061; compute_bezier_curve(control_points_a2)<br \/>\n    # \u6a2a\u7ebf<br \/>\n    control_points_a3 &#061; np.array([[0.1, 0.5], [0.4, 0.55], [0.7, 0.5]])<br \/>\n    curve_a3 &#061; compute_bezier_curve(control_points_a3)<br \/>\n    ax.plot(curve_a1[:, 0], curve_a1[:, 1], &#039;r-&#039;, linewidth&#061;3)<br \/>\n    ax.plot(curve_a2[:, 0], curve_a2[:, 1], &#039;r-&#039;, linewidth&#061;3)<br \/>\n    ax.plot(curve_a3[:, 0], curve_a3[:, 1], &#039;r-&#039;, linewidth&#061;3)<br \/>\n    ax.set_xlim(-0.1, 0.9)<br \/>\n    ax.set_ylim(-0.1, 1.1)<br \/>\n    ax.set_title(&#039;\u5b57\u6bcd&#034;A&#034;\u8bbe\u8ba1&#039;, fontsize&#061;12, fontweight&#061;&#039;bold&#039;)<br \/>\n    ax.grid(True, alpha&#061;0.3)<br \/>\n    ax.axis(&#039;equal&#039;)<br \/>\n    # \u53f3\u4e0a&#xff1a;\u7cbe\u786e\u5706\u5f27\u6bd4\u8f83<br \/>\n    ax &#061; axes[0, 2]<br \/>\n    # \u4f7f\u7528\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u7cbe\u786e\u8868\u793a90\u5ea6\u5706\u5f27<br \/>\n    theta &#061; np.pi\/2<br \/>\n    r &#061; 0.5<br \/>\n    center &#061; np.array([0, 0])<br \/>\n    # \u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u8868\u793a<br \/>\n    w &#061; np.cos(theta\/4)  # \u6743\u91cd<br \/>\n    # \u7b2c\u4e00\u4e2a1\/4\u5706<br \/>\n    P0 &#061; center &#043; np.array([r, 0])<br \/>\n    P1 &#061; center &#043; np.array([r, r * np.tan(theta\/4)])<br \/>\n    P2 &#061; center &#043; np.array([r*np.cos(theta\/2), r*np.sin(theta\/2)])<br \/>\n    control_rational &#061; np.array([P0, P1, P2])<br \/>\n    weights &#061; np.array([1, w, 1])<br \/>\n    curve_rational &#061; compute_rational_bezier_curve(control_rational, weights)<br \/>\n    # \u6807\u51c6\u8d1d\u585e\u5c14\u66f2\u7ebf\u8fd1\u4f3c<br \/>\n    control_standard &#061; np.array([P0, P1, P2])<br \/>\n    curve_standard &#061; compute_bezier_curve(control_standard)<br \/>\n    # \u7cbe\u786e\u5706\u5f27<br \/>\n    angles &#061; np.linspace(0, theta\/2, 50)<br \/>\n    exact_arc &#061; np.column_stack([r*np.cos(angles), r*np.sin(angles)])<br \/>\n    ax.plot(exact_arc[:, 0], exact_arc[:, 1], &#039;g-&#039;, linewidth&#061;2, label&#061;&#039;\u7cbe\u786e\u5706\u5f27&#039;)<br \/>\n    ax.plot(curve_rational[:, 0], curve_rational[:, 1], &#039;b&#8211;&#039;, linewidth&#061;2, label&#061;&#039;\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf&#039;)<br \/>\n    ax.plot(curve_standard[:, 0], curve_standard[:, 1], &#039;r:&#039;, linewidth&#061;2, label&#061;&#039;\u6807\u51c6\u8d1d\u585e\u5c14\u66f2\u7ebf&#039;)<br \/>\n    ax.set_xlim(-0.1, 0.6)<br \/>\n    ax.set_ylim(-0.1, 0.6)<br \/>\n    ax.set_title(&#039;\u5706\u5f27\u7cbe\u786e\u8868\u793a\u6bd4\u8f83&#039;, fontsize&#061;12, fontweight&#061;&#039;bold&#039;)<br \/>\n    ax.legend(fontsize&#061;9)<br \/>\n    ax.grid(True, alpha&#061;0.3)<br \/>\n    ax.axis(&#039;equal&#039;)<br \/>\n    # \u5de6\u4e0b&#xff1a;\u4e2d\u6587\u5b57\u4f53\u8bbe\u8ba1\u793a\u4f8b<br \/>\n    ax &#061; axes[1, 0]<br \/>\n    # &#034;\u4e2d&#034;\u5b57\u8bbe\u8ba1<br \/>\n    # \u7ad6\u7ebf<br \/>\n    control_zhong1 &#061; np.array([[0.3, 0], [0.3, 0.3], [0.3, 0.6]])<br \/>\n    curve_zhong1 &#061; compute_bezier_curve(control_zhong1)<br \/>\n    # \u6a2a\u7ebf<br \/>\n    control_zhong2 &#061; np.array([[0, 0.2], [0.3, 0.2], [0.6, 0.2]])<br \/>\n    curve_zhong2 &#061; compute_bezier_curve(control_zhong2)<br \/>\n    # \u6a2a\u7ebf2<br \/>\n    control_zhong3 &#061; np.array([[0, 0.4], [0.3, 0.4], [0.6, 0.4]])<br \/>\n    curve_zhong3 &#061; compute_bezier_curve(control_zhong3)<br \/>\n    # \u7ad6\u7ebf4<br \/>\n    control_zhong4 &#061; np.array([[0.0, 0.2], [0.0, 0.3], [0.0, 0.4]])<br \/>\n    curve_zhong4 &#061; compute_bezier_curve(control_zhong4)<br \/>\n    # \u7ad6\u7ebf5<br \/>\n    control_zhong5 &#061; np.array([[0.6, 0.2], [0.6, 0.3], [0.6, 0.4]])<br \/>\n    curve_zhong5 &#061; compute_bezier_curve(control_zhong5)<br \/>\n    ax.plot(curve_zhong1[:, 0], curve_zhong1[:, 1], &#039;k-&#039;, linewidth&#061;3)<br \/>\n    ax.plot(curve_zhong2[:, 0], curve_zhong2[:, 1], &#039;k-&#039;, linewidth&#061;3)<br \/>\n    ax.plot(curve_zhong3[:, 0], curve_zhong3[:, 1], &#039;k-&#039;, linewidth&#061;3)<br \/>\n    ax.plot(curve_zhong4[:, 0], curve_zhong4[:, 1], &#039;k-&#039;, linewidth&#061;3)<br \/>\n    ax.plot(curve_zhong5[:, 0], curve_zhong5[:, 1], &#039;k-&#039;, linewidth&#061;3)<br \/>\n    ax.set_xlim(-0.1, 0.7)<br \/>\n    ax.set_ylim(-0.1, 1.1)<br \/>\n    ax.set_title(&#039;\u4e2d\u6587\u5b57\u4f53&#xff1a;&#034;\u4e2d&#034;\u5b57\u8bbe\u8ba1&#039;, fontsize&#061;12, fontweight&#061;&#039;bold&#039;)<br \/>\n    ax.grid(True, alpha&#061;0.3)<br \/>\n    ax.axis(&#039;equal&#039;)<br \/>\n    # \u4e2d\u4e0b&#xff1a;\u5b57\u4f53\u5e73\u6ed1\u5ea6\u5bf9\u6bd4<br \/>\n    ax &#061; axes[1, 1]<br \/>\n    # \u7c97\u7cd9\u7684\u5b57\u6bcd&#039;O&#039;<br \/>\n    rough_points &#061; [<br \/>\n        np.array([[0, 0], [0.2, 0], [0.5, 0.2], [0.8, 0], [1, 0]]),<br \/>\n        np.array([[1, 0], [1, 0.3], [1, 0.6], [1, 1]]),<br \/>\n        np.array([[1, 1], [0.8, 1], [0.5, 0.8], [0.2, 1], [0, 1]]),<br \/>\n        np.array([[0, 1], [0, 0.6], [0, 0.3], [0, 0]])<br \/>\n    ]<br \/>\n    for points in rough_points:<br \/>\n        curve &#061; compute_bezier_curve(points)<br \/>\n        ax.plot(curve[:, 0], curve[:, 1], &#039;r-&#039;, linewidth&#061;2, alpha&#061;0.5, label&#061;&#039;\u7c97\u7cd9\u8bbe\u8ba1&#039; if points is rough_points[0] else &#034;&#034;)<br \/>\n    # \u5e73\u6ed1\u7684\u5b57\u6bcd&#039;O&#039;<br \/>\n    smooth_points &#061; [<br \/>\n        np.array([[0.2, 0], [0.3, -0.1], [0.7, -0.1], [0.8, 0]]),<br \/>\n        np.array([[0.8, 0], [1, 0.2], [1, 0.8], [0.8, 1]]),<br \/>\n        np.array([[0.8, 1], [0.7, 1.1], [0.3, 1.1], [0.2, 1]]),<br \/>\n        np.array([[0.2, 1], [0, 0.8], [0, 0.2], [0.2, 0]])<br \/>\n    ]<br \/>\n    for points in smooth_points:<br \/>\n        curve &#061; compute_bezier_curve(points)<br \/>\n        ax.plot(curve[:, 0], curve[:, 1], &#039;b-&#039;, linewidth&#061;3, label&#061;&#039;\u5e73\u6ed1\u8bbe\u8ba1&#039; if points is smooth_points[0] else &#034;&#034;)<br \/>\n    ax.set_xlim(-0.2, 1.2)<br \/>\n    ax.set_ylim(-0.2, 1.2)<br \/>\n    ax.set_title(&#039;\u5b57\u4f53\u5e73\u6ed1\u5ea6\u5bf9\u6bd4&#039;, fontsize&#061;12, fontweight&#061;&#039;bold&#039;)<br \/>\n    ax.legend(fontsize&#061;9)<br \/>\n    ax.grid(True, alpha&#061;0.3)<br \/>\n    ax.axis(&#039;equal&#039;)<br \/>\n    # \u53f3\u4e0b&#xff1a;\u8fde\u7b14\u5b57\u4f53\u793a\u4f8b<br \/>\n    ax &#061; axes[1, 2]<br \/>\n    # \u8fde\u7b14\u5b57\u90e8\u5206\u8bbe\u8ba1<br \/>\n    control_love &#061; [<br \/>\n        np.array([[0, 0.8], [0.2, 1], [0.4, 0.8]]),<br \/>\n        np.array([[0.4, 0.8], [0.6, 0.6], [0.8, 0.8]]),<br \/>\n        np.array([[0.8, 0.8], [1, 1], [1.2, 0.8]]),<br \/>\n        np.array([[0.6, 0.6], [0.6, 0.3], [0.6, 0]]),<br \/>\n        np.array([[0.6, 0], [0.4, -0.2], [0.2, 0]])<br \/>\n    ]<br \/>\n    colors &#061; [&#039;r&#039;, &#039;g&#039;, &#039;b&#039;, &#039;m&#039;, &#039;c&#039;]<br \/>\n    labels &#061; [&#039;\u4e0a\u90e8\u66f2\u7ebf&#039;, &#039;\u4e2d\u95f4\u8fde\u63a5&#039;, &#039;\u53f3\u90e8\u66f2\u7ebf&#039;, &#039;\u7ad6\u7b14&#039;, &#039;\u5e95\u90e8\u56de\u7b14&#039;]<br \/>\n    for i, points in enumerate(control_love):<br \/>\n        curve &#061; compute_bezier_curve(points)<br \/>\n        ax.plot(curve[:, 0], curve[:, 1], f&#039;{colors[i]}-&#039;, linewidth&#061;2, label&#061;labels[i])<br \/>\n    ax.set_xlim(-0.2, 1.4)<br \/>\n    ax.set_ylim(-0.3, 1.2)<br \/>\n    ax.set_title(&#039;\u8fde\u7b14\u5b57\u4f53\u8bbe\u8ba1\u793a\u4f8b&#039;, fontsize&#061;12, fontweight&#061;&#039;bold&#039;)<br \/>\n    ax.legend(fontsize&#061;8, loc&#061;&#039;upper right&#039;)<br \/>\n    ax.grid(True, alpha&#061;0.3)<br \/>\n    ax.axis(&#039;equal&#039;)<br \/>\n    fig.suptitle(&#039;\u5b57\u4f53\u8bbe\u8ba1\u5e94\u7528&#xff1a;\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u7cbe\u786e\u8868\u793a&#039;, fontsize&#061;16, fontweight&#061;&#039;bold&#039;)<br \/>\n    fig.tight_layout()<br \/>\n    return fig<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p># \u6267\u884c\u5b57\u4f53\u8bbe\u8ba1\u6848\u4f8b<br \/>\nfig_font &#061; bezier_application_font_design()<br \/>\nfig_font<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"453\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/02\/20260222072609-699aaf917c30b.png\" width=\"695\" \/><\/p>\n<\/p>\n<h5 id=\"auto-44\">6.3 \u52a8\u753b\u8def\u5f84<\/h5>\n<p>C\u00b9\/G\u00b9\u8fde\u7eed\u6027\u786e\u4fdd\u8fd0\u52a8\u5e73\u6ed1<\/p>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>def cubic_bezier(p0, p1, p2, p3, t):<br \/>\n    &#034;&#034;&#034;\u8ba1\u7b97\u4e09\u6b21\u8d1d\u585e\u5c14\u66f2\u7ebf\u4e0a\u7684\u70b9&#034;&#034;&#034;<br \/>\n    return (1-t)**3 * p0 &#043; 3*t*(1-t)**2 * p1 &#043; 3*t**2*(1-t)*p2 &#043; t**3*p3<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>def compute_c1_continuity_control_points(prev_curve, next_p2, next_p3):<br \/>\n    &#034;&#034;&#034;\u8ba1\u7b97\u6ee1\u8db3C\u00b9\u8fde\u7eed\u6027\u7684\u63a7\u5236\u70b9&#034;&#034;&#034;<br \/>\n    P0, P1, P2, P3 &#061; prev_curve<\/p>\n<p>    # C\u00b9\u8fde\u7eed\u6761\u4ef6<br \/>\n    Q0 &#061; P3  # \u4f4d\u7f6e\u8fde\u7eed<br \/>\n    Q1 &#061; 2*P3 &#8211; P2  # \u4e00\u9636\u5bfc\u6570\u8fde\u7eed<br \/>\n    Q2 &#061; next_p2<br \/>\n    Q3 &#061; next_p3<\/p>\n<p>    return np.array([Q0, Q1, Q2, Q3])<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>def generate_smooth_animation_path(key_points, continuity_type&#061;&#039;C1&#039;):<br \/>\n        &#034;&#034;&#034;\u751f\u6210\u5e73\u6ed1\u52a8\u753b\u8def\u5f84&#034;&#034;&#034;<br \/>\n        curves &#061; []<br \/>\n        n_segments &#061; len(key_points) &#8211; 1<\/p>\n<p>        # \u4e3a\u6bcf\u4e2a\u5173\u952e\u70b9\u751f\u6210\u521d\u59cb\u63a7\u5236\u70b9<br \/>\n        control_sets &#061; []<\/p>\n<p>        # \u7b2c\u4e00\u6bb5\u7684\u63a7\u5236\u70b9<br \/>\n        P0 &#061; key_points[0]<br \/>\n        P1 &#061; key_points[0] &#043; (key_points[1] &#8211; key_points[0]) \/ 3<br \/>\n        control_sets.append([P0, P1])<\/p>\n<p>        # \u4e2d\u95f4\u6bb5\u7684\u63a7\u5236\u70b9<br \/>\n        for i in range(1, len(key_points)-1):<br \/>\n            prev &#061; key_points[i-1]<br \/>\n            curr &#061; key_points[i]<br \/>\n            next &#061; key_points[i&#043;1]<\/p>\n<p>            tangent &#061; (next &#8211; prev) \/ 2<\/p>\n<p>            P2 &#061; curr &#8211; tangent \/ 3<br \/>\n            P3 &#061; curr<br \/>\n            P0_next &#061; curr<br \/>\n            P1_next &#061; curr &#043; tangent \/ 3<\/p>\n<p>            control_sets[-1].extend([P2, P3])<br \/>\n            control_sets.append([P0_next, P1_next])<\/p>\n<p>        # \u6700\u540e\u4e00\u6bb5\u7684\u63a7\u5236\u70b9<br \/>\n        last_idx &#061; len(key_points) &#8211; 1<br \/>\n        P2 &#061; key_points[last_idx] &#8211; (key_points[last_idx] &#8211; key_points[last_idx-1]) \/ 3<br \/>\n        P3 &#061; key_points[last_idx]<br \/>\n        control_sets[-1].extend([P2, P3])<\/p>\n<p>        # \u6784\u5efa\u66f2\u7ebf<br \/>\n        for i in range(n_segments):<br \/>\n            if continuity_type &#061;&#061; &#039;C1&#039; and i &gt; 0:<br \/>\n                # C\u00b9\u8fde\u7eed\u6027<br \/>\n                prev_curve &#061; curves[-1]<br \/>\n                next_p2 &#061; control_sets[i][2]<br \/>\n                next_p3 &#061; control_sets[i][3]<\/p>\n<p>                curve_points &#061; compute_c1_continuity_control_points(prev_curve, next_p2, next_p3)<br \/>\n            else:<br \/>\n                # \u7b2c\u4e00\u6bb5\u6216G\u00b9\u8fde\u7eed\u6027<br \/>\n                curve_points &#061; np.array(control_sets[i])<\/p>\n<p>            curves.append(curve_points)<\/p>\n<p>        return curves<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>def bezier_application_animation_path():<br \/>\n    &#034;&#034;&#034;<br \/>\n    \u8d1d\u585e\u5c14\u66f2\u7ebf\u5e94\u7528\u5b9e\u4f8b&#xff1a;\u52a8\u753b\u8def\u5f84<br \/>\n    \u4f7f\u7528C\u00b9\u6216G\u00b9\u8fde\u7eed\u6027\u786e\u4fdd\u8fd0\u52a8\u5e73\u6ed1<br \/>\n    &#034;&#034;&#034;<\/p>\n<p>    # \u521b\u5efa\u6f14\u793a\u56fe\u5f62&#xff08;\u9759\u6001\u5c55\u793a&#xff09;<br \/>\n    fig, axes &#061; plt.subplots(2, 3, figsize&#061;(24, 12))<\/p>\n<p>    # \u5b9a\u4e49\u5173\u952e\u70b9<br \/>\n    key_points &#061; np.array([<br \/>\n        [0, 0],<br \/>\n        [2, 3],<br \/>\n        [5, 1],<br \/>\n        [7, 4],<br \/>\n        [10, 2]<br \/>\n    ])<\/p>\n<p>    # \u5de6\u4e0a&#xff1a;C\u00b9\u8fde\u7eed\u6027\u8def\u5f84<br \/>\n    ax &#061; axes[0, 0]<br \/>\n    c1_curves &#061; generate_smooth_animation_path(key_points, continuity_type&#061;&#039;C1&#039;)<\/p>\n<p>    # \u7ed8\u5236C\u00b9\u8def\u5f84<br \/>\n    for i, curve in enumerate(c1_curves):<br \/>\n        t_values &#061; np.linspace(0, 1, 100)<br \/>\n        segment_points &#061; np.array([cubic_bezier(*curve, t) for t in t_values])<br \/>\n        ax.plot(segment_points[:, 0], segment_points[:, 1], &#039;b-&#039;, linewidth&#061;2)<\/p>\n<p>        # \u7ed8\u5236\u63a7\u5236\u591a\u8fb9\u5f62<br \/>\n        ax.plot(curve[:, 0], curve[:, 1], &#039;g&#8211;&#039;, linewidth&#061;1, alpha&#061;0.5)<br \/>\n        ax.scatter(curve[:, 0], curve[:, 1], s&#061;40, c&#061;&#039;green&#039;, alpha&#061;0.5)<\/p>\n<p>        # \u6807\u8bb0\u63a7\u5236\u70b9<br \/>\n        if i &#061;&#061; 0:<br \/>\n            for j, point in enumerate(curve):<br \/>\n                ax.text(point[0]&#043;0.1, point[1]&#043;0.1, f&#039;P{j}&#039;, fontsize&#061;9, fontweight&#061;&#039;bold&#039;)<br \/>\n        else:<br \/>\n            for j, point in enumerate(curve):<br \/>\n                ax.text(point[0]&#043;0.1, point[1]&#043;0.1, f&#039;Q{j}&#039;, fontsize&#061;9, fontweight&#061;&#039;bold&#039;)<\/p>\n<p>    # \u6807\u8bb0\u5173\u952e\u70b9<br \/>\n    ax.scatter(key_points[:, 0], key_points[:, 1], s&#061;100, c&#061;&#039;red&#039;,<br \/>\n               edgecolors&#061;&#039;black&#039;, linewidth&#061;2, zorder&#061;5)<\/p>\n<p>    # \u6807\u8bb0\u8fde\u63a5\u70b9\u5904\u7684C\u00b9\u8fde\u7eed\u6027<br \/>\n    for i in range(len(c1_curves)-1):<br \/>\n        P2 &#061; c1_curves[i][2]<br \/>\n        P3 &#061; c1_curves[i][3]<br \/>\n        Q1 &#061; c1_curves[i&#043;1][1]<\/p>\n<p>        # \u7ed8\u5236\u5207\u7ebf\u5411\u91cf<br \/>\n        ax.arrow(P3[0], P3[1], P3[0]-P2[0], P3[1]-P2[1],<br \/>\n                head_width&#061;0.15, head_length&#061;0.2, fc&#061;&#039;purple&#039;, ec&#061;&#039;purple&#039;, alpha&#061;0.7)<br \/>\n        ax.arrow(P3[0], P3[1], Q1[0]-P3[0], Q1[1]-P3[1],<br \/>\n                head_width&#061;0.15, head_length&#061;0.2, fc&#061;&#039;orange&#039;, ec&#061;&#039;orange&#039;, alpha&#061;0.7)<\/p>\n<p>    ax.set_title(&#039;C\u00b9\u8fde\u7eed\u6027\u52a8\u753b\u8def\u5f84&#039;, fontsize&#061;12, fontweight&#061;&#039;bold&#039;)<br \/>\n    ax.set_xlabel(&#039;X\u5750\u6807&#039;, fontsize&#061;11)<br \/>\n    ax.set_ylabel(&#039;Y\u5750\u6807&#039;, fontsize&#061;11)<br \/>\n    ax.grid(True, alpha&#061;0.3)<br \/>\n    ax.axis(&#039;equal&#039;)<\/p>\n<p>    # \u53f3\u4e0a&#xff1a;G\u00b9\u8fde\u7eed\u6027\u8def\u5f84<br \/>\n    ax &#061; axes[0, 2]<br \/>\n    g1_curves &#061; generate_smooth_animation_path(key_points, continuity_type&#061;&#039;G1&#039;)<\/p>\n<p>    # \u7ed8\u5236G\u00b9\u8def\u5f84<br \/>\n    for i, curve in enumerate(g1_curves):<br \/>\n        t_values &#061; np.linspace(0, 1, 100)<br \/>\n        segment_points &#061; np.array([cubic_bezier(*curve, t) for t in t_values])<br \/>\n        ax.plot(segment_points[:, 0], segment_points[:, 1], &#039;r-&#039;, linewidth&#061;2)<\/p>\n<p>        # \u7ed8\u5236\u63a7\u5236\u591a\u8fb9\u5f62<br \/>\n        ax.plot(curve[:, 0], curve[:, 1], &#039;g&#8211;&#039;, linewidth&#061;1, alpha&#061;0.5)<br \/>\n        ax.scatter(curve[:, 0], curve[:, 1], s&#061;40, c&#061;&#039;green&#039;, alpha&#061;0.5)<\/p>\n<p>    # \u6807\u8bb0\u5173\u952e\u70b9<br \/>\n    ax.scatter(key_points[:, 0], key_points[:, 1], s&#061;100, c&#061;&#039;red&#039;,<br \/>\n               edgecolors&#061;&#039;black&#039;, linewidth&#061;2, zorder&#061;5)<\/p>\n<p>    ax.set_title(&#039;G\u00b9\u8fde\u7eed\u6027\u52a8\u753b\u8def\u5f84&#039;, fontsize&#061;12, fontweight&#061;&#039;bold&#039;)<br \/>\n    ax.set_xlabel(&#039;X\u5750\u6807&#039;, fontsize&#061;11)<br \/>\n    ax.set_ylabel(&#039;Y\u5750\u6807&#039;, fontsize&#061;11)<br \/>\n    ax.grid(True, alpha&#061;0.3)<br \/>\n    ax.axis(&#039;equal&#039;)<\/p>\n<p>    # \u4e2d\u56fe&#xff1a;\u5dee\u5f02\u503c\u66f2\u7ebf<br \/>\n    ax3 &#061; axes[0,1]<br \/>\n    # \u8ba1\u7b97C\u00b9\u548cG\u00b9\u8def\u5f84\u4e0a\u7684\u70b9&#xff08;\u9ad8\u5206\u8fa8\u7387\u91c7\u6837&#xff09;<br \/>\n    t_values &#061; np.linspace(0, 1, 500)  # \u9ad8\u5206\u8fa8\u7387\u53c2\u6570<br \/>\n    c1_points &#061; []<br \/>\n    g1_points &#061; []<\/p>\n<p>    for i in range(len(c1_curves)):<br \/>\n        c1_segment &#061; np.array([cubic_bezier(*c1_curves[i], t) for t in t_values])<br \/>\n        g1_segment &#061; np.array([cubic_bezier(*g1_curves[i], t) for t in t_values])<br \/>\n        c1_points.append(c1_segment)<br \/>\n        g1_points.append(g1_segment)<\/p>\n<p>    c1_points &#061; np.vstack(c1_points)<br \/>\n    g1_points &#061; np.vstack(g1_points)<br \/>\n    # \u63d0\u53d6X\u5750\u6807\u548cY\u5750\u6807\u7684\u5dee\u5f02<br \/>\n    x_coords &#061; c1_points[:, 0]  # \u4f7f\u7528C\u00b9\u8def\u5f84\u7684X\u5750\u6807\u4f5c\u4e3a\u6a2a\u8f74<br \/>\n    y_diff &#061; c1_points[:, 1] &#8211; g1_points[:, 1]  # \u8ba1\u7b97Y\u5750\u6807\u7684\u5dee\u5f02<\/p>\n<p>    ax3.plot(x_coords, y_diff, &#039;g-&#039;, linewidth&#061;2)<br \/>\n    ax3.set_title(&#039;C\u00b9\u4e0eG\u00b9\u8def\u5f84Y\u5750\u6807\u5dee\u5f02\u503c\u66f2\u7ebf&#039;, fontsize&#061;12, fontweight&#061;&#039;bold&#039;)<br \/>\n    ax3.set_xlabel(&#039;X\u5750\u6807&#039;, fontsize&#061;11)<br \/>\n    ax3.set_ylabel(&#039;Y\u5750\u6807\u5dee\u5f02\u503c&#039;, fontsize&#061;11)<br \/>\n    ax3.grid(True, alpha&#061;0.3)<br \/>\n    ax3.set_ylim(np.min(y_diff) * 1.1, np.max(y_diff) * 1.1)<\/p>\n<p>    # \u5de6\u4e0b&#xff1a;\u8fde\u7eed\u6027\u6761\u4ef6\u5bf9\u6bd4<br \/>\n    ax &#061; axes[1, 0]<br \/>\n    ax.axis(&#039;off&#039;)<\/p>\n<p>    # \u663e\u793a\u8fde\u7eed\u6027\u6761\u4ef6<br \/>\n    text &#061; &#034;\u8fde\u7eed\u6027\u6761\u4ef6\u5bf9\u6bd4&#xff1a;\\\\n&#034;<br \/>\n    text &#043;&#061; &#034;C\u00b9\u8fde\u7eed\u6027\u6761\u4ef6&#xff1a;\\\\n&#034;<br \/>\n    text &#043;&#061; &#034;1. \u4f4d\u7f6e\u8fde\u7eed&#xff1a;P3 &#061; Q0\\\\n&#034;<br \/>\n    text &#043;&#061; &#034;2. \u4e00\u9636\u5bfc\u6570\u8fde\u7eed&#xff1a;P3 &#8211; P2 &#061; Q1 &#8211; Q0 \u2192 Q1 &#061; 2P3 &#8211; P2\\\\n&#034;<\/p>\n<p>    text &#043;&#061; &#034;G\u00b9\u8fde\u7eed\u6027\u6761\u4ef6&#xff1a;\\\\n&#034;<br \/>\n    text &#043;&#061; &#034;1. \u4f4d\u7f6e\u8fde\u7eed&#xff1a;P3 &#061; Q0\\\\n&#034;<br \/>\n    text &#043;&#061; &#034;2. \u5207\u7ebf\u65b9\u5411\u4e00\u81f4&#xff1a;Q1\u5728P2P3\u5ef6\u957f\u7ebf\u4e0a \u2192 Q1 &#061; P3 &#043; k(P3 &#8211; P2), k &gt; 0\\\\n&#034;<\/p>\n<p>    text &#043;&#061; &#034;\u52a8\u753b\u5e94\u7528\u5efa\u8bae&#xff1a;\\\\n&#034;<br \/>\n    text &#043;&#061; &#034;\u2022 C\u00b9\u8fde\u7eed&#xff1a;\u901f\u5ea6\u5927\u5c0f\u548c\u65b9\u5411\u90fd\u8fde\u7eed&#xff0c;\u8fd0\u52a8\u6700\u5e73\u6ed1\\\\n&#034;<br \/>\n    text &#043;&#061; &#034;\u2022 G\u00b9\u8fde\u7eed&#xff1a;\u8fd0\u52a8\u65b9\u5411\u8fde\u7eed&#xff0c;\u901f\u5ea6\u5927\u5c0f\u53ef\u8c03&#xff0c;\u66f4\u7075\u6d3b\\\\n&#034;<br \/>\n    text &#043;&#061; &#034;\u2022 \u5bf9\u4e8e\u5927\u591a\u6570\u52a8\u753b&#xff0c;G\u00b9\u8fde\u7eed\u5df2\u8db3\u591f\\\\n&#034;<\/p>\n<p>    ax.text(0.1, 0.5, text, fontsize&#061;11, verticalalignment&#061;&#039;center&#039;,<br \/>\n            bbox&#061;dict(boxstyle&#061;&#039;round&#039;, facecolor&#061;&#039;wheat&#039;, alpha&#061;0.8))<\/p>\n<p>    # \u53f3\u4e0b&#xff1a;\u5e94\u7528\u573a\u666f<br \/>\n    ax &#061; axes[1, 2]<br \/>\n    ax.axis(&#039;off&#039;)<\/p>\n<p>    # \u663e\u793a\u5e94\u7528\u573a\u666f<br \/>\n    text &#061; &#034;\u52a8\u753b\u8def\u5f84\u5e94\u7528\u573a\u666f&#xff1a;\\\\n&#034;<br \/>\n    text &#043;&#061; &#034;1. \u6e38\u620f\u89d2\u8272\u79fb\u52a8&#xff1a;\\\\n&#034;<br \/>\n    text &#043;&#061; &#034;   \u2022 \u89d2\u8272\u6cbf\u9884\u8bbe\u8def\u5f84\u79fb\u52a8\u2022 NPC\u5de1\u903b\u8def\u7ebf\u2022 \u6280\u80fd\u7279\u6548\u8f68\u8ff9\\\\n&#034;<\/p>\n<p>    text &#043;&#061; &#034;2. UI\u52a8\u753b&#xff1a;\\\\n&#034;<br \/>\n    text &#043;&#061; &#034;   \u2022 \u6309\u94ae\u70b9\u51fb\u52a8\u753b\u2022 \u9875\u9762\u5207\u6362\u8fc7\u6e21\u2022 \u5143\u7d20\u5165\u573a\/\u51fa\u573a\u52a8\u753b\\\\n&#034;<\/p>\n<p>    text &#043;&#061; &#034;3. \u6570\u636e\u53ef\u89c6\u5316&#xff1a;\\\\n&#034;<br \/>\n    text &#043;&#061; &#034;   \u2022 \u6570\u636e\u70b9\u8fde\u7ebf\u52a8\u753b\u2022 \u8d8b\u52bf\u7ebf\u7ed8\u5236\u2022 \u7126\u70b9\u79fb\u52a8\u52a8\u753b\\\\n&#034;<\/p>\n<p>    text &#043;&#061; &#034;4. \u5f71\u89c6\u7279\u6548&#xff1a;\\\\n&#034;<br \/>\n    text &#043;&#061; &#034;   \u2022 \u6444\u50cf\u673a\u8fd0\u52a8\u8def\u5f84\u2022 \u7c92\u5b50\u8fd0\u52a8\u8f68\u8ff9\u2022 \u5149\u7ebf\u8def\u5f84\u8ffd\u8e2a\\\\n&#034;<\/p>\n<p>    ax.text(0.1, 0.5, text, fontsize&#061;11, verticalalignment&#061;&#039;center&#039;,<br \/>\n            bbox&#061;dict(boxstyle&#061;&#039;round&#039;, facecolor&#061;&#039;lightblue&#039;, alpha&#061;0.8))<\/p>\n<p>    # \u4e2d\u4e0b&#xff1a;\u5dee\u5f02\u503c\u539f\u56e0\u89e3\u91ca<br \/>\n    ax &#061; axes[1, 1]<br \/>\n    ax.axis(&#039;off&#039;)<\/p>\n<p>    # \u663e\u793a\u5dee\u5f02\u503c\u539f\u56e0\u89e3\u91ca<br \/>\n    text &#061; &#034;\u5dee\u5f02\u503c\u5206\u6790&#xff1a;\\\\n&#034;<br \/>\n    text &#043;&#061; &#034;1. \u5dee\u5f02\u6765\u6e90&#xff1a;\\\\n&#034;<br \/>\n    text &#043;&#061; &#034;   \u2022 C\u00b9\u8fde\u7eed\u6027\u8981\u6c42\u5bfc\u6570\u8fde\u7eed&#xff0c;G\u00b9\u8fde\u7eed\u6027\u4ec5\u8981\u6c42\u5207\u7ebf\u65b9\u5411\u8fde\u7eed\u3002\\\\n&#034;<br \/>\n    text &#043;&#061; &#034;   \u2022 \u56e0\u6b64&#xff0c;\u5728\u8fde\u63a5\u70b9\u9644\u8fd1&#xff0c;C\u00b9\u8def\u5f84\u7684Y\u5750\u6807\u53d8\u5316\u66f4\u5e73\u6ed1\u3002\\\\n&#034;<\/p>\n<p>    text &#043;&#061; &#034;2. \u5dee\u5f02\u6700\u5927\u503c&#xff1a;\\\\n&#034;<br \/>\n    text &#043;&#061; &#034;   \u2022 \u6700\u5927\u5dee\u5f02\u51fa\u73b0\u5728\u8fde\u63a5\u70b9\u9644\u8fd1\u3002\\\\n&#034;<br \/>\n    text &#043;&#061; &#034;   \u2022 \u5dee\u5f02\u6700\u5927\u503c\u4e3a -9\u00d710-6&#xff0c;\u8868\u660e\u4e24\u6761\u8def\u5f84\u5728Y\u65b9\u5411\u4e0a\u7684\u5fae\u5c0f\u504f\u5dee\u3002\\\\n&#034;<\/p>\n<p>    text &#043;&#061; &#034;3. \u5b9e\u9645\u5f71\u54cd&#xff1a;\\\\n&#034;<br \/>\n    text &#043;&#061; &#034;   \u2022 \u7531\u4e8e\u5dee\u5f02\u6781\u5c0f&#xff0c;\u8089\u773c\u96be\u4ee5\u5bdf\u89c9\u3002\\\\n&#034;<br \/>\n    text &#043;&#061; &#034;   \u2022 \u5728\u9ad8\u7cbe\u5ea6\u52a8\u753b\u4e2d&#xff0c;\u9700\u6839\u636e\u9700\u6c42\u9009\u62e9\u5408\u9002\u7684\u8fde\u7eed\u6027\u7c7b\u578b\u3002&#034;<\/p>\n<p>    ax.text(0.1, 0.5, text, fontsize&#061;11, verticalalignment&#061;&#039;center&#039;,<br \/>\n        bbox&#061;dict(boxstyle&#061;&#039;round&#039;, facecolor&#061;&#039;lightgreen&#039;, alpha&#061;0.8))<\/p>\n<p>    fig.suptitle(&#039;\u52a8\u753b\u8def\u5f84\u5e94\u7528&#xff1a;C\u00b9\/G\u00b9\u8fde\u7eed\u6027\u786e\u4fdd\u8fd0\u52a8\u5e73\u6ed1&#039;, fontsize&#061;16, fontweight&#061;&#039;bold&#039;)<br \/>\n    fig.tight_layout()<\/p>\n<p>    return fig<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p># \u6267\u884c\u52a8\u753b\u8def\u5f84\u6848\u4f8b<br \/>\nfig_animation &#061; bezier_application_animation_path()<br \/>\nfig_animation<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"309\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/02\/20260222072609-699aaf91a1ad7.png\" width=\"693\" \/><\/p>\n<\/p>\n<h5 id=\"auto-45\">6.4 CAD\/CAM<\/h5>\n<p>\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u4fdd\u6301\u6295\u5f71\u4e0d\u53d8\u6027<\/p>\n<p>\u5f15\u7533\u9605\u8bfb&#xff1a;<\/p>\n<p>\u6295\u5f71\u4e0d\u53d8\u6027&#xff08;Projection Invariance&#xff09;\u662f\u8ba1\u7b97\u673a\u56fe\u5f62\u5b66\u548c\u51e0\u4f55\u5efa\u6a21\u4e2d\u7684\u4e00\u4e2a\u91cd\u8981\u6982\u5ff5&#xff0c;\u5c24\u5176\u5728 CAD\/CAM \u548c\u8ba1\u7b97\u673a\u89c6\u89c9\u9886\u57df\u4e2d\u5177\u6709\u91cd\u8981\u610f\u4e49\u3002\u5b83\u7684\u6838\u5fc3\u601d\u60f3\u662f&#xff1a;\u67d0\u4e9b\u51e0\u4f55\u5c5e\u6027\u6216\u5173\u7cfb\u5728\u7ecf\u8fc7\u6295\u5f71\u53d8\u6362\u540e\u4ecd\u7136\u4fdd\u6301\u4e0d\u53d8\u3002<\/p>\n<\/p>\n<hr \/>\n<\/p>\n<h6>\u6295\u5f71\u4e0d\u53d8\u6027\u7684\u5b9a\u4e49<\/h6>\n<\/p>\n<p>\u5728\u6570\u5b66\u548c\u51e0\u4f55\u4e2d&#xff0c;\u6295\u5f71\u53d8\u6362\u662f\u4e00\u79cd\u5c06\u4e09\u7ef4\u7a7a\u95f4\u4e2d\u7684\u70b9\u6620\u5c04\u5230\u4e8c\u7ef4\u5e73\u9762\u7684\u64cd\u4f5c&#xff08;\u4f8b\u5982\u900f\u89c6\u6295\u5f71\u6216\u5e73\u884c\u6295\u5f71&#xff09;\u3002\u6295\u5f71\u4e0d\u53d8\u6027\u6307\u7684\u662f&#xff1a;<\/p>\n<p>\u67d0\u4e9b\u51e0\u4f55\u7279\u6027&#xff08;\u5982\u70b9\u3001\u7ebf\u3001\u66f2\u7ebf\u7684\u62d3\u6251\u7ed3\u6784\u3001\u4ea4\u6bd4\u7b49&#xff09;\u5728\u6295\u5f71\u53d8\u6362\u524d\u540e\u4fdd\u6301\u4e00\u81f4\u3002<\/p>\n<p>\u6362\u53e5\u8bdd\u8bf4&#xff0c;\u65e0\u8bba\u4ece\u54ea\u4e2a\u89d2\u5ea6\u89c2\u5bdf\u7269\u4f53&#xff0c;\u8fd9\u4e9b\u7279\u6027\u90fd\u4e0d\u4f1a\u6539\u53d8\u3002<\/p>\n<\/p>\n<hr \/>\n<\/p>\n<h6>\u6295\u5f71\u4e0d\u53d8\u6027\u7684\u5177\u4f53\u8868\u73b0<\/h6>\n<\/p>\n<\/p>\n<h6>1. \u70b9\u7684\u6295\u5f71\u4e0d\u53d8\u6027<\/h6>\n<\/p>\n<ul>\n<li>\n<p>\u4e00\u4e2a\u70b9\u5728\u4e09\u7ef4\u7a7a\u95f4\u4e2d\u7684\u4f4d\u7f6e\u7ecf\u8fc7\u6295\u5f71\u53d8\u6362\u540e&#xff0c;\u4ecd\u7136\u662f\u4e00\u4e2a\u70b9\u3002<\/p>\n<\/li>\n<li>\n<p>\u4f8b\u5982&#xff1a;\u4e09\u7ef4\u7a7a\u95f4\u4e2d\u7684\u70b9\u00a0P(x,y,z)\u00a0\u7ecf\u8fc7\u900f\u89c6\u6295\u5f71\u540e\u53d8\u6210\u4e8c\u7ef4\u5e73\u9762\u4e0a\u7684\u70b9\u00a0P&#039;(x&#039;,y&#039;)&#xff0c;\u4f46\u5176\u201c\u70b9\u201d\u7684\u672c\u8d28\u4e0d\u53d8\u3002<\/p>\n<\/li>\n<\/ul>\n<\/p>\n<h6>2. \u76f4\u7ebf\u7684\u6295\u5f71\u4e0d\u53d8\u6027<\/h6>\n<\/p>\n<ul>\n<li>\n<p>\u4e09\u7ef4\u7a7a\u95f4\u4e2d\u7684\u4e00\u6761\u76f4\u7ebf\u7ecf\u8fc7\u6295\u5f71\u53d8\u6362\u540e&#xff0c;\u5728\u4e8c\u7ef4\u5e73\u9762\u4e0a\u4ecd\u7136\u662f\u76f4\u7ebf\u3002<\/p>\n<\/li>\n<li>\n<p>\u4f8b\u5982&#xff1a;\u4e00\u6761\u76f4\u7ebf\u5728\u4e0d\u540c\u89c6\u89d2\u4e0b\u7684\u6295\u5f71\u59cb\u7ec8\u662f\u4e00\u6761\u76f4\u7ebf&#xff0c;\u4e0d\u4f1a\u53d8\u6210\u66f2\u7ebf\u3002<\/p>\n<\/li>\n<\/ul>\n<\/p>\n<h6>3. \u66f2\u7ebf\u7684\u6295\u5f71\u4e0d\u53d8\u6027<\/h6>\n<\/p>\n<ul>\n<li>\n<p>\u7279\u6b8a\u7c7b\u578b\u7684\u66f2\u7ebf&#xff08;\u5982\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf&#xff09;\u5728\u6295\u5f71\u53d8\u6362\u540e\u4ecd\u80fd\u4fdd\u6301\u5176\u5f62\u72b6\u7279\u5f81\u3002<\/p>\n<\/li>\n<li>\n<p>\u4f8b\u5982&#xff1a;\u5706\u9525\u66f2\u7ebf&#xff08;\u692d\u5706\u3001\u629b\u7269\u7ebf\u3001\u53cc\u66f2\u7ebf&#xff09;\u7ecf\u8fc7\u6295\u5f71\u540e\u53ef\u80fd\u53d8\u5f62&#xff0c;\u4f46\u5b83\u4eec\u4ecd\u7136\u662f\u5706\u9525\u66f2\u7ebf\u65cf\u7684\u4e00\u5458\u3002<\/p>\n<\/li>\n<\/ul>\n<\/p>\n<h6>4. \u4ea4\u6bd4\u7684\u6295\u5f71\u4e0d\u53d8\u6027<\/h6>\n<\/p>\n<ul>\n<li>\n<p>\u4ea4\u6bd4&#xff08;Cross Ratio&#xff09;\u662f\u56db\u4e2a\u5171\u7ebf\u70b9\u4e4b\u95f4\u7684\u4e00\u79cd\u6bd4\u4f8b\u5173\u7cfb&#xff0c;\u5b83\u662f\u6295\u5f71\u53d8\u6362\u4e2d\u6700\u57fa\u672c\u7684\u4e0d\u53d8\u91cf\u3002<\/p>\n<\/li>\n<li>\n<p>\u4f8b\u5982&#xff1a;\u56db\u4e2a\u70b9\u00a0A,B,C,D\u00a0\u5728\u4e00\u6761\u76f4\u7ebf\u4e0a&#xff0c;\u5b83\u4eec\u7684\u4ea4\u6bd4\u4e3a&#xff1a;<\/p>\n<\/li>\n<\/ul>\n<p>(A,B;C,D)&#061;A\u2062C\u22c5B\u2062DA\u2062D\u22c5B\u2062C<\/p>\n<p>\u8fd9\u4e2a\u503c\u5728\u4efb\u4f55\u6295\u5f71\u53d8\u6362\u4e0b\u90fd\u4fdd\u6301\u4e0d\u53d8\u3002<\/p>\n<\/p>\n<hr \/>\n<\/p>\n<h6>\u4e3a\u4ec0\u4e48\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u5177\u6709\u6295\u5f71\u4e0d\u53d8\u6027&#xff1f;<\/h6>\n<\/p>\n<p>\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf&#xff08;Rational B\u00e9zier Curve&#xff09;\u4e4b\u6240\u4ee5\u5177\u6709\u6295\u5f71\u4e0d\u53d8\u6027&#xff0c;\u662f\u56e0\u4e3a\u5b83\u5f15\u5165\u4e86\u6743\u91cd\u56e0\u5b50&#xff0c;\u4f7f\u5f97\u66f2\u7ebf\u5728\u9f50\u6b21\u5750\u6807\u7cfb\u4e2d\u8868\u793a\u3002\u4ee5\u4e0b\u662f\u5173\u952e\u539f\u56e0&#xff1a;<\/p>\n<\/p>\n<h6>1. \u9f50\u6b21\u5750\u6807\u8868\u793a<\/h6>\n<\/p>\n<ul>\n<li>\n<p>\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u4f7f\u7528\u9f50\u6b21\u5750\u6807\u00a0(x,y,w)\u00a0\u8868\u793a\u70b9&#xff0c;\u5176\u4e2d\u00a0w\u00a0\u662f\u6743\u91cd\u3002<\/p>\n<\/li>\n<li>\n<p>\u6295\u5f71\u53d8\u6362\u672c\u8d28\u4e0a\u662f\u5bf9\u9f50\u6b21\u5750\u6807\u7684\u7ebf\u6027\u53d8\u6362&#xff0c;\u56e0\u6b64\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u7684\u5f62\u5f0f\u5728\u6295\u5f71\u540e\u4f9d\u7136\u6210\u7acb\u3002<\/p>\n<\/li>\n<\/ul>\n<\/p>\n<h6>2. \u6743\u91cd\u7684\u4f5c\u7528<\/h6>\n<\/p>\n<ul>\n<li>\n<p>\u6743\u91cd\u5141\u8bb8\u66f2\u7ebf\u66f4\u7075\u6d3b\u5730\u903c\u8fd1\u590d\u6742\u7684\u51e0\u4f55\u5f62\u72b6&#xff08;\u5982\u5706\u5f27\u3001\u692d\u5706\u7b49&#xff09;\u3002<\/p>\n<\/li>\n<li>\n<p>\u5728\u6295\u5f71\u8fc7\u7a0b\u4e2d&#xff0c;\u6743\u91cd\u4f1a\u968f\u7740\u5750\u6807\u4e00\u8d77\u53d8\u6362&#xff0c;\u4f46\u66f2\u7ebf\u7684\u6574\u4f53\u5f62\u72b6\u7279\u6027\u5f97\u4ee5\u4fdd\u7559\u3002<\/p>\n<\/li>\n<\/ul>\n<\/p>\n<h6>3. \u6570\u5b66\u63a8\u5bfc<\/h6>\n<\/p>\n<p>\u8bbe\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u7684\u63a7\u5236\u70b9\u4e3a\u00a0Pi&#061;(xi,yi,wi)&#xff0c;\u5219\u66f2\u7ebf\u65b9\u7a0b\u4e3a&#xff1a;<\/p>\n<p>C(t)&#061;\u2211i&#061;0nwi\u2062Bi,n(t)Pi\u2211i&#061;0nwi\u2062Bi,n(t)<\/p>\n<p>\u5f53\u5bf9\u8be5\u66f2\u7ebf\u8fdb\u884c\u6295\u5f71\u53d8\u6362\u65f6&#xff0c;\u5206\u5b50\u548c\u5206\u6bcd\u90fd\u4f1a\u53d7\u5230\u76f8\u540c\u7684\u7ebf\u6027\u53d8\u6362\u5f71\u54cd&#xff0c;\u56e0\u6b64\u66f2\u7ebf\u7684\u6bd4\u4f8b\u5173\u7cfb\u4fdd\u6301\u4e0d\u53d8\u3002<\/p>\n<\/p>\n<hr \/>\n<\/p>\n<h6>\u5b9e\u9645\u5e94\u7528\u573a\u666f<\/h6>\n<\/p>\n<\/p>\n<h6>1. CAD\/CAM \u8bbe\u8ba1<\/h6>\n<\/p>\n<ul>\n<li>\n<p>\u5728\u4e09\u7ef4\u5efa\u6a21\u4e2d&#xff0c;\u8bbe\u8ba1\u5e08\u7ecf\u5e38\u9700\u8981\u5c06\u4e09\u7ef4\u6a21\u578b\u6295\u5f71\u5230\u4e8c\u7ef4\u56fe\u7eb8\u4e0a\u8fdb\u884c\u67e5\u770b\u6216\u52a0\u5de5\u3002<\/p>\n<\/li>\n<li>\n<p>\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u7684\u6295\u5f71\u4e0d\u53d8\u6027\u4fdd\u8bc1\u4e86\u8bbe\u8ba1\u610f\u56fe\u5728\u4e0d\u540c\u89c6\u89d2\u4e0b\u7684\u4e00\u81f4\u6027\u3002<\/p>\n<\/li>\n<\/ul>\n<\/p>\n<h6>2. \u8ba1\u7b97\u673a\u89c6\u89c9<\/h6>\n<\/p>\n<ul>\n<li>\n<p>\u5728\u6444\u50cf\u673a\u6210\u50cf\u4e2d&#xff0c;\u4e09\u7ef4\u573a\u666f\u901a\u8fc7\u900f\u89c6\u6295\u5f71\u6620\u5c04\u5230\u4e8c\u7ef4\u56fe\u50cf\u3002<\/p>\n<\/li>\n<li>\n<p>\u6295\u5f71\u4e0d\u53d8\u6027\u5e2e\u52a9\u8bc6\u522b\u548c\u91cd\u5efa\u4e09\u7ef4\u7ed3\u6784\u3002<\/p>\n<\/li>\n<\/ul>\n<\/p>\n<h6>3. \u52a8\u753b\u4e0e\u6e32\u67d3<\/h6>\n<\/p>\n<ul>\n<li>\n<p>\u5728\u4e09\u7ef4\u52a8\u753b\u5236\u4f5c\u4e2d&#xff0c;\u7269\u4f53\u7684\u8fd0\u52a8\u8f68\u8ff9\u9700\u8981\u5728\u4e0d\u540c\u89c6\u89d2\u4e0b\u770b\u8d77\u6765\u81ea\u7136\u3002<\/p>\n<\/li>\n<li>\n<p>\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u53ef\u4ee5\u786e\u4fdd\u52a8\u753b\u8def\u5f84\u5728\u6295\u5f71\u540e\u4ecd\u7136\u5e73\u6ed1\u3002<\/p>\n<\/li>\n<\/ul>\n<hr \/>\n<\/p>\n<h6>\u793a\u4f8b\u8bf4\u660e<\/h6>\n<\/p>\n<p>\u5047\u8bbe\u6211\u4eec\u6709\u4e00\u4e2a\u4e09\u7ef4\u692d\u5706\u5f27&#xff0c;\u7528\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u8868\u793a\u3002\u5f53\u6211\u4eec\u4ece\u4e0d\u540c\u89d2\u5ea6\u89c2\u5bdf\u8fd9\u4e2a\u692d\u5706\u65f6&#xff1a;<\/p>\n<ul>\n<li>\n<p>\u692d\u5706\u53ef\u80fd\u4f1a\u88ab\u538b\u6241\u6216\u62c9\u4f38&#xff0c;\u4f46\u5b83\u4ecd\u7136\u662f\u4e00\u4e2a\u692d\u5706\u3002<\/p>\n<\/li>\n<li>\n<p>\u5982\u679c\u6362\u6210\u666e\u901a\u7684\u591a\u9879\u5f0f\u8d1d\u585e\u5c14\u66f2\u7ebf&#xff0c;\u692d\u5706\u4f1a\u88ab\u626d\u66f2\u6210\u5176\u4ed6\u5f62\u72b6&#xff08;\u5982\u5375\u5f62\u6216\u4e0d\u89c4\u5219\u66f2\u7ebf&#xff09;\u3002<\/p>\n<\/li>\n<\/ul>\n<p>\u8fd9\u5c31\u662f\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u7684\u4f18\u52bf\u6240\u5728\u2014\u2014\u5b83\u80fd\u66f4\u597d\u5730\u4fdd\u6301\u51e0\u4f55\u5f62\u72b6\u7684\u672c\u8d28\u7279\u6027\u3002<\/p>\n<\/p>\n<hr \/>\n<\/p>\n<h6>\u603b\u7ed3<\/h6>\n<\/p>\n<p>\u6295\u5f71\u4e0d\u53d8\u6027\u662f\u51e0\u4f55\u5efa\u6a21\u4e2d\u4e00\u79cd\u91cd\u8981\u7684\u6570\u5b66\u6027\u8d28&#xff0c;\u5b83\u786e\u4fdd\u4e86\u67d0\u4e9b\u51e0\u4f55\u7279\u6027\u5728\u6295\u5f71\u53d8\u6362\u540e\u4f9d\u7136\u6210\u7acb\u3002\u5bf9\u4e8e\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u800c\u8a00&#xff0c;\u8fd9\u79cd\u6027\u8d28\u6765\u6e90\u4e8e\u5176\u9f50\u6b21\u5750\u6807\u8868\u793a\u548c\u6743\u91cd\u673a\u5236&#xff0c;\u4f7f\u5176\u5728 CAD\/CAM\u3001\u8ba1\u7b97\u673a\u89c6\u89c9\u7b49\u9886\u57df\u5177\u6709\u5e7f\u6cdb\u7684\u5e94\u7528\u4ef7\u503c\u3002<\/p>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>def compute_rational_bezier_curve_3d(control_points, weights, t_values&#061;None):<br \/>\n    &#034;&#034;&#034;\u8ba1\u7b97\u4e09\u7ef4\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf&#034;&#034;&#034;<br \/>\n    control_points &#061; np.array(control_points)<br \/>\n    weights &#061; np.array(weights)<br \/>\n    n &#061; len(control_points) &#8211; 1<\/p>\n<p>    if t_values is None:<br \/>\n        t_values &#061; np.linspace(0, 1, 100)<\/p>\n<p>    curve_points &#061; np.zeros((len(t_values), control_points.shape[1]))<\/p>\n<p>    for i, t in enumerate(t_values):<br \/>\n        numerator &#061; np.zeros(control_points.shape[1])<br \/>\n        denominator &#061; 0.0<\/p>\n<p>        for j in range(n&#043;1):<br \/>\n            basis &#061; bernstein_basis_numeric(n, j, t)<br \/>\n            weighted_basis &#061; weights[j] * basis<br \/>\n            numerator &#043;&#061; weighted_basis * control_points[j]<br \/>\n            denominator &#043;&#061; weighted_basis<\/p>\n<p>        if denominator !&#061; 0:<br \/>\n            curve_points[i] &#061; numerator \/ denominator<\/p>\n<p>    return curve_points<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>def compute_bezier_curve_3d(control_points, t_values&#061;None):<br \/>\n    &#034;&#034;&#034;\u8ba1\u7b97\u4e09\u7ef4\u6807\u51c6\u8d1d\u585e\u5c14\u66f2\u7ebf&#034;&#034;&#034;<br \/>\n    control_points &#061; np.array(control_points)<br \/>\n    n &#061; len(control_points) &#8211; 1<\/p>\n<p>    if t_values is None:<br \/>\n        t_values &#061; np.linspace(0, 1, 100)<\/p>\n<p>    curve_points &#061; np.zeros((len(t_values), control_points.shape[1]))<\/p>\n<p>    for i, t in enumerate(t_values):<br \/>\n        for j in range(n&#043;1):<br \/>\n            basis &#061; bernstein_basis_numeric(n, j, t)<br \/>\n            curve_points[i] &#043;&#061; basis * control_points[j]<\/p>\n<p>    return curve_points<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>def apply_perspective_projection(points, camera_pos, focal_length):<br \/>\n    &#034;&#034;&#034;\u5e94\u7528\u900f\u89c6\u6295\u5f71&#034;&#034;&#034;<br \/>\n    projected_points &#061; []<\/p>\n<p>    for point in points:<br \/>\n        # \u8ba1\u7b97\u76f8\u5bf9\u4e8e\u76f8\u673a\u7684\u4f4d\u7f6e<br \/>\n        relative_pos &#061; point &#8211; camera_pos<\/p>\n<p>        # \u900f\u89c6\u6295\u5f71<br \/>\n        if relative_pos[2] !&#061; 0:<br \/>\n            x_proj &#061; focal_length * relative_pos[0] \/ relative_pos[2]<br \/>\n            y_proj &#061; focal_length * relative_pos[1] \/ relative_pos[2]<br \/>\n            projected_points.append([x_proj, y_proj])<br \/>\n        else:<br \/>\n            projected_points.append([0, 0])<\/p>\n<p>    return np.array(projected_points)<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p>def bezier_application_cad_cam():<br \/>\n    &#034;&#034;&#034;<br \/>\n    \u8d1d\u585e\u5c14\u66f2\u7ebf\u5e94\u7528\u5b9e\u4f8b&#xff1a;CAD\/CAM<br \/>\n    \u4f7f\u7528\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u4fdd\u6301\u6295\u5f71\u4e0d\u53d8\u6027<br \/>\n    &#034;&#034;&#034;<\/p>\n<p>    # \u521b\u5efa\u56fe\u5f62<br \/>\n    fig &#061; plt.figure(figsize&#061;(16, 12))<\/p>\n<p>    # 1. \u4e09\u7ef4\u66f2\u7ebf\u8bbe\u8ba1<br \/>\n    ax1 &#061; fig.add_subplot(2, 3, 1, projection&#061;&#039;3d&#039;)<\/p>\n<p>    # \u5b9a\u4e49\u4e09\u7ef4\u63a7\u5236\u70b9<br \/>\n    control_points_3d &#061; np.array([<br \/>\n        [0, 0, 0],<br \/>\n        [1, 2, 1],<br \/>\n        [3, 1, 2],<br \/>\n        [4, 3, 1],<br \/>\n        [5, 0, 0]<br \/>\n    ])<\/p>\n<p>    # \u8ba1\u7b97\u4e09\u7ef4\u8d1d\u585e\u5c14\u66f2\u7ebf<br \/>\n    curve_3d &#061; compute_bezier_curve_3d(control_points_3d)<\/p>\n<p>    # \u7ed8\u5236\u4e09\u7ef4\u66f2\u7ebf<br \/>\n    ax1.plot(curve_3d[:, 0], curve_3d[:, 1], curve_3d[:, 2],<br \/>\n             &#039;b-&#039;, linewidth&#061;2.5, label&#061;&#039;\u4e09\u7ef4\u66f2\u7ebf&#039;)<br \/>\n    ax1.scatter(control_points_3d[:, 0], control_points_3d[:, 1], control_points_3d[:, 2],<br \/>\n               c&#061;&#039;r&#039;, s&#061;50, alpha&#061;0.7, label&#061;&#039;\u63a7\u5236\u70b9&#039;)<\/p>\n<p>    ax1.set_xlabel(&#039;X&#039;, fontsize&#061;11)<br \/>\n    ax1.set_ylabel(&#039;Y&#039;, fontsize&#061;11)<br \/>\n    ax1.set_zlabel(&#039;Z&#039;, fontsize&#061;11)<br \/>\n    ax1.set_title(&#039;\u4e09\u7ef4CAD\u66f2\u7ebf\u8bbe\u8ba1&#039;, fontsize&#061;12, fontweight&#061;&#039;bold&#039;)<br \/>\n    ax1.legend(fontsize&#061;9)<\/p>\n<p>    # 2. \u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u5728CAD\u4e2d\u7684\u5e94\u7528<br \/>\n    ax2 &#061; fig.add_subplot(2, 3, 2)<\/p>\n<p>    # \u692d\u5706\u53c2\u6570<br \/>\n    a, b &#061; 2, 1<br \/>\n    num_segments &#061; 8<\/p>\n<p>    # \u7cbe\u786e\u692d\u5706&#xff08;\u7528\u4e8e\u6bd4\u8f83&#xff09;<br \/>\n    angles_exact &#061; np.linspace(0, 2*np.pi, 500)<br \/>\n    exact_ellipse &#061; np.column_stack([a * np.cos(angles_exact), b * np.sin(angles_exact)])<br \/>\n    ax2.plot(exact_ellipse[:, 0], exact_ellipse[:, 1], &#039;k-&#039;,<br \/>\n             linewidth&#061;1, alpha&#061;0.3, label&#061;&#039;\u7cbe\u786e\u692d\u5706&#039;)<\/p>\n<p>    # \u4f7f\u75288\u6bb5\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u62fc\u63a5\u692d\u5706<br \/>\n    for i in range(num_segments):<br \/>\n        start_angle &#061; i * 2*np.pi\/num_segments<br \/>\n        end_angle &#061; (i&#043;1) * 2*np.pi\/num_segments<br \/>\n        theta &#061; end_angle &#8211; start_angle<\/p>\n<p>        # \u63a7\u5236\u70b9<br \/>\n        P0 &#061; np.array([a*np.cos(start_angle), b*np.sin(start_angle), 0])<br \/>\n        P2 &#061; np.array([a*np.cos(end_angle), b*np.sin(end_angle), 0])<\/p>\n<p>        # \u4e2d\u95f4\u63a7\u5236\u70b9<br \/>\n        mid_angle &#061; (start_angle &#043; end_angle) \/ 2<br \/>\n        cos_half_theta &#061; np.cos(theta\/2)<br \/>\n        P1 &#061; np.array([<br \/>\n            a*np.cos(mid_angle)\/cos_half_theta,<br \/>\n            b*np.sin(mid_angle)\/cos_half_theta,<br \/>\n            0<br \/>\n        ])<\/p>\n<p>        # \u6743\u91cd<br \/>\n        weights &#061; np.array([1, cos_half_theta, 1])<\/p>\n<p>        # \u8ba1\u7b97\u66f2\u7ebf<br \/>\n        control_points &#061; np.array([P0, P1, P2])<br \/>\n        curve &#061; compute_rational_bezier_curve_3d(control_points, weights)<\/p>\n<p>        # \u7ed8\u5236\u66f2\u7ebf<br \/>\n        color &#061; plt.cm.tab10(i\/num_segments)<br \/>\n        ax2.plot(curve[:, 0], curve[:, 1], &#039;-&#039;, linewidth&#061;2, color&#061;color)<\/p>\n<p>        # \u524d\u4e24\u6bb5\u663e\u793a\u63a7\u5236\u591a\u8fb9\u5f62<br \/>\n        if i &lt; 2:<br \/>\n            ax2.plot(control_points[:, 0], control_points[:, 1], &#039;&#8211;&#039;,<br \/>\n                    linewidth&#061;1, color&#061;color, alpha&#061;0.6)<br \/>\n            ax2.scatter(control_points[:, 0], control_points[:, 1],<br \/>\n                       s&#061;40, color&#061;color, alpha&#061;0.8)<\/p>\n<p>    ax2.set_xlim(-2.5, 2.5)<br \/>\n    ax2.set_ylim(-1.5, 1.5)<br \/>\n    ax2.set_title(&#039;\u6709\u7406\u66f2\u7ebf\u8868\u793a\u692d\u5706 (CAD\u7cbe\u786e\u5efa\u6a21)&#039;, fontsize&#061;12, fontweight&#061;&#039;bold&#039;)<br \/>\n    ax2.set_xlabel(&#039;X&#039;, fontsize&#061;11)<br \/>\n    ax2.set_ylabel(&#039;Y&#039;, fontsize&#061;11)<br \/>\n    ax2.grid(True, alpha&#061;0.3)<br \/>\n    ax2.axis(&#039;equal&#039;)<\/p>\n<p>    # 3. \u6295\u5f71\u4e0d\u53d8\u6027\u6f14\u793a<br \/>\n    ax3 &#061; fig.add_subplot(2, 3, 3, projection&#061;&#039;3d&#039;)<\/p>\n<p>    # \u5b9a\u4e49\u4e09\u7ef4\u66f2\u7ebf<br \/>\n    control_cad &#061; np.array([<br \/>\n        [0, 0, 0],<br \/>\n        [1, 1, 0.5],<br \/>\n        [2, 0, 1],<br \/>\n        [3, 1, 0.5],<br \/>\n        [4, 0, 0]<br \/>\n    ])<\/p>\n<p>    # \u6807\u51c6\u8d1d\u585e\u5c14\u66f2\u7ebf<br \/>\n    curve_standard &#061; compute_bezier_curve_3d(control_cad)<\/p>\n<p>    # \u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf<br \/>\n    weights_cad &#061; np.array([1, 2, 1, 2, 1])<br \/>\n    curve_rational &#061; compute_rational_bezier_curve_3d(control_cad, weights_cad)<\/p>\n<p>    # \u7ed8\u5236\u539f\u59cb\u66f2\u7ebf<br \/>\n    ax3.plot(curve_standard[:, 0], curve_standard[:, 1], curve_standard[:, 2],<br \/>\n            &#039;b-&#039;, linewidth&#061;2, label&#061;&#039;\u6807\u51c6\u66f2\u7ebf&#039;, alpha&#061;0.7)<br \/>\n    ax3.plot(curve_rational[:, 0], curve_rational[:, 1], curve_rational[:, 2],<br \/>\n            &#039;r-&#039;, linewidth&#061;2, label&#061;&#039;\u6709\u7406\u66f2\u7ebf&#039;, alpha&#061;0.7)<\/p>\n<p>    # \u5e94\u7528\u900f\u89c6\u53d8\u6362<br \/>\n    camera_pos &#061; np.array([2, -5, 3])<br \/>\n    focal_length &#061; 2<\/p>\n<p>    # \u6295\u5f71\u52302D\u5e73\u9762<br \/>\n    projected_standard &#061; apply_perspective_projection(curve_standard, camera_pos, focal_length)<br \/>\n    projected_rational &#061; apply_perspective_projection(curve_rational, camera_pos, focal_length)<\/p>\n<p>    ax3.set_xlabel(&#039;X&#039;, fontsize&#061;11)<br \/>\n    ax3.set_ylabel(&#039;Y&#039;, fontsize&#061;11)<br \/>\n    ax3.set_zlabel(&#039;Z&#039;, fontsize&#061;11)<br \/>\n    ax3.set_title(&#039;\u4e09\u7ef4CAD\u66f2\u7ebf\u6295\u5f71&#039;, fontsize&#061;12, fontweight&#061;&#039;bold&#039;)<br \/>\n    ax3.legend(fontsize&#061;9)<\/p>\n<p>    # 4. \u6295\u5f71\u7ed3\u679c\u6bd4\u8f83<br \/>\n    ax4 &#061; fig.add_subplot(2, 3, 4)<\/p>\n<p>    ax4.plot(projected_standard[:, 0], projected_standard[:, 1],<br \/>\n             &#039;b-&#039;, linewidth&#061;2, label&#061;&#039;\u6807\u51c6\u66f2\u7ebf\u6295\u5f71&#039;, alpha&#061;0.7)<br \/>\n    ax4.plot(projected_rational[:, 0], projected_rational[:, 1],<br \/>\n             &#039;r-&#039;, linewidth&#061;2, label&#061;&#039;\u6709\u7406\u66f2\u7ebf\u6295\u5f71&#039;, alpha&#061;0.7)<\/p>\n<p>    ax4.set_xlabel(&#039;\u6295\u5f71X&#039;, fontsize&#061;11)<br \/>\n    ax4.set_ylabel(&#039;\u6295\u5f71Y&#039;, fontsize&#061;11)<br \/>\n    ax4.set_title(&#039;\u6295\u5f71\u4e0d\u53d8\u6027\u6bd4\u8f83&#039;, fontsize&#061;12, fontweight&#061;&#039;bold&#039;)<br \/>\n    ax4.grid(True, alpha&#061;0.3)<br \/>\n    ax4.legend(fontsize&#061;9)<br \/>\n    ax4.axis(&#039;equal&#039;)<\/p>\n<p>    # 5. CAM\u5200\u5177\u8def\u5f84\u751f\u6210<br \/>\n    ax5 &#061; fig.add_subplot(2, 3, 5)<\/p>\n<p>    # \u5b9a\u4e49\u52a0\u5de5\u8f6e\u5ed3<br \/>\n    machining_points &#061; np.array([<br \/>\n        [0, 0],<br \/>\n        [1, 0],<br \/>\n        [2, 1],<br \/>\n        [3, 1],<br \/>\n        [4, 0],<br \/>\n        [5, -1],<br \/>\n        [6, 0],<br \/>\n        [7, 1],<br \/>\n        [8, 0]<br \/>\n    ])<\/p>\n<p>    # \u4f7f\u7528\u8d1d\u585e\u5c14\u66f2\u7ebf\u5e73\u6ed1\u5200\u5177\u8def\u5f84<br \/>\n    tool_paths &#061; []<br \/>\n    for i in range(0, len(machining_points)-1, 2):<br \/>\n        if i&#043;2 &lt; len(machining_points):<br \/>\n            control_tool &#061; np.array([machining_points[i],<br \/>\n                                    (machining_points[i] &#043; machining_points[i&#043;1])\/2,<br \/>\n                                    machining_points[i&#043;1],<br \/>\n                                    (machining_points[i&#043;1] &#043; machining_points[i&#043;2])\/2,<br \/>\n                                    machining_points[i&#043;2]])<\/p>\n<p>            curve_tool &#061; compute_bezier_curve_3d(<br \/>\n                np.column_stack([control_tool, np.zeros((5, 1))])<br \/>\n            )<\/p>\n<p>            ax5.plot(curve_tool[:, 0], curve_tool[:, 1], &#039;g-&#039;, linewidth&#061;2, alpha&#061;0.7)<br \/>\n            ax5.scatter(control_tool[:, 0], control_tool[:, 1],<br \/>\n                       s&#061;30, c&#061;&#039;orange&#039;, alpha&#061;0.5)<\/p>\n<p>    # \u7ed8\u5236\u539f\u59cb\u8f6e\u5ed3\u70b9<br \/>\n    ax5.plot(machining_points[:, 0], machining_points[:, 1], &#039;k&#8211;&#039;,<br \/>\n             linewidth&#061;1, alpha&#061;0.5, label&#061;&#039;\u539f\u59cb\u8f6e\u5ed3&#039;)<br \/>\n    ax5.scatter(machining_points[:, 0], machining_points[:, 1],<br \/>\n               s&#061;50, c&#061;&#039;red&#039;, alpha&#061;0.7, label&#061;&#039;\u52a0\u5de5\u70b9&#039;)<\/p>\n<p>    ax5.set_xlabel(&#039;X (mm)&#039;, fontsize&#061;11)<br \/>\n    ax5.set_ylabel(&#039;Y (mm)&#039;, fontsize&#061;11)<br \/>\n    ax5.set_title(&#039;CAM\u5200\u5177\u8def\u5f84\u751f\u6210&#039;, fontsize&#061;12, fontweight&#061;&#039;bold&#039;)<br \/>\n    ax5.grid(True, alpha&#061;0.3)<br \/>\n    ax5.legend(fontsize&#061;9)<br \/>\n    ax5.axis(&#039;equal&#039;)<\/p>\n<p>    # 6. \u5de5\u7a0b\u66f2\u9762\u8bbe\u8ba1<br \/>\n    ax6 &#061; fig.add_subplot(2, 3, 6, projection&#061;&#039;3d&#039;)<\/p>\n<p>    # \u521b\u5efa\u66f2\u9762\u63a7\u5236\u7f51\u683c<br \/>\n    u &#061; np.linspace(0, 1, 5)<br \/>\n    v &#061; np.linspace(0, 1, 5)<\/p>\n<p>    # \u521b\u5efa\u63a7\u5236\u70b9\u7f51\u683c<br \/>\n    control_grid &#061; np.zeros((5, 5, 3))<br \/>\n    for i in range(5):<br \/>\n        for j in range(5):<br \/>\n            control_grid[i, j] &#061; [u[i]*8, v[j]*6, np.sin(u[i]*np.pi)*np.cos(v[j]*np.pi)*2]<\/p>\n<p>    # \u7ed8\u5236\u63a7\u5236\u7f51\u683c<br \/>\n    for i in range(5):<br \/>\n        ax6.plot(control_grid[i, :, 0], control_grid[i, :, 1], control_grid[i, :, 2],<br \/>\n                &#039;r-&#039;, linewidth&#061;1, alpha&#061;0.5)<br \/>\n    for j in range(5):<br \/>\n        ax6.plot(control_grid[:, j, 0], control_grid[:, j, 1], control_grid[:, j, 2],<br \/>\n                &#039;r-&#039;, linewidth&#061;1, alpha&#061;0.5)<\/p>\n<p>    # \u7ed8\u5236\u63a7\u5236\u70b9<br \/>\n    ax6.scatter(control_grid[:, :, 0].flatten(),<br \/>\n               control_grid[:, :, 1].flatten(),<br \/>\n               control_grid[:, :, 2].flatten(),<br \/>\n               c&#061;&#039;b&#039;, s&#061;30, alpha&#061;0.7)<\/p>\n<p>    ax6.set_xlabel(&#039;X&#039;, fontsize&#061;11)<br \/>\n    ax6.set_ylabel(&#039;Y&#039;, fontsize&#061;11)<br \/>\n    ax6.set_zlabel(&#039;Z&#039;, fontsize&#061;11)<br \/>\n    ax6.set_title(&#039;\u5de5\u7a0b\u66f2\u9762\u8bbe\u8ba1 (NURBS\u57fa\u7840)&#039;, fontsize&#061;12, fontweight&#061;&#039;bold&#039;)<\/p>\n<p>    fig.suptitle(&#039;CAD\/CAM\u5e94\u7528&#xff1a;&#039; \\\\<br \/>\n    &#039;\u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u4fdd\u6301\u6295\u5f71\u4e0d\u53d8\u6027&#039;, fontsize&#061;16, fontweight&#061;&#039;bold&#039;)<br \/>\n    fig.tight_layout()<br \/>\n    return fig<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table>\n<tbody>\n<tr>\n<td>\n<p>&gt;&gt;&gt;\n<\/td>\n<td>\n<p># \u6267\u884cCAD\/CAM\u6848\u4f8b<br \/>\nfig_cad_cam &#061; bezier_application_cad_cam()<br \/>\nfig_cad_cam<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"507\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/02\/20260222072609-699aaf91b90d1.png\" width=\"709\" \/><\/p>\n<\/p>\n<h4 id=\"auto-62\">7. \u603b\u7ed3<\/h4>\n<h5 id=\"auto-63\">7.1 \u6807\u51c6\u8d1d\u585e\u5c14\u66f2\u7ebf\u5173\u952e\u7279\u6027<\/h5>\n<\/p>\n<li>\n<p>\u6570\u5b66\u57fa\u7840&#xff1a;\u57fa\u4e8e\u4f2f\u6069\u65af\u5766\u57fa\u51fd\u6570&#xff0c;\u5177\u6709\u826f\u597d\u7684\u6570\u503c\u7a33\u5b9a\u6027<\/p>\n<\/li>\n<li>\n<p>\u51e0\u4f55\u76f4\u89c2&#xff1a;\u901a\u8fc7\u63a7\u5236\u70b9\u76f4\u63a5\u63a7\u5236\u66f2\u7ebf\u5f62\u72b6<\/p>\n<\/li>\n<li>\n<p>\u51f8\u5305\u6027&#xff1a;\u66f2\u7ebf\u59cb\u7ec8\u4f4d\u4e8e\u63a7\u5236\u70b9\u7684\u51f8\u5305\u5185<\/p>\n<\/li>\n<li>\n<p>\u7aef\u70b9\u63d2\u503c&#xff1a;\u66f2\u7ebf\u901a\u8fc7\u7b2c\u4e00\u4e2a\u548c\u6700\u540e\u4e00\u4e2a\u63a7\u5236\u70b9<\/p>\n<\/li>\n<li>\n<p>\u53d8\u5dee\u7f29\u51cf\u6027&#xff1a;\u66f2\u7ebf\u6ce2\u52a8\u4e0d\u8d85\u8fc7\u63a7\u5236\u591a\u8fb9\u5f62\u6ce2\u52a8<\/p>\n<\/li>\n<li>\n<p>\u4eff\u5c04\u4e0d\u53d8\u6027&#xff1a;\u5bf9\u63a7\u5236\u70b9\u7684\u4eff\u5c04\u53d8\u6362\u7b49\u4ef7\u4e8e\u5bf9\u66f2\u7ebf\u7684\u76f8\u540c\u53d8\u6362<\/p>\n<\/li>\n<h5 id=\"auto-64\">7.2 \u6709\u7406\u8d1d\u585e\u5c14\u66f2\u7ebf\u4f18\u52bf<\/h5>\n<\/p>\n<li>\n<p>\u6295\u5f71\u4e0d\u53d8\u6027&#xff1a;\u5728\u6295\u5f71\u53d8\u6362\u4e0b\u4fdd\u6301\u4e0d\u53d8<\/p>\n<\/li>\n<li>\n<p>\u6743\u91cd\u63a7\u5236&#xff1a;\u901a\u8fc7\u6743\u91cd\u53c2\u6570\u63d0\u4f9b\u989d\u5916\u63a7\u5236\u81ea\u7531\u5ea6<\/p>\n<\/li>\n<li>\n<p>\u7cbe\u786e\u8868\u793a&#xff1a;\u53ef\u4ee5\u7cbe\u786e\u8868\u793a\u5706\u9525\u66f2\u7ebf<\/p>\n<\/li>\n<li>\n<p>\u5411\u540e\u517c\u5bb9&#xff1a;\u5f53\u6240\u6709\u6743\u91cd\u76f8\u7b49\u65f6&#xff0c;\u9000\u5316\u4e3a\u6807\u51c6\u8d1d\u585e\u5c14\u66f2\u7ebf<\/p>\n<\/li>\n<h5 id=\"auto-65\">7.3 \u8fde\u7eed\u6027\u6761\u4ef6<\/h5>\n<\/p>\n<li>\n<p>\u4f4d\u7f6e\u8fde\u7eed&#xff08;C\u2070&#xff09;&#xff1a;Pn&#061;Q0<\/p>\n<\/li>\n<li>\n<p>\u5207\u7ebf\u65b9\u5411\u8fde\u7eed&#xff08;G\u00b9&#xff09;&#xff1a;Pn-1,Pn&#061;Q0,Q1\u00a0\u4e09\u70b9\u5171\u7ebf<\/p>\n<\/li>\n<li>\n<p>\u5207\u7ebf\u8fde\u7eed&#xff08;C\u00b9&#xff09;&#xff1a;n\u2062(Pn-Pn-1)&#061;m\u2062(Q1-Q0)<\/p>\n<\/li>\n<li>\n<p>\u66f2\u7387\u8fde\u7eed&#xff08;G\u00b2\/C\u00b2&#xff09;&#xff1a;\u9700\u8981\u6ee1\u8db3\u4e8c\u9636\u5bfc\u6570\u6761\u4ef6<\/p>\n<\/li>\n","protected":false},"excerpt":{"rendered":"<p>\u58f0\u660e&#xff1a;\u672c\u5b66\u4e60\u7b14\u8bb0\u4f7f\u7528\u57fa\u4e8eGNU TeXmacs\u7684\u4e13\u4e1a\u7f16\u8f91\u5de5\u5177\u548cpython\u73af\u5883\u5b9e\u73b0&#xff0c;\u5185\u5bb9\u6765\u81ea\u4e8e\u7f51\u7edc\u6574\u7406\u5b66\u4e60&#xff0c;\u5185\u5d4c\u4ee3\u7801\u7531AI\u8f85\u52a9\u5e76\u624b\u52a8\u8c03\u8bd5\u901a\u8fc7&#xff0c;\u5c3d\u7ba1\u4e3a\u4e86\u4e0a\u4f20\u505a\u4e86\u624b\u52a8\u5904\u7406&#xff0c;\u5948\u4f55\u517c\u5bb9\u6027\u6b20\u4f73&#xff0c;\u65e0\u6cd5\u5b9e\u73b0\u539f\u5f00\u53d1\u73af\u5883\u6d4f\u89c8\u6548\u679c\u30021. \u4f2f\u6069\u65af\u5766\u57fa\u51fd\u65701.1 \u6570\u5b66\u5b9a\u4e49\u4f2f\u6069\u65af\u5766\u57fa\u51fd\u6570\u662f\u8d1d\u585e\u5c14\u66f2\u7ebf\u7684\u6570\u5b66\u57fa\u7840\u3002\u5bf9\u4e8e\u975e\u8d1f\u6574\u6570\u00a0n\u00a0\u548c\u6574\u6570\u00a0i&#xff08;0\u2264i\u2264n&#xff09;&#xff0c;\u7b2c\u00a0i\u00a0\u4e2a\u00a0n\u00a0\u6b21\u4f2f\u6069\u65af<\/p>\n","protected":false},"author":2,"featured_media":76482,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[8232,7643,2468,81,1482,427],"topic":[],"class_list":["post-76494","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-server","tag-8232","tag-7643","tag-matplotlib","tag-python","tag-1482","tag-427"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.3 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>\u8d1d\u585e\u5c14\u66f2\u7ebf\uff1a\u6570\u5b66\u63a8\u5bfc\u4e0ePython\u5b9e\u73b0 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.wsisp.com\/helps\/76494.html\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\u8d1d\u585e\u5c14\u66f2\u7ebf\uff1a\u6570\u5b66\u63a8\u5bfc\u4e0ePython\u5b9e\u73b0 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"og:description\" content=\"\u58f0\u660e&#xff1a;\u672c\u5b66\u4e60\u7b14\u8bb0\u4f7f\u7528\u57fa\u4e8eGNU TeXmacs\u7684\u4e13\u4e1a\u7f16\u8f91\u5de5\u5177\u548cpython\u73af\u5883\u5b9e\u73b0&#xff0c;\u5185\u5bb9\u6765\u81ea\u4e8e\u7f51\u7edc\u6574\u7406\u5b66\u4e60&#xff0c;\u5185\u5d4c\u4ee3\u7801\u7531AI\u8f85\u52a9\u5e76\u624b\u52a8\u8c03\u8bd5\u901a\u8fc7&#xff0c;\u5c3d\u7ba1\u4e3a\u4e86\u4e0a\u4f20\u505a\u4e86\u624b\u52a8\u5904\u7406&#xff0c;\u5948\u4f55\u517c\u5bb9\u6027\u6b20\u4f73&#xff0c;\u65e0\u6cd5\u5b9e\u73b0\u539f\u5f00\u53d1\u73af\u5883\u6d4f\u89c8\u6548\u679c\u30021. \u4f2f\u6069\u65af\u5766\u57fa\u51fd\u65701.1 \u6570\u5b66\u5b9a\u4e49\u4f2f\u6069\u65af\u5766\u57fa\u51fd\u6570\u662f\u8d1d\u585e\u5c14\u66f2\u7ebf\u7684\u6570\u5b66\u57fa\u7840\u3002\u5bf9\u4e8e\u975e\u8d1f\u6574\u6570\u00a0n\u00a0\u548c\u6574\u6570\u00a0i&#xff08;0\u2264i\u2264n&#xff09;&#xff0c;\u7b2c\u00a0i\u00a0\u4e2a\u00a0n\u00a0\u6b21\u4f2f\u6069\u65af\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.wsisp.com\/helps\/76494.html\" \/>\n<meta property=\"og:site_name\" content=\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"article:published_time\" content=\"2026-02-22T07:26:10+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/02\/20260222072608-699aaf906c644.png\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"36 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/76494.html\",\"url\":\"https:\/\/www.wsisp.com\/helps\/76494.html\",\"name\":\"\u8d1d\u585e\u5c14\u66f2\u7ebf\uff1a\u6570\u5b66\u63a8\u5bfc\u4e0ePython\u5b9e\u73b0 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"isPartOf\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\"},\"datePublished\":\"2026-02-22T07:26:10+00:00\",\"dateModified\":\"2026-02-22T07:26:10+00:00\",\"author\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/76494.html#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.wsisp.com\/helps\/76494.html\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/76494.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.wsisp.com\/helps\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u8d1d\u585e\u5c14\u66f2\u7ebf\uff1a\u6570\u5b66\u63a8\u5bfc\u4e0ePython\u5b9e\u73b0\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\",\"url\":\"https:\/\/www.wsisp.com\/helps\/\",\"name\":\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"description\":\"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"contentUrl\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"caption\":\"admin\"},\"sameAs\":[\"http:\/\/wp.wsisp.com\"],\"url\":\"https:\/\/www.wsisp.com\/helps\/author\/admin\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"\u8d1d\u585e\u5c14\u66f2\u7ebf\uff1a\u6570\u5b66\u63a8\u5bfc\u4e0ePython\u5b9e\u73b0 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.wsisp.com\/helps\/76494.html","og_locale":"zh_CN","og_type":"article","og_title":"\u8d1d\u585e\u5c14\u66f2\u7ebf\uff1a\u6570\u5b66\u63a8\u5bfc\u4e0ePython\u5b9e\u73b0 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","og_description":"\u58f0\u660e&#xff1a;\u672c\u5b66\u4e60\u7b14\u8bb0\u4f7f\u7528\u57fa\u4e8eGNU TeXmacs\u7684\u4e13\u4e1a\u7f16\u8f91\u5de5\u5177\u548cpython\u73af\u5883\u5b9e\u73b0&#xff0c;\u5185\u5bb9\u6765\u81ea\u4e8e\u7f51\u7edc\u6574\u7406\u5b66\u4e60&#xff0c;\u5185\u5d4c\u4ee3\u7801\u7531AI\u8f85\u52a9\u5e76\u624b\u52a8\u8c03\u8bd5\u901a\u8fc7&#xff0c;\u5c3d\u7ba1\u4e3a\u4e86\u4e0a\u4f20\u505a\u4e86\u624b\u52a8\u5904\u7406&#xff0c;\u5948\u4f55\u517c\u5bb9\u6027\u6b20\u4f73&#xff0c;\u65e0\u6cd5\u5b9e\u73b0\u539f\u5f00\u53d1\u73af\u5883\u6d4f\u89c8\u6548\u679c\u30021. \u4f2f\u6069\u65af\u5766\u57fa\u51fd\u65701.1 \u6570\u5b66\u5b9a\u4e49\u4f2f\u6069\u65af\u5766\u57fa\u51fd\u6570\u662f\u8d1d\u585e\u5c14\u66f2\u7ebf\u7684\u6570\u5b66\u57fa\u7840\u3002\u5bf9\u4e8e\u975e\u8d1f\u6574\u6570\u00a0n\u00a0\u548c\u6574\u6570\u00a0i&#xff08;0\u2264i\u2264n&#xff09;&#xff0c;\u7b2c\u00a0i\u00a0\u4e2a\u00a0n\u00a0\u6b21\u4f2f\u6069\u65af","og_url":"https:\/\/www.wsisp.com\/helps\/76494.html","og_site_name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","article_published_time":"2026-02-22T07:26:10+00:00","og_image":[{"url":"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/02\/20260222072608-699aaf906c644.png"}],"author":"admin","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"admin","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"36 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.wsisp.com\/helps\/76494.html","url":"https:\/\/www.wsisp.com\/helps\/76494.html","name":"\u8d1d\u585e\u5c14\u66f2\u7ebf\uff1a\u6570\u5b66\u63a8\u5bfc\u4e0ePython\u5b9e\u73b0 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","isPartOf":{"@id":"https:\/\/www.wsisp.com\/helps\/#website"},"datePublished":"2026-02-22T07:26:10+00:00","dateModified":"2026-02-22T07:26:10+00:00","author":{"@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41"},"breadcrumb":{"@id":"https:\/\/www.wsisp.com\/helps\/76494.html#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.wsisp.com\/helps\/76494.html"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.wsisp.com\/helps\/76494.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.wsisp.com\/helps"},{"@type":"ListItem","position":2,"name":"\u8d1d\u585e\u5c14\u66f2\u7ebf\uff1a\u6570\u5b66\u63a8\u5bfc\u4e0ePython\u5b9e\u73b0"}]},{"@type":"WebSite","@id":"https:\/\/www.wsisp.com\/helps\/#website","url":"https:\/\/www.wsisp.com\/helps\/","name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","description":"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41","name":"admin","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/","url":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","contentUrl":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","caption":"admin"},"sameAs":["http:\/\/wp.wsisp.com"],"url":"https:\/\/www.wsisp.com\/helps\/author\/admin"}]}},"_links":{"self":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/76494","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/comments?post=76494"}],"version-history":[{"count":0,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/76494\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/media\/76482"}],"wp:attachment":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/media?parent=76494"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/categories?post=76494"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/tags?post=76494"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/topic?post=76494"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}