如何使用本地JavaScript代码绘制Bezier曲线而不使用ctx.bezierCurveTo?

18

我需要使用本地JavaScript绘制并获取每个步骤的贝塞尔曲线坐标,而不使用ctx.bezierCurveTo方法。

我找到了几个资源,但有些让我感到困惑。特别是这个看起来很接近,但我无法清楚地实现它。

我该如何完成这个任务呢?


这是使用C语言(带有OpenGL)的方法,但是思路应该是相同的:http://pastebin.com/XuiPMSuZ - nhahtdh
@Hydrangea 我已经写了一个AI格式解析器,就这样。 - Digerkam
@Digerkam:那只是一个使用你提供的链接中的公式的函数。 - nhahtdh
@RaymondChen 因为我不需要“绘制”,我只需要路径上的像素值。 - Digerkam
哦,好的,你不感兴趣画它们。(你的问题说你想画它们。) - Raymond Chen
显示剩余3条评论
2个回答

44
您可以绘制贝塞尔曲线:
bezier = function(t, p0, p1, p2, p3){
  var cX = 3 * (p1.x - p0.x),
      bX = 3 * (p2.x - p1.x) - cX,
      aX = p3.x - p0.x - cX - bX;

  var cY = 3 * (p1.y - p0.y),
      bY = 3 * (p2.y - p1.y) - cY,
      aY = p3.y - p0.y - cY - bY;

  var x = (aX * Math.pow(t, 3)) + (bX * Math.pow(t, 2)) + (cX * t) + p0.x;
  var y = (aY * Math.pow(t, 3)) + (bY * Math.pow(t, 2)) + (cY * t) + p0.y;

  return {x: x, y: y};
},

(function(){
  var accuracy = 0.01, //this'll give the bezier 100 segments
      p0 = {x: 10, y: 10}, //use whatever points you want obviously
      p1 = {x: 50, y: 100},
      p2 = {x: 150, y: 200},
      p3 = {x: 200, y: 75},
      ctx = document.createElement('canvas').getContext('2d');

  ctx.width = 500;
  ctx.height = 500;
  document.body.appendChild(ctx.canvas);

  ctx.moveTo(p0.x, p0.y);
  for (var i=0; i<1; i+=accuracy){
     var p = bezier(i, p0, p1, p2, p3);
     ctx.lineTo(p.x, p.y);
  }

  ctx.stroke()
})()

Here's a fiddle http://jsfiddle.net/fQYsU/


2
我正在制作一个JavaScript SVG路径解释器(出于完全正当的原因,请勿评判),贝塞尔曲线对我来说非常重要,这是我的关注点 :) - LarsW
1
你能否解释一下为什么Y只是控制点的Y分量的函数吗?谢谢兄弟。 - neaumusic

2

这里是一个代码示例,可以添加任意数量的点来生成贝塞尔曲线。 你需要传递一个包含点的x和y值的对象数组。 [ { x: 1,y: 2 } , { x: 3,y: 4} ... ]

function factorial(n) {
    if(n<0)    
        return(-1); /*Wrong value*/      
    if(n==0)    
        return(1);  /*Terminating condition*/    
    else    
    {    
        return(n*factorial(n-1));        
    }
}

function nCr(n,r) {
    return( factorial(n) / ( factorial(r) * factorial(n-r) ) );
}

function BezierCurve(points) {
    let n=points.length;
    let curvepoints=[];
    for(let u=0; u <= 1 ; u += 0.0001 ){

        let p={x:0,y:0};

        for(let i=0 ; i<n ; i++){
            let B=nCr(n-1,i)*Math.pow((1-u),(n-1)-i)*Math.pow(u,i);
            let px=points[i].x*B;
            let py=points[i].y*B;
            
            p.x+=px;
            p.y+=py;
            
        }

        curvepoints.push(p);
    }
    
    return curvepoints;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接