連続性のあるベジェ曲線の描画
連続したベジェ曲線

ベジェ曲線は始点と終点を必ず通り、他の制御点は通らない特徴がある。ポリラインの辺の中点で分割したガイドカーブを使い、その中点を各区間の始点・終点にする。つなぎ目の点は前後の制御点の中点なので、3点が一直線上に並び、両側の接線の向きが揃う。 これで各区間が滑らかにつながった連続したカーブを描くことができる。
2次(Quadratic)のベジェ曲線
3点のガイドカーブを利用して、2次のベジェ曲線を描いていく。ガイドカーブの生成は以下のページに書きました。
ポリラインをベジェ制御点に分割する

//
// 2次(Quadratic)のベジェ曲線
//
// input1にガイドカーブをつなげる
// RunOver:Detail
//
int num = 100;
int prim = addprim(0, "polyline");
for(int i = 0; i < nprimitives(1); i++)
{
int pts[] = primpoints(1, i);
vector p0 = point(1, "P", pts[0]);
vector p1 = point(1, "P", pts[1]);
vector p2 = point(1, "P", pts[2]);
//
// ベジェ曲線を描く
//
for(int n = 0; n < num; n++)
{
// 区間の終点は次の区間の始点と重なるので、最後の区間以外は飛ばす
if(n == num - 1 && i < nprimitives(1)-1)
continue;
float t = n / float(num-1);
vector pos = (1-t)*(1-t)*p0 + 2*(1-t)*t*p1 + t*t*p2;
int pt = addpoint(0, pos);
addvertex(0, prim, pt);
}
}
3次(Cubic)のベジェ曲線
4点のガイドカーブを利用して3次のベジェ曲線を描いていく。最後が3点なら2次のベジェ曲線を描いて終わらせる。3点でも4点でもないプリミティブは飛ばす。


//
// 3次(Cubic)のベジェ曲線
//
// input1にガイドカーブをつなげる
// RunOver:Detail
//
int num = 100;
int prim = addprim(0, "polyline");
for(int i = 0; i < nprimitives(1); i++)
{
int pts[] = primpoints(1, i);
if(len(pts) == 3)
{
vector p0 = point(1, "P", pts[0]);
vector p1 = point(1, "P", pts[1]);
vector p2 = point(1, "P", pts[2]);
// 2次ベジェ曲線を描く
for(int n = 0; n < num; n++)
{
// 区間の終点は次の区間の始点と重なるので、最後の区間以外は飛ばす
if(n == num - 1 && i < nprimitives(1)-1)
continue;
float t = n / float(num-1);
vector pos = (1-t)*(1-t)*p0 + 2*(1-t)*t*p1 + t*t*p2;
int pt = addpoint(0, pos);
addvertex(0, prim, pt);
}
}
else if(len(pts) == 4)
{
// ベジェ曲線のための4点を選ぶ
vector p0 = point(1, "P", pts[0]);
vector p1 = point(1, "P", pts[1]);
vector p2 = point(1, "P", pts[2]);
vector p3 = point(1, "P", pts[3]);
// 3次ベジェ曲線を描く
for(int n = 0; n < num; n++)
{
// 区間の終点は次の区間の始点と重なるので、最後の区間以外は飛ばす
if(n == num - 1 && i < nprimitives(1)-1)
continue;
float t = n / float(num-1);
vector pos = (1-t)*(1-t)*(1-t)*p0 + 3*(1-t)*(1-t)*t*p1 + 3*(1-t)*t*t*p2 + t*t*t*p3;
int pt = addpoint(0, pos);
addvertex(0, prim, pt);
}
}
}