return f;\r
} else if (this.mode === "spline") {\r
this.to.call();\r
- var x = 0,\r
- y = 0,\r
- that = this,\r
- bezier = function (x1, y1, x2, y2, x3, y3, x4, y4) {\r
- return function (x) {\r
- /*三次方程式の解から、ベジェ曲線のyを求める*/\r
- var t = Math.qubicnewton([x4-3*(x3-x2)-x1, 3*(x3-2*x2+x1), 3*(x2-x1), x1-x], x);\r
- y = (y4-3*(y3-y2)-y1)*t*t*t + 3*(y3-2*y2+y1)*t*t + 3*(y2-y1)*t + y1;\r
- return f(y);\r
- };\r
- },\r
- tk = this.keySplines;\r
- return bezier(0, 0, tk[0], tk[1], tk[2], tk[3], 1, 1);\r
+ var tk = this.keySplines,\r
+ x2 = tk[0],\r
+ y2 = tk[1],\r
+ x3 = tk[2],\r
+ y3 = tk[3],\r
+ x4 = 1,\r
+ y4 = 1,\r
+ Ax = x4-3*(x3-x2),\r
+ Bx = 3*(x3-2*x2),\r
+ Cx = 3*x2,\r
+ Ay = (y4-3*(y3-y2)),\r
+ By = 3*(y3-2*y2),\r
+ Cy = 3*y2,\r
+ _newton = Math.qubicnewton; //高速化のためのエイリアス\r
+ tk = x2 = y2 = x3 = y3 = x4 = y4 = void 0;\r
+ return function (x) {\r
+ /*3次ベジェ曲線は媒介曲線\r
+ *x = (x4-3*(x3-x2)-x1)*t*t*t + 3*(x3-2*x2+x1)*t*t + 3*(x2-x1)*t + x1\r
+ *y = (y4-3*(y3-y2)-y1)*t*t*t + 3*(y3-2*y2+y1)*t*t + 3*(y2-y1)*t + y1\r
+ * ただし、0 <= t <= 1\r
+ * スプラインモードの場合、x1 = y1 = 0, x4 = y4 = 1\r
+ * ベジェ曲線のxの式が三次方程式であるため、その解 t から、ベジェ曲線の y を求める\r
+ * なお、ニュートン法の初期値はxとする\r
+ * なぜなら、xの式をみると、xが増加傾向となるスプラインモードでは、係数が負となる可能性が低いため*/\r
+ var t = _newton(Ax, Bx, Cx, -x, x);\r
+ return f(Ay*t*t*t + By*t*t + Cy*t);\r
+ };\r
} else if (this.mode === "discrete") {\r
return function (t) {\r
return isNaN(t) ? this.string\r
}\r
} ).to = base("$from").$to;\r
\r
-/*ニュートン法により、三次方程式 a[0]x^3 + a[1]x^2 + a[2]x + a[3] の解を求める\r
+/*ニュートン法により、三次方程式 a0x^3 + a1x^2 + a2x + a3 の解を求める\r
* 引数bは初期値*/\r
-Math.qubicnewton = function(a, b) {\r
- var eps = 1e-10, //収束誤差\r
- fb = f(b);\r
+Math.qubicnewton = function(a0, a1, a2, a3, b) {\r
+ var eps = 1e-10, //収束誤差\r
+ fb = a0 *b*b*b + a1 *b*b + a2*b + a3, //方程式の結果\r
+ _abs = Math.abs; //高速化のための関数のエイリアス\r
if (fb === 0) {\r
return b;\r
}\r
/*限界の収束回数は100回とする*/\r
for (var i=0;i<100;++i) {\r
- if (Math.abs(fb) < eps) {\r
+ if (_abs(fb) < eps) {\r
return b;\r
} else {\r
- b = b - fb / (3* a[0] *b*b + 2 * a[1] *b + a[2]);\r
- fb = f(b);\r
+ b = b - fb / (3* a0 *b*b + 2 * a1 *b + a2);\r
+ fb = a0 *b*b*b + a1 *b*b + a2*b + a3;\r
}\r
}\r
return b; //収束しなかった結果\r
- /*与えられた三次方程式*/\r
- function f(x) {\r
- return a[0] *x*x*x + a[1] *x*x + a[2]*x + a[3];\r
- };\r
};\r
\r
/*立方根(3乗根)を求める。Math.powだと負の値に対応していないため\r