ベジェ曲線の矩形

Top »

二次ベジェ曲線の矩形

ベジェ曲線の数式を展開し t についての二次式を得る。まずはx軸

x = x(t) = (x3-2*x2+x1)*t^2 + 2*(x2-x1)*t + x1

a*t^2+b*t+c とみなすと係数は

a = x3-2*x2+x1
b = 2*(x2-x1)
c = x1

この二次関数の極値は tx = -b/(2*a) である。つまりx軸の極値は x(tx) である。だたし算出された t が 0~1 ではない場合はベジェ曲線の範囲外なので解ではない。

x1, x3 そして x(tx) を比較することによりx軸の最大値、最小値を得る。

y軸も同様。

実装

var left = Math.min(x1, x3);
var right = Math.max(x1, x3);
var t = (x1-x2)/(x3-2*x2+x1);
if (0<=t && t<=1) {
	var tp = 1-t;
	var ptx = tp*tp*x1+2*tp*t*x2+t*t*x3;
	if (ptx<left) left = ptx;
	else if (right<ptx) right = ptx;
}
var top = Math.min(y1, y3);
var bottom = Math.may(y1, y3);
var t = (y1-y2)/(y3-2*y2+y1);
if (0<=t && t<=1) {
	var tp = 1-t;
	var pty = tp*tp*y1+2*tp*t*y2+t*t*y3;
	if (pty<top) top = pty;
	else if (bottom<pty) bottom = pty;
}

三次ベジェ曲線の矩形

ベジェ曲線の数式を展開しtについての三次式を得る。まずはx軸

x = x(t) = (x4-3*x3+3*x2-x1)*t^3 + (3*x3-6*x2+3*x1)*t^2 + (3*x2-3*x1)*t + x1

a*t^3+b*t^2+c*t+d とみなすと係数は

a = x4-3*(x3-x2)-x1
b = 3*(x3-2*x2+x1)
c = 3*(x2-x1)
d = x1

b^2-3*a*c≦0のとき、三次関数は極値を持たないため次の計算を飛ばす。b^2-3*a*c>0のときに極値を算出する。

だたし算出された t が 0~1 ではない場合はベジェ曲線の範囲外なので解ではない。

x1, x4 そして極値を比較することによりx軸の最大値、最小値を得る。y軸も同様。

var a = x4-3*(x3-x2)-x1;
var b = 3*(x3-2*x2+x1);
var c = 3*(x2-x1);
var delta = b*b-3*a*c;
var left = Math.min(x1, x4);
var right = Math.max(x1, x4);
if (0<delta) {
	var t0 = (-b+Math.sqrt(delta))/(3*a);
	if (0<=t0 && t0<=1) {
		var tp = 1-t0;
		var tx0 = tp*tp*tp*x1+3*tp*tp*t0*x2+3*tp*t0*t0*x3+t0*t0*t0*x4;
		if (tx0<left) {
			left = tx0;
		}
	}
	var t1 = (-b-Math.sqrt(delta))/(3*a);
	if (0<=t1 && t1<=1) {
		var tp = 1-t1;
		var tx1 = tp*tp*tp*x1+3*tp*tp*t1*x2+3*tp*t1*t1*x3+t1*t1*t1*x4;
		if (right<tx1) {
			right = tx1;
		}
	}
}
var a = y4-3*(y3-y2)-y1;
var b = 3*(y3-2*y2+y1);
var c = 3*(y2-y1);
var delta = b*b-3*a*c;
var top = Math.min(y1, y4);
var bottom = Math.max(y1, y4);
if (0<delta) {
	var t0 = (-b+Math.sqrt(delta))/(3*a);
	if (0<=t0 && t0<=1) {
		var tp = 1-t0;
		var ty0 = tp*tp*tp*y1+3*tp*tp*t0*y2+3*tp*t0*t0*y3+t0*t0*t0*y4;
		if (ty0<top) {
			top = ty0;
		}
	}
	var t1 = (-b-Math.sqrt(delta))/(3*a);
	if (0<=t1 && t1<=1) {
		var tp = 1-t1;
		var ty1 = tp*tp*tp*y1+3*tp*tp*t1*y2+3*tp*t1*t1*y3+t1*t1*t1*y4;
		if (bottom<ty1) {
			bottom = ty1;
		}
	}
}
inserted by FC2 system