xxxxxxxxxx
74
// ばぐはっけん!
// これで落とす
function setup() {
createCanvas(640, 640);
}
function draw(){
background(255);
const px = [113,540,341,208];
const py = [271,210,522,154];
drawBezier(px, py, 0, 96, 192);
}
function drawBezier(px,py,r,g,b){
stroke(r,g,b);
noFill();
strokeWeight(2);
bezier(px[0],py[0],px[1],py[1],px[2],py[2],px[3],py[3]);
const data = getBezierBD(px, py);
stroke(64,90);
fill(r,g,b,40);
rect(data.x, data.y, data.w, data.h);
}
function getPos(t,a,b,c,d){
const m0 = pow(1-t,3);
const m1 = 3*t*pow(1-t,2);
const m2 = 3*t*t*(1-t);
const m3 = t*t*t;
return m0*a+m1*b+m2*c+m3*d;
}
// これで極値が出る
function getCritical(a,b,c,d){
const _D = pow(b-c,2)-(a-b)*(c-d);
if(_D<0){ return []; }
if(c-d==0 && b-c ==0){ return []; }
if(c-d==0){
const x0 = -(a-b)/(2*(b-c)); // ばぐ!!
if(x0>0){
return [x0/(x0+1)];
}else{
return [];
}
}
const _E = Math.sqrt(_D);
const x1 = (-b+c+_E)/(c-d);
const x2 = (-b+c-_E)/(c-d);
const result=[];
if(x1>0){result.push(x1/(x1+1));}
if(x2>0){result.push(x2/(x2+1));}
return result;
}
function getBezierBD(px, py){
const results = [0,1];
results.push(getCritical(px));
results.push(getCritical(py));
// mapが便利
const xData = results.map(t => getPos(t, px));
const yData = results.map(t => getPos(t, py));
// reduceの方が多いときとか安全らしいので
const minX = xData.reduce((a, b) => min(a, b), Infinity);
const maxX = xData.reduce((a, b) => max(a, b), -Infinity);
const minY = yData.reduce((a, b) => min(a, b), Infinity);
const maxY = yData.reduce((a, b) => max(a, b), -Infinity);
return {x:minX, y:minY, w:maxX-minX, h:maxY-minY};
}