如何连接多条贝塞尔曲线?

我想用 来画一个图bezierCurveTo()。据我所知,只能设置 3 个锚点 1 bezierCurveTo()。如果我使用多个,我会得到一条不平滑的线。我该如何解决这个问题?


<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> 


凤凰求蛊
浏览 151回答 2
2回答

皈依舞

这是一个不平凡的问题。这取决于您想要实现的平滑程度(只需连接切线,或使连接点的曲线半径相同)。最简单的方法如图所示([A3-X] / [X-B2] = [A3-A4] / [B1-B2];从 A4 开始 [A3-X] 向量,从 B1 开始 [X-B2] 到获取 A3x 和 B2x 锚点)。但您也可以查看D3 Shape 模块(例如 Catmul Rom 曲线),它会从它应该经过的点生成贝塞尔样条曲线。或者看看某处的算法。

www说

我们可以将所有曲线放入一个数组中,然后循环它们,在绘制下一条贝塞尔曲线之前移动到最后一个点。下面是示例代码:<canvas id="myCanvas" width="600" height="150"></canvas><script>&nbsp; &nbsp; var canvas = document.getElementById('myCanvas');&nbsp; &nbsp; var context = canvas.getContext('2d');&nbsp; &nbsp; function drawCurve(x, y, curves) {&nbsp; &nbsp; &nbsp; &nbsp; context.beginPath();&nbsp; &nbsp; &nbsp; &nbsp; context.moveTo(x, y);&nbsp; &nbsp; &nbsp; &nbsp; for (i = 0; i < curves.length; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c = curves[i]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; context.bezierCurveTo(c[0], c[1], c[2], c[3], c[4], c[5]);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; context.moveTo(c[4], c[5]);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; context.stroke();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; context.strokeStyle = 'blue';&nbsp; &nbsp; drawCurve(0, 150, [&nbsp; &nbsp; &nbsp; &nbsp; [100, 0, 200, 100, 300, 50],&nbsp; &nbsp; &nbsp; &nbsp; [400, 0, 500, 100, 600, 20]&nbsp; &nbsp; ]);&nbsp; &nbsp; context.strokeStyle = 'red';&nbsp; &nbsp; drawCurve(0, 10, [&nbsp; &nbsp; &nbsp; &nbsp; [100, 0, 180, 90, 280, 50],&nbsp; &nbsp; &nbsp; &nbsp; [400, 0, 400, 80, 600, 120]&nbsp; &nbsp; ]);&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; context.strokeStyle = 'green';&nbsp; &nbsp; drawCurve(0, 80, [&nbsp; &nbsp; &nbsp; &nbsp; [100, 0, 90, 45, 140, 25],&nbsp; &nbsp; &nbsp; &nbsp; [200, 0, 200, 40, 300, 50],&nbsp; &nbsp; &nbsp; &nbsp; [500, 60, 400, 80, 300, 120],&nbsp; &nbsp; &nbsp; &nbsp; [300, 120, 200, 160, 100, 80],&nbsp; &nbsp; ]);</script>但“不平滑的线”也取决于你的曲线,如果它们的方向完全相反,我们会看到尖锐的边缘。请参阅下面的示例,我正在绘制一颗星星。<canvas id="myCanvas" width="150" height="150"></canvas><script>&nbsp; var canvas = document.getElementById('myCanvas');&nbsp; var context = canvas.getContext('2d');&nbsp; function drawCurve(x, y, curves) {&nbsp; &nbsp; context.moveTo(x, y);&nbsp; &nbsp; for (i = 0; i < curves.length; i++) {&nbsp; &nbsp; &nbsp; c = curves[i]&nbsp; &nbsp; &nbsp; context.bezierCurveTo(c[0], c[1], c[2], c[3], c[4], c[5]);&nbsp; &nbsp; &nbsp; context.moveTo(c[4], c[5]);&nbsp; &nbsp; }&nbsp; &nbsp; context.stroke();&nbsp; }&nbsp; data = []&nbsp; numPoints = 12&nbsp; size = 35&nbsp; angle = 45&nbsp; for (j = 0; j < numPoints; j++) {&nbsp; &nbsp; a = angle * Math.PI / 180&nbsp; &nbsp; points = []&nbsp; &nbsp; points.push(80 + Math.round(size / 2 * Math.sin(a)))&nbsp; &nbsp; points.push(80 + Math.round(size / 2 * Math.cos(a)))&nbsp; &nbsp; points.push(80 + Math.round(size * Math.sin(a)))&nbsp; &nbsp; points.push(80 + Math.round(size * Math.cos(a)))&nbsp; &nbsp; points.push(80 + Math.round(size * 2 * Math.sin(a)))&nbsp; &nbsp; points.push(80 + Math.round(size * 2 * Math.cos(a)))&nbsp; &nbsp; angle += 360 / numPoints&nbsp; &nbsp; data.push(points)&nbsp; }&nbsp; drawCurve(80, 80, data);</script>
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Html5