まずは、ベジェ曲線について学ぶ。
ベジェ曲線を、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>