获取贝塞尔曲线长度的一半的坐标

时间:2018-09-18 08:47:05

标签: javascript html canvas bezier

我有一个用4个贝塞尔曲线绘制的椭圆。

我想在每个贝塞尔曲线上画一个点。

该点应位于贝塞尔曲线长度的中间(贝塞尔曲线长度的一半)。

如何获取这些点的坐标?

有没有公式或算法可以做到?

picture which hopefully will describe my question

1 个答案:

答案 0 :(得分:-1)

我的解决方案也不是真正的省略号,如@ Mike'Pomax'Kamermans所强调的那样,而是类似椭圆的贝塞尔曲线。如果 half 表示底部曲线的 length 的3:1分割点(而不是与轴成45度),则使用ctx并使用@ivan来解决此问题-kuckir的interpolation function

function interpolate(a, b, frac){
  var nx = a.x+(b.x-a.x)*frac;
  var ny = a.y+(b.y-a.y)*frac;
  return {x:nx,  y:ny};
}

function getDivisionPointOfBezier(cp1, cp2, cp3, cp4, frac) {
  var p1 = interpolate(cp1, cp2, frac);
  var p2 = interpolate(cp2, cp3, frac);
  var p3 = interpolate(cp3, cp4, frac);

  var p4 = interpolate(p1, p2, frac);
  var p5 = interpolate(p2, p3, frac);

  var p6 = interpolate(p4, p5, frac);
  return p6;
}

// control points of the ellipsis bezier
var cp1 = {x:0, y:50};
var cp2 = {x:0, y:100};
var cp3 = {x:200, y:100};
var cp4 = {x:200, y:50};
var cp5 = {x:200, y:0};
var cp6 = {x:0, y:0};


var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");


ctx.beginPath();

// bottom half-curve
ctx.moveTo(cp1.x, cp1.y);
ctx.bezierCurveTo(cp2.x, cp2.y, cp3.x, cp3.y, cp4.x, cp4.y);

// top half-curve
ctx.moveTo(cp4.x, cp4.y);
ctx.bezierCurveTo(cp5.x, cp5.y, cp6.x, cp6.y, cp1.x, cp1.y);

ctx.stroke();

// draw red point
var divPoint = getDivisionPointOfBezier(cp1, cp2, cp3, cp4, 0.75);
ctx.beginPath();
ctx.fillStyle = 'red';
ctx.arc(divPoint.x,divPoint.y,5,0,2*Math.PI);
ctx.fill();
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;">
</canvas>

此图表示底部的计算。 bézier algorithm如何计算每个点的位置(黑点代表控制点),我们正在寻找3:1分割点。 enter image description here