ポリラインをメッシュで区切る

メッシュ内を削除する

プリミティブの三角形の内外判定をして、内包されている場合はフラグを立てる。

//
// 点がプリミティブ内に内包されているか判定する
// RunOver: Points
// input1: primitive
//

//
// 外積のY成分だけ返す関数
//
float crossY(vector v0; vector v1;)
{
    return(v0.z * v1.x - v1.z * v0.x);
}

//
// 範囲のポリゴン内に入っているかチェック
//
int flag = 0;

for(int i = 0; i < nprimitives(1); i++)
{
    // 三角形のポイント
    int index[] = primpoints(1, i);
    
    vector p0 = point(1, "P", index[0]);
    vector p1 = point(1, "P", index[1]);
    vector p2 = point(1, "P", index[2]);
    
    float y0 = crossY(p1 - p0, @P - p0);
    float y1 = crossY(p2 - p1, @P - p1);
    float y2 = crossY(p0 - p2, @P - p2);
    
    // 符号が一致(内側にある)
    if((y0 >= 0 && y1 >= 0 && y2 >= 0) || (y0 <= 0 && y1 <= 0 && y2 <= 0))
    {
        i@__flag = 1;
        break;
    }
}

続けて、Primitve Wrangleをつなげ、フラグの立っているポイント以外をポリラインでつなげていく。

//
// フラグを見ながらポリラインを生成する
// RunOver: Primitives
//
int pts[] = primpoints(0, @primnum);

int prim = 0;

int prev_flag = 0;
for(int i = 0; i < len(pts); i++)
{
    int flag = point(0, "__flag", pts[i]);
 
    // 始点が内包されていない場合
    if(i == 0)
    {
        if(flag == 0)
            prim = addprim(0, "polyline");
        else
            prev_flag = 1;
    }
    
    // フラグが変わったら新しくポリラインを生成する
    if(flag == 0 && flag != prev_flag)
    {
        prim = addprim(0, "polyline");
        addvertex(0, prim, pts[i]);
    }
    // ポイントをポリラインに追加する
    else if(flag == 0)
    {
        addvertex(0, prim, pts[i]);
    }
    
    prev_flag = flag;
}

removeprim(0, @primnum, 1);

メッシュで分割する

矩形範囲内を削除するのではなく、新たに別のポリラインを生成する場合。

矩形への進入、退出の切り替わりのたびにフラグを立て、新しいポリラインを生成する。

//
// フラグを見ながらポリラインを生成する
// RunOver: Primitives
//
int pts[] = primpoints(0, @primnum);

int prim = addprim(0, "polyline");
addvertex(0, prim, pts[0]); // 始点を加える

int flag = point(0, "__flag", pts[0]);
if(flag == 1) setprimgroup(0, "__inside", prim, 1);
else setprimgroup(0, "__outside", prim, 1);

for(int i = 1; i < len(pts)-1; i++)
{
    // 内包されていたら1
    flag = point(0, "__flag", pts[i]);
    int prev = point(0, "__flag", pts[i-1]);
    int next = point(0, "__flag", pts[i+1]);
 
    // フラグが変わったら新しくポリラインを生成する
    if(flag == 1)
    {
        if(next == 1 && prev == 0)
        {
            addvertex(0, prim, pts[i]);
            prim = addprim(0, "polyline");
            setprimgroup(0, "__inside", prim, 1);
        }
        else if(next == 0 && prev == 1 || (next == 0 && prev == 0))
        {
            addvertex(0, prim, pts[i]);
            prim = addprim(0, "polyline");
            setprimgroup(0, "__outside", prim, 1);
        }
    }

    addvertex(0, prim, pts[i]);
}

addvertex(0, prim, pts[-1]); // 終点を加える

removeprim(0, @primnum, 1);

__insideと__outsideのグループをつけることで、後段でどちらかを削除することもできる。

タイトルとURLをコピーしました