0017-09-02

[]CEDEC2017で紹介されていたビルを作るHDA CEDEC2017で紹介されていたビルを作るHDA - Nao_uの日記 を含むブックマーク はてなブックマーク - CEDEC2017で紹介されていたビルを作るHDA - Nao_uの日記 CEDEC2017で紹介されていたビルを作るHDA - Nao_uの日記 のブックマークコメント

f:id:Nao_u:20170903145449p:image

回転対応などの汎用性を無視して、それっぽいものを実装してみる

特殊 等分割のほうは、「エッジなし」「エッジ半分」「エッジ両方」は未実装だけど、やっぱり必須だなぁ…。

3分割

string groupName = ch("groupName");
float sizeA = ch("Size_a");
float sizeB = ch("Size_b");
string groupNameA = ch("groupNameA");
string groupNameB = ch("groupNameB");
string groupNameC = ch("groupNameC");
float turn90 = ch("turn90");

if( groupName == "" || inprimgroup(@Opinput1,groupName,@primnum) == 1 )
{
    removeprim(geoself(), @primnum, 0);
    
    int points[] = primpoints(0, @primnum);
    
    int ip0, ip1, ip2, ip3;
    if( turn90 != 0 ){
        ip0 = points[1];
        ip1 = points[2];
        ip3 = points[3];
        ip2 = points[0];
    }else{
        ip0 = points[0];
        ip1 = points[1];
        ip3 = points[2];
        ip2 = points[3];
    }
    
    vector p0 = point(0, "P", ip0);
    vector p1 = point(0, "P", ip1);
    vector p2 = point(0, "P", ip2);
    vector p3 = point(0, "P", ip3);
    
    vector ap0 = p0 + normalize(p2-p0)*sizeA;
    vector ap1 = p1 + normalize(p3-p1)*sizeA;
    vector ap2 = p2 + normalize(p0-p2)*sizeB;
    vector ap3 = p3 + normalize(p1-p3)*sizeB;
    
    int iap0 = addpoint(geoself(), ap0);
    int iap1 = addpoint(geoself(), ap1);
    int iap2 = addpoint(geoself(), ap2);
    int iap3 = addpoint(geoself(), ap3);
    
    int prim;
    
    // Aプリミティブを生成
    prim = addprim(geoself(), "poly");
    addvertex(geoself(), prim, ip0);
    addvertex(geoself(), prim, ip1);
    addvertex(geoself(), prim, iap1);
    addvertex(geoself(), prim, iap0);
    if( groupName != "" ) setprimgroup(geoself(), groupName, prim, 1, "set");
    setprimgroup(geoself(), groupName+"_"+groupNameA, prim, 1, "set");
    
    // Bプリミティブを生成
    prim = addprim(geoself(), "poly");
    addvertex(geoself(), prim, iap2);
    addvertex(geoself(), prim, iap3);
    addvertex(geoself(), prim, ip3);
    addvertex(geoself(), prim, ip2);
    if( groupName != "" ) setprimgroup(geoself(), groupName, prim, 1, "set");
    setprimgroup(geoself(), groupName+"_"+groupNameB, prim, 1, "set");
    
    // Cプリミティブを生成
    prim = addprim(geoself(), "poly");
    addvertex(geoself(), prim, iap0);
    addvertex(geoself(), prim, iap1);
    addvertex(geoself(), prim, iap3);
    addvertex(geoself(), prim, iap2);
    if( groupName != "" ) setprimgroup(geoself(), groupName, prim, 1, "set");
    setprimgroup(geoself(), groupName+"_"+groupNameC, prim, 1, "set");
}

特殊 等分割


string groupName = ch("groupName");
float sizeA = ch("sizeA");
float sizeB = ch("sizeB");
if( sizeB < 0.001 ) sizeB = 0.001;
string groupNameA = ch("groupNameA");
string groupNameB = ch("groupNameB");
float turn90 = ch("turn90");

if( groupName == "" || inprimgroup(@Opinput1, groupName, @primnum) == 1 )
{
    removeprim(geoself(), @primnum, 0);
    
    int points[] = primpoints(0, @primnum);
    int ip0, ip1, ip2, ip3;
    if( turn90 != 0 )
    {
        ip0 = points[0];
        ip1 = points[1];
        ip3 = points[2];
        ip2 = points[3];
    }else{
        ip0 = points[1];
        ip1 = points[2];
        ip3 = points[3];
        ip2 = points[0];
    }
    
//    printf("[%d] %d,%d,%d,%d",@primnum,ip0,ip1,ip2,ip3);
    
    vector p0 = point(0, "P", ip0);
    vector p1 = point(0, "P", ip1);
    vector p2 = point(0, "P", ip2);
    vector p3 = point(0, "P", ip3);
    
    // 進行方向のベクトルを求める
    vector dirVec = normalize(p1-p0);
    
    // 幅を求める
    float width = distance(p1,p0);
    // 繰り返し回数を求める
    int rep = 1+width / (sizeA+sizeB);
    // 繰り返し回数の上限を設定
    if( rep > 100 ) rep = 100;
    
    /*
    printf("w=%f\n",width);
    printf("a=%f\n",sizeA);
    printf("b=%f\n",sizeB);
    printf("rep=%d\n",rep);
    */
    // sizeBをちょうどいい幅に補正
    sizeB = (width - sizeA*rep) / rep;
    
    int prim;
    
    // 前の点のベクトル
    vector pp0 = p0;
    vector pp1 = p2;
    int ipp0 = addpoint(geoself(), pp0);
    int ipp1 = addpoint(geoself(), pp1);
    // 今追加したベクトル
    vector pn0, pn1;    
    int ipn0, ipn1;
    
    for( int i=0; i// Aを追加
        pn0 = pp0 + dirVec * sizeA;
        pn1 = pp1 + dirVec * sizeA;
        ipn0 = addpoint(geoself(), pn0);
        ipn1 = addpoint(geoself(), pn1);
    
        prim = addprim(geoself(), "poly");
        addvertex(geoself(), prim, ipp0);
        addvertex(geoself(), prim, ipp1);
        addvertex(geoself(), prim, ipn1);
        addvertex(geoself(), prim, ipn0);
        if( groupName != "" ) setprimgroup(geoself(), groupName, prim, 1, "set");
        setprimgroup(geoself(), groupName+"_"+groupNameA, prim, 1, "set" );
        pp0 = pn0; ipp0 = ipn0;
        pp1 = pn1; ipp1 = ipn1;
    
        // Bを追加
        pn0 = pp0 + dirVec * sizeB;
        pn1 = pp1 + dirVec * sizeB;
        ipn0 = addpoint(geoself(), pn0);
        ipn1 = addpoint(geoself(), pn1);
    
        prim = addprim(geoself(), "poly");
        addvertex(geoself(), prim, ipp0);
        addvertex(geoself(), prim, ipp1);
        addvertex(geoself(), prim, ipn1);
        addvertex(geoself(), prim, ipn0);
        if( groupName != "" ) setprimgroup(geoself(), groupName, prim, 1, "set");
        setprimgroup(geoself(), groupName+"_"+groupNameB, prim, 1, "set" );
        pp0 = pn0; ipp0 = ipn0;
        pp1 = pn1; ipp1 = ipn1;
    }
}