2次ベジェ曲線を高速に描く(加減算と乗算だけで)

<!DOCTYPE html>
<meta charset="utf-8">
<title>ベジェ曲線</title>
<style>
</style>

<body>
<h1>ベジエ曲線を整数の加減算だけで描画する方法</h1>
<h2>高速に2次ベジェ曲線を計算する</h2>
<p>JavaScriptでは整数型の演算ができるわけではないが以下を参考に作る
<p><a href="http://studio-rain.cocolog-nifty.com/blog/2008/07/post_c4f5.html">
http://studio-rain.cocolog-nifty.com/blog/2008/07/post_c4f5.html</a>
<p>世の中すごい人だらけ</p>

<canvas width="800" height="400"></canvas>
<script>


(function () {
  var OPTION_DEFAULT = {
    offset: {x: 0, y: 0},
    fillColor: 'rgb(0,0,0)',
    grid: {x: 30, y: 30}

  };

  function Controller (canvas, option) {
    this.canvas = canvas;
    this.ctx    = canvas.getContext ('2d');
    this.option = option;
  }

  function setGrid () {
    var ctx = this.ctx;
    var x = this.option.offset.x;
    var y = this.option.offset.y;
    var h = this.canvas.height;
    var w = this.canvas.width;

    ctx.beginPath();
    ctx.strokeStyle = 'rgb(200,200,200)';
    ctx.strokeRect (0, 0, w, h);

    ctx.fillStyle = 'rgb(150,150,150)';
    ctx.fillRect (x+1, y-1, w-2, 3);
    ctx.fillRect (x-1, 1, 3, h-2);
  }

  function pset (x, y, color, size) {
    var offset = this.option.offset;
    var ctx = this.ctx;
    ctx.fillStyle = color || this.option.fillColor || 'rgb(0,0,0)';
    ctx.fillRect (x + offset.x, offset.y - y, size, size);//大きさも考えろよ
  }


  function create (canvas, option) {
    var ctx = canvas.getContext ('2d');

    if ('undefined' === typeof option)
      option = { };

    for (p in OPTION_DEFAULT) //標準設定で上書き
      if (OPTION_DEFAULT.hasOwnProperty (p))
        if (! option.hasOwnProperty (p))
          option[p] = OPTION_DEFAULT[p];

    return new Controller (canvas, option);
  }

  Controller.prototype.setGrid = setGrid;
  Controller.prototype.pset = pset;

  Controller.create = create;

  this.CTX = Controller;
}) ();


//2次ベジェ曲線ジェネレータ
// var aryPoint = intbz ([x0,y0], [x1,y1], ..])
//
// ビット演算で計算しているため、点p0から点p2まで 2^7 で分割される

(function () {
  var nbit = 7; //128
  var n2bit = nbit + nbit;
  var N = 1 << nbit;
  var N2 = 1 << n2bit;
  var q0 = N + N -2;
  var q1 = 1 - 2 * N;

  function intP3bz (x0, y0, x1, y1, x2, y2) {
    var ax = x0 * N2, ay = y0 * N2,
        bx = x2 + q0 * x1 + q1 * x0, by = y2 + q0 * y1 + q1 * y0,
        cx = x2 + x2 - 4 * x1 + x0 + x0, cy = y2 + y2 - 4 * y1 + y0 + y0;

    for (var i = N; i--; ax += bx, ay += by, bx += cx, by += cy)
      this.push ([ax >> n2bit, ay >> n2bit]);
  }


  function intbz (p) {
    var a = p[0], b = p[1], c, i, r = [ ];

    for (i = 2; c = p[i++]; )
      intP3bz.call (r, a[0], a[1], b[0], b[1], c[0], c[1]),
      b = [c[0] + (c[0] - b[0]), c[1] + c[1] - b[1]], a = c, c = p[i];

    return r;
  }


  this.intbz = intbz;

}) ();



var c = CTX.create (document.querySelector ('canvas'), { offset: {x: 0, y: 200}});
c.setGrid ();

var p = intbz ([[0,0], [200,100], [400,0], [600,100], [800,0]]);
for(var i = 0; q = p[i]; i+=1) {
  c.pset (q[0], q[1], 'rgb(255,0,0)', 4);
}
</script>