【问题标题】:Get coordinates of half of the length of the bezier curve获取贝塞尔曲线长度一半的坐标
【发布时间】:2018-09-20 00:09:05
【问题描述】:

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

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

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

如何获取这些点的坐标?

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

【问题讨论】:

标签: javascript html canvas bezier


【解决方案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 的分割点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-01
    • 2017-09-09
    • 2014-09-29
    • 1970-01-01
    • 1970-01-01
    • 2017-06-25
    • 1970-01-01
    相关资源
    最近更新 更多