ベジェ曲線の描画

連続したベジェ曲線

ベジェ曲線は始点と終点を必ず通り、他の制御点は通らない特徴がある。ガイドカーブを分割して中間点を始点と終点にすれば、各々のカーブが同じベクトルでつながるので連続したカーブを描くことができる。

2次(Quandric)のベジェ曲線

3点のガイドカーブを利用して、2次のベジェ曲線を描いていく。
ガイドカーブの生成は以下のページに書きました。
ベジェ曲線のガイドカーブをつくる

//
// 2次(Quandric)のベジェ曲線
//
// 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)
        {}
        else
        {
            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);
        }
    }
    
    //float hue = (i / (float)(nprimitives(1) * 1)) * -1 + 0.6;
    //setprimattrib(0, "Cd", prim, hsvtorgb(hue, 1, 1));
}

3次(Cubic)のベジェ曲線

4点のガイドカーブを利用して3次のベジェ曲線を描いていく。最後が3点なら2次のベジェ曲線を描いて終わらせる。

//
// 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)
            {}
            else
            {
                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)
    {
        // ベジェ曲線のための3点を選ぶ
        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)
            {}
            else
            {
                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);
            }
        }
    }
    
    //float hue = (i / (float)(nprimitives(1) * 1)) * -1 + 0.6;
    //setprimattrib(0, "Cd", prim, hsvtorgb(hue, 1, 1));
}
タイトルとURLをコピーしました