ベジエ曲線は、好きなところで2つのベジエ曲線に分割できる。
曲線を t : 1-t に分割したければ、 制御点 1-2, 2-3, 3-4 を t : 1-t に分割し、 それを結んで出来た2本の直線を、再び t : 1-t に分割し、 残りの1本を t : 1-t に分割する。
分割した点は、新たな曲線の制御点になっている。
//曲線を切断する
static public Vec2D[][] BezierCut(Vec2D[] points, double t)
{
Vec2D[][] result = new Vec2D[2][];
result[0] = new Vec2D[points.Length];
result[1] = new Vec2D[points.Length];
//0か1で切断しようとしている場合
if (t == 0 || t == 1) {
result[(int)t][0] = result[(int)t][1] =
result[(int)t][2] = result[(int)t][3] =
points[(int)t * (points.Length - 1)];
result[((int)t + 1) % 2] = points;
return result;
}
//stでくぎられる点を見つける
//分割前の P0, Pn が分割後の L0, Rn になる
result[0][0] = points[0];
result[1][points.Length - 1] = points[points.Length - 1];
Vec2D[] prev = points;
for (int i = 1; i < points.Length; i++) {
Vec2D[] tmp = new Vec2D[points.Length - i];
for (int j = 0; j < points.Length - i; j++) {
//tmp[j] - tmp[j+1] の間を st で区切る
tmp[j].x = prev[j].x + (prev[j + 1].x - prev[j].x) * t;
tmp[j].y = prev[j].y + (prev[j + 1].y - prev[j].y) * t;
}
result[0][i].x = tmp[0].x;
result[0][i].y = tmp[0].y;
result[1][points.Length - i - 1].x = tmp[tmp.Length - 1].x;
result[1][points.Length - i - 1].y = tmp[tmp.Length - 1].y;
prev = tmp; //算出したものを保持
}
return result;
}

