JavaScript 曲线生成

发布于 2024-12-07 07:11:54 字数 124 浏览 0 评论 0原文

如何编写一个函数,接受 2D 点数组并返回贝塞尔/二次曲线,以便稍后使用 HTML5 Canvas bezierCurveToquadraticCurveTo 重新绘制它方法?

How can I write a function that takes an array of 2D points and returns the Bezier/Quadractic curve(s) so I can redraw it later using the HTML5 Canvas bezierCurveTo or quadraticCurveTo method?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

紫瑟鸿黎 2024-12-14 07:11:54

编辑:改进。

查看使用以下代码的演示

var makeCurveArgs = function(points) {
  var copy = points.slice();
  var result = [];
  copy.shift(); //drop the first point, it will be handled elsewhere
  var tangent;
  if(copy.length >= 3) {
    var cp1 = copy.shift();
    var cp2 = copy.shift();
    var p2 = copy.shift();

    result.push([cp1[0], cp1[1], cp2[0], cp2[1], p2[0], p2[1]]);            
  }
  while(copy.length >= 2) {
    var cp1 = [2 * p2[0] - cp2[0], 2 * p2[1] - cp2[1]];
    var cp2 = copy.shift();
    var p2 = copy.shift();
    result.push([cp1[0], cp1[1], cp2[0], cp2[1], p2[0], p2[1]]);            
  }
  return result;
}

var notThatHard = function(points) {
  var origin = points[0].slice();
  var curves = makeCurveArgs(points);
  var drawCurves = function(context) {


    context.beginPath();
    context.moveTo(origin[0], origin[1]);
      for(var i = 0; i < curves.length; i++) {
      var c = curves[i];
      context.bezierCurveTo(c[0], c[1], c[2], c[3], c[4], c[5]);
  }
  };
  return drawCurves;
};

一般方法是,您给我点和控制点的坐标,然后我给您返回一个函数,该函数将在画布上下文上执行该路径。

我给出的函数需要一个 2N+2 2 元素数组的数组;每个 2 元素数组都是一个 (x,y) 坐标。坐标的使用方式如下:

points[0]: starting point of the curve
points[1]: lies on a line tangent to the beginning of the 1st bezier curve
points[2]: lies on a line tangent to the end of the 1st bezier curve
points[3]: end of 1st bezier curve, start of 2nd bezier curve
points[4]: lies on a line tangent to the end of the 2nd bezier curve
points[5]: end of 2nd bezier curve, start of 3rd curve
...
points[2*K+2]: lies on a line tangent to the end of the Kth bezier curve
points[2*K+3]: end of Kth bezier curve, start of (K+1)th

我认为编写一个类似的 QuadraticCurveTo 函数并不难。

EDIT: improved.

See a demo which uses the code below.

var makeCurveArgs = function(points) {
  var copy = points.slice();
  var result = [];
  copy.shift(); //drop the first point, it will be handled elsewhere
  var tangent;
  if(copy.length >= 3) {
    var cp1 = copy.shift();
    var cp2 = copy.shift();
    var p2 = copy.shift();

    result.push([cp1[0], cp1[1], cp2[0], cp2[1], p2[0], p2[1]]);            
  }
  while(copy.length >= 2) {
    var cp1 = [2 * p2[0] - cp2[0], 2 * p2[1] - cp2[1]];
    var cp2 = copy.shift();
    var p2 = copy.shift();
    result.push([cp1[0], cp1[1], cp2[0], cp2[1], p2[0], p2[1]]);            
  }
  return result;
}

var notThatHard = function(points) {
  var origin = points[0].slice();
  var curves = makeCurveArgs(points);
  var drawCurves = function(context) {


    context.beginPath();
    context.moveTo(origin[0], origin[1]);
      for(var i = 0; i < curves.length; i++) {
      var c = curves[i];
      context.bezierCurveTo(c[0], c[1], c[2], c[3], c[4], c[5]);
  }
  };
  return drawCurves;
};

The general approach is that you give me the coordinates of your points and control points and I give you back a function which will execute that path on a canvas context.

The function I give requires an array of 2N+2 2-element arrays; each 2-element array is an (x,y) coordinate. The coordinates are used as follows:

points[0]: starting point of the curve
points[1]: lies on a line tangent to the beginning of the 1st bezier curve
points[2]: lies on a line tangent to the end of the 1st bezier curve
points[3]: end of 1st bezier curve, start of 2nd bezier curve
points[4]: lies on a line tangent to the end of the 2nd bezier curve
points[5]: end of 2nd bezier curve, start of 3rd curve
...
points[2*K+2]: lies on a line tangent to the end of the Kth bezier curve
points[2*K+3]: end of Kth bezier curve, start of (K+1)th

I think a similar function for quadraticCurveTo wouldn't be hard to write.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文