簡體   English   中英

如何連接多條貝塞爾曲線?

[英]How to connect multiple bezier curves?

我想使用bezierCurveTo()繪制圖表。 據我所知,只能用 1 個bezierCurveTo()設置 3 個錨點。 如果我使用其中的多個,我會得到一條不平滑的線。 我該如何解決這個問題?

 <canvas id="myCanvas" width="600" height="150" style="border:1px solid #d3d3d3;"></canvas> <script> var canvas = document.getElementById('myCanvas'); var context = canvas.getContext('2d'); context.beginPath(); context.moveTo(0, 150); context.bezierCurveTo(100, 0, 200, 100, 300, 20); context.bezierCurveTo(400, 0, 500, 100, 600, 20); context.strokeStyle = 'blue'; context.stroke(); </script>

這是一個不平凡的問題。 這取決於您想要達到多少平滑度(只需連接切線,或使連接點中的曲線半徑相同)。 最簡單的方法如圖 ([A3-X] / [X-B2] = [A3-A4] / [B1-B2]; 從 A4 開始 [A3-X] 向量和從 B1 到 [X-B2]獲得 A3x 和 B2x 錨點)。 在此處輸入圖片說明

但是你也可以看看D3 Shape 模塊(例如 Catmul Rom 曲線),它會從它應該通過的點生成一個 Bezier 樣條。 或者在某處查看算法。

我們可以將所有曲線放在一個數組中,然后循環遍歷它們,在繪制下一條貝塞爾曲線之前移動到最后一個點。 下面是一個示例代碼:

 <canvas id="myCanvas" width="600" height="150"></canvas> <script> var canvas = document.getElementById('myCanvas'); var context = canvas.getContext('2d'); function drawCurve(x, y, curves) { context.beginPath(); context.moveTo(x, y); for (i = 0; i < curves.length; i++) { c = curves[i] context.bezierCurveTo(c[0], c[1], c[2], c[3], c[4], c[5]); context.moveTo(c[4], c[5]); context.stroke(); } } context.strokeStyle = 'blue'; drawCurve(0, 150, [ [100, 0, 200, 100, 300, 50], [400, 0, 500, 100, 600, 20] ]); context.strokeStyle = 'red'; drawCurve(0, 10, [ [100, 0, 180, 90, 280, 50], [400, 0, 400, 80, 600, 120] ]); context.strokeStyle = 'green'; drawCurve(0, 80, [ [100, 0, 90, 45, 140, 25], [200, 0, 200, 40, 300, 50], [500, 60, 400, 80, 300, 120], [300, 120, 200, 160, 100, 80], ]); </script>

但是“不平滑的線”也取決於你的曲線,如果它們的方向完全相反,我們會看到一個尖銳的邊緣。

請參閱下面的示例,我正在繪制一顆星星。

 <canvas id="myCanvas" width="150" height="150"></canvas> <script> var canvas = document.getElementById('myCanvas'); var context = canvas.getContext('2d'); function drawCurve(x, y, curves) { context.moveTo(x, y); for (i = 0; i < curves.length; i++) { c = curves[i] context.bezierCurveTo(c[0], c[1], c[2], c[3], c[4], c[5]); context.moveTo(c[4], c[5]); } context.stroke(); } data = [] numPoints = 12 size = 35 angle = 45 for (j = 0; j < numPoints; j++) { a = angle * Math.PI / 180 points = [] points.push(80 + Math.round(size / 2 * Math.sin(a))) points.push(80 + Math.round(size / 2 * Math.cos(a))) points.push(80 + Math.round(size * Math.sin(a))) points.push(80 + Math.round(size * Math.cos(a))) points.push(80 + Math.round(size * 2 * Math.sin(a))) points.push(80 + Math.round(size * 2 * Math.cos(a))) angle += 360 / numPoints data.push(points) } drawCurve(80, 80, data); </script>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM