まずは、ベジェ曲線について学ぶ。

ベジェ曲線を、canvas に描いてみる。
遊んでみて理解する。4点を超える高次元の計算は確かに無駄。
ウィキペディアの「ベジェ曲線」を見るも

こういうものを見るといつものように思考が停止する&眠くなる。

<!DOCTYPE html>
<title>Be'zier Curve</title>
<meta charset="UTF-8">


<canvas id="hoge" width="800" height="600"></canvas>

<script>

(function () {
  
  function Graffiti (canvas) {
    this.ctx = canvas.getContext ('2d');
  }
  
  
  function line (/*[x0, y0], [x1, y1], ...*/) {
    var index = 0;
    var x = arguments[index][0];
    var y = arguments[index][1];
    var arg;
    var ctx = this.ctx;
    
    ctx.beginPath ();
    ctx.moveTo (x, y);
    
    while (arg = arguments[++index]) {
      if ('b' === arg) {
        ctx.closePath ();
        break;
      }
      if ('bx' === arg) {
        ctx.closePath ();
        ctx.fillRect ();
        break;
      }
      ctx.lineTo (arg[0], arg[1]);
    }
    ctx.stroke ();
    
    return this;
  }
  
  function pset (x, y, c) {
    var ctx = this.ctx;
    if (c instanceof Array) {
      ctx.fillStyle = 'rgb(' + c[0] + ',' + c[1] +',' + c[2] + ')';
    }
    
    ctx.fillRect (x, y, 1, 1);
    return this;  
  }  


  function create (canvas) {
    if (! canvas.getContext)
      return null;
    return new Graffiti (canvas);
  }
  
  
  //__________
  
  Graffiti.prototype.line = line;
  Graffiti.prototype.pset = pset;
  
  Graffiti.create = create;
  
  this.Graffiti = Graffiti;
})();


// Bezier Curve
(function () {

  function BezierCurve (x, y) {
    this.x = x;
    this.y = y;
  }
  
  
  function getPoisition (time) {
    if (0 <= time && time <= 1) {
      return calc.call (this, time);
    }
  }
  
  function calc (t) {
    var I = this.x.length - 1;
    var T = 1 - t;
    var i = 0;
    var x = 0;
    var y = 0;
    var a, b;
    var c = 1;
    
    for (;i <= I; i++) {
      /*
      b = (i == 0 || I == i) ? 1: I;
      a = I - i;
      x += b * this.x[i] * Math.pow (T, i) * Math.pow (t, a);
      y += b * this.y[i] * Math.pow (T, i) * Math.pow (t, a);
      */

      // Math.pow を使う時点で、速度のことは言えたものではないが…
      a = I - i;
      b = ((i == 0 || I == i) ? 1: I) * c * Math.pow (t, a);
      x += this.x[i] * b;
      y += this.y[i] * b;
      c *= T;
    }

    return { x: x, y: y };
  }
  
  
  function create (points) {
    var px = [];
    var py = [];
    var i = 0;
    var p;

    while (p = points[i++]) {
      px.push (p[0]);
      py.push (p[1]);
    }

    return new BezierCurve (px, py);
  }
  
  BezierCurve.create = create;
  BezierCurve.prototype.getPoisition = getPoisition;
  this.BezierCurve = BezierCurve;
})();

//__________________________
var canvas = Graffiti.create (document.querySelector ('#hoge'));

var points = [
  [ 40, 300],
  [ 60, 100],
  [400,  50],
  [450, 400]
];

canvas.line.apply (canvas, points);


var bs = BezierCurve.create (points);
var p;

for (var i = 0; i <= 1; i += 0.001) {
  p = bs.getPoisition (i);
  canvas.pset (p.x, p.y, [255, 0,0]);
}

</script>
<p>http://ruiueyama.tumblr.com/post/11197882224</p>