チュートリアル | (トピック一覧へ戻る) |
import processing.opengl.*; import igeo.*; size(480, 360, IG.GL); IG.open("surface11.3dm"); ISurface[] surfaces = IG.surfaces(); for (ISurface surf : surfaces) { int unum = 30, vnum = 30; double uinc = 1.0/unum, vinc = 1.0/vnum; double gap = 0.25; for(int i=0; i < unum; i++){ for(int j=0; j < vnum; j++){ IVec pt1 = surf.pt( i*uinc, j*vinc ); IVec pt2 = surf.pt( (i+1-gap)*uinc, j*vinc ); IVec pt3 = surf.pt( (i+1-gap)*uinc, (j+1-gap)*vinc ); IVec pt4 = surf.pt( i*uinc, (j+1-gap)*vinc ); new ISurface(pt1,pt2,pt3,pt4); } } surf.del(); }
次のコードではランダムに選択された四角形を三角形に分割します。 それから四角形または三角形の線を描き、その線を内部にオフセットし、 それからZ軸方向に押し出して多角形状のパイプを生成します。
import processing.opengl.*; import igeo.*; size(480, 360, IG.GL); IG.open("surface11.3dm"); ISurface[] surfaces = IG.surfaces(); for (ISurface surf : surfaces) { int unum = 30, vnum = 30; double uinc = 1.0/unum, vinc = 1.0/vnum; double offsetDist = -0.04; int degree = 1; // 1 or 2 for(int i=0; i < unum; i++){ for(int j=0; j < vnum; j++){ IVec pt1 = surf.pt( i*uinc, j*vinc ); IVec pt2 = surf.pt( (i+1)*uinc, j*vinc ); IVec pt3 = surf.pt( (i+1)*uinc, (j+1)*vinc ); IVec pt4 = surf.pt( i*uinc, (j+1)*vinc ); if(IRandom.percent(30)){ // rectangle ICurve crv = new ICurve(new IVec[]{ pt1, pt2, pt3, pt4 }, degree, true); ICurve offCrv = IG.offset(crv, offsetDist); IG.extrude(offCrv, -4).clr(0.2); } else if(IRandom.percent(30)){ // triangles ICurve crv = new ICurve(new IVec[]{ pt1, pt2, pt3 }, degree, true); ICurve offCrv = IG.offset(crv, offsetDist); IG.extrude(offCrv, -2).clr(0.2); ICurve crv2 = new ICurve(new IVec[]{ pt1, pt3, pt4 }, degree, true); ICurve offCrv2 = IG.offset(crv2, offsetDist); IG.extrude(offCrv2, -2).clr(0.2); } else{ // triangles in other direction ICurve crv = new ICurve(new IVec[]{ pt1, pt2, pt4 }, degree, true); ICurve offCrv = IG.offset(crv, offsetDist); IG.extrude(offCrv, -1).clr(0.2); ICurve crv2 = new ICurve(new IVec[]{ pt2, pt3, pt4 }, degree, true); ICurve offCrv2 = IG.offset(crv2, offsetDist); IG.extrude(offCrv2, -1).clr(0.2); } } } surf.del(); }
変数degreeは、四角形と三角形の線のNURBS次数を決めていますが、 これを1から2に変更すると、生成される形状も多角形状から、曲面状に代わります。
import processing.opengl.*; import igeo.*; size(480, 360, IG.GL); IG.open("surface11.3dm"); ISurface[] surfaces = IG.surfaces(); for (ISurface surf : surfaces) { int unum = 30, vnum = 30; double uinc = 1.0/unum, vinc = 1.0/vnum; double offsetDist = -0.04; int degree = 2; // 1 or 2 for(int i=0; i < unum; i++){ for(int j=0; j < vnum; j++){ IVec pt1 = surf.pt( i*uinc, j*vinc ); IVec pt2 = surf.pt( (i+1)*uinc, j*vinc ); IVec pt3 = surf.pt( (i+1)*uinc, (j+1)*vinc ); IVec pt4 = surf.pt( i*uinc, (j+1)*vinc ); if(IRandom.percent(30)){ // rectangle ICurve crv = new ICurve(new IVec[]{ pt1, pt2, pt3, pt4 }, degree, true); ICurve offCrv = IG.offset(crv, offsetDist); IG.extrude(offCrv, -4).clr(0.2); } else if(IRandom.percent(30)){ // triangles ICurve crv = new ICurve(new IVec[]{ pt1, pt2, pt3 }, degree, true); ICurve offCrv = IG.offset(crv, offsetDist); IG.extrude(offCrv, -2).clr(0.2); ICurve crv2 = new ICurve(new IVec[]{ pt1, pt3, pt4 }, degree, true); ICurve offCrv2 = IG.offset(crv2, offsetDist); IG.extrude(offCrv2, -2).clr(0.2); } else{ // triangles in other direction ICurve crv = new ICurve(new IVec[]{ pt1, pt2, pt4 }, degree, true); ICurve offCrv = IG.offset(crv, offsetDist); IG.extrude(offCrv, -1).clr(0.2); ICurve crv2 = new ICurve(new IVec[]{ pt2, pt3, pt4 }, degree, true); ICurve offCrv2 = IG.offset(crv2, offsetDist); IG.extrude(offCrv2, -1).clr(0.2); } } } surf.del(); }
次のコードは画像の入力を一つ取ります。
この画像のグレー値が半分以下(0.5)の場合にのみ、
幾何学オブジェクトを生成するので、
結果として画像の明るい部分は空いた空間となります。
例では右の画像を"voidmap.jpg"として用いています。
import processing.opengl.*; import igeo.*; size(480, 360, IG.GL); IG.open("surface11.3dm"); ISurface[] surfaces = IG.surfaces(); IImageMap map1 = new IImageMap("voidmap.jpg"); for (ISurface surf : surfaces) { int unum = 30, vnum = 30; double uinc = 1.0/unum, vinc = 1.0/vnum; double offsetDist = -0.04; int degree = 1; // 1 or 2 for(int i=0; i < unum; i++){ for(int j=0; j < vnum; j++){ IVec pt1 = surf.pt( i*uinc, j*vinc ); IVec pt2 = surf.pt( (i+1)*uinc, j*vinc ); IVec pt3 = surf.pt( (i+1)*uinc, (j+1)*vinc ); IVec pt4 = surf.pt( i*uinc, (j+1)*vinc ); if(map1.get( (i+0.5)*uinc, (j+0.5)*vinc ) < 0.5 ){ if(IRandom.percent(30)){ ICurve crv = new ICurve(new IVec[]{ pt1, pt2, pt3, pt4 }, degree, true); ICurve offCrv = IG.offset(crv, offsetDist); IG.extrude(offCrv, -3).clr(0.2); } else if(IRandom.percent(30)){ ICurve crv = new ICurve(new IVec[]{ pt1, pt2, pt3 }, degree, true); ICurve offCrv = IG.offset(crv, offsetDist); IG.extrude(offCrv, -2).clr(0.2); ICurve crv2 = new ICurve(new IVec[]{ pt1, pt3, pt4 }, degree, true); ICurve offCrv2 = IG.offset(crv2, offsetDist); IG.extrude(offCrv2, -2).clr(0.2); } else{ ICurve crv = new ICurve(new IVec[]{ pt1, pt2, pt4 }, degree, true); ICurve offCrv = IG.offset(crv, offsetDist); IG.extrude(offCrv, -1).clr(0.2); ICurve crv2 = new ICurve(new IVec[]{ pt2, pt3, pt4 }, degree, true); ICurve offCrv2 = IG.offset(crv2, offsetDist); IG.extrude(offCrv2, -1).clr(0.2); } } } } surf.del(); }
次の例では5つの異なる画像を用意し、それをそれぞれ
空き、高さ、高さのランダム化、三角か四角の選択、色の制御に用います。
用いる画像は左から"voidmap.jpg"、 "heightmap.jpg"、
"heightRandomizeMap.jpg"、 "divisionmap.jpg"、
"colormap.jpg"です。
高さの画像の暗いところは低いチューブが生成され、明るいところに高いものが生成されます。
高さのランダム化の部分では、画像が暗いと一定の高さですが、そうでないところはランダムに高さが変わります。
三角か四角の選択では、画像が暗いと四角、そうでないと三角となり、三角分割の2種類の方向はランダムに決定されます。
import processing.opengl.*; import igeo.*; size(480, 360, IG.GL); IG.open("surface11.3dm"); ISurface[] surfaces = IG.surfaces(); IImageMap map1 = new IImageMap("voidmap.jpg"); IImageMap map2 = new IImageMap("heightmap.jpg"); IImageMap map3 = new IImageMap("heightRandomizeMap.jpg"); IImageMap map4 = new IImageMap("divisionmap.jpg"); IImageMap map5 = new IImageMap("colormap.jpg"); for (ISurface surf : surfaces) { int unum = 30, vnum = 30; double uinc = 1.0/unum, vinc = 1.0/vnum; double offsetDist = -0.04; int degree = 1; // 1 or 2 double maxHeight = 2; double heightRandomizeRange = 2.5; for(int i=0; i < unum; i++){ for(int j=0; j < vnum; j++){ IVec pt1 = surf.pt( i*uinc, j*vinc ); IVec pt2 = surf.pt( (i+1)*uinc, j*vinc ); IVec pt3 = surf.pt( (i+1)*uinc, (j+1)*vinc ); IVec pt4 = surf.pt( i*uinc, (j+1)*vinc ); double division = map4.get((i+0.5)*uinc,(j+0.5)*vinc)*maxHeight; double height = map2.get((i+0.5)*uinc,(j+0.5)*vinc)*maxHeight; height += map3.get((i+0.5)*uinc,(j+0.5)*vinc) * IRandom.get(0,heightRandomizeRange); if(map1.get( (i+0.5)*uinc, (j+0.5)*vinc ) < 0.5 ){ if(division < 0.5){ ICurve crv = new ICurve(new IVec[]{ pt1, pt2, pt3, pt4 }, degree, true); ICurve offCrv = IG.offset(crv, offsetDist); IG.extrude(offCrv, -height).clr(map5.clr((i+0.5)*uinc, (j+0.5)*vinc)); } else if(IRandom.percent(50)){ ICurve crv = new ICurve(new IVec[]{ pt1, pt2, pt3 }, degree, true); ICurve offCrv = IG.offset(crv, offsetDist); IG.extrude(offCrv, -height).clr(map5.clr((i+0.5)*uinc, (j+0.5)*vinc)); ICurve crv2 = new ICurve(new IVec[]{ pt1, pt3, pt4 }, degree, true); ICurve offCrv2 = IG.offset(crv2, offsetDist); IG.extrude(offCrv2, -height).clr(map5.clr((i+0.5)*uinc, (j+0.5)*vinc)); } else{ ICurve crv = new ICurve(new IVec[]{ pt1, pt2, pt4 }, degree, true); ICurve offCrv = IG.offset(crv, offsetDist); IG.extrude(offCrv, -height).clr(map5.clr((i+0.5)*uinc, (j+0.5)*vinc)); ICurve crv2 = new ICurve(new IVec[]{ pt2, pt3, pt4 }, degree, true); ICurve offCrv2 = IG.offset(crv2, offsetDist); IG.extrude(offCrv2, -height).clr(map5.clr((i+0.5)*uinc, (j+0.5)*vinc)); } } } } surf.del(); }
以下はNURBS次数を2にした、曲面の場合です。
import processing.opengl.*; import igeo.*; size(480, 360, IG.GL); IG.open("surface11.3dm"); ISurface[] surfaces = IG.surfaces(); IImageMap map1 = new IImageMap("voidmap.jpg"); IImageMap map2 = new IImageMap("heightmap.jpg"); IImageMap map3 = new IImageMap("heightRandomizeMap.jpg"); IImageMap map4 = new IImageMap("divisionmap.jpg"); IImageMap map5 = new IImageMap("colormap.jpg"); for (ISurface surf : surfaces) { int unum = 30, vnum = 30; double uinc = 1.0/unum, vinc = 1.0/vnum; double offsetDist = -0.04; int degree = 2; // 1 or 2 double maxHeight = 2; double heightRandomizeRange = 2.5; for(int i=0; i < unum; i++){ for(int j=0; j < vnum; j++){ IVec pt1 = surf.pt( i*uinc, j*vinc ); IVec pt2 = surf.pt( (i+1)*uinc, j*vinc ); IVec pt3 = surf.pt( (i+1)*uinc, (j+1)*vinc ); IVec pt4 = surf.pt( i*uinc, (j+1)*vinc ); double division = map4.get((i+0.5)*uinc,(j+0.5)*vinc)*maxHeight; double height = map2.get((i+0.5)*uinc,(j+0.5)*vinc)*maxHeight; height += map3.get((i+0.5)*uinc,(j+0.5)*vinc) * IRandom.get(0,heightRandomizeRange); if(map1.get( (i+0.5)*uinc, (j+0.5)*vinc ) < 0.5 ){ if(division < 0.5){ ICurve crv = new ICurve(new IVec[]{ pt1, pt2, pt3, pt4 }, degree, true); ICurve offCrv = IG.offset(crv, offsetDist); IG.extrude(offCrv, -height).clr(map5.clr((i+0.5)*uinc, (j+0.5)*vinc)); } else if(IRandom.percent(50)){ ICurve crv = new ICurve(new IVec[]{ pt1, pt2, pt3 }, degree, true); ICurve offCrv = IG.offset(crv, offsetDist); IG.extrude(offCrv, -height).clr(map5.clr((i+0.5)*uinc, (j+0.5)*vinc)); ICurve crv2 = new ICurve(new IVec[]{ pt1, pt3, pt4 }, degree, true); ICurve offCrv2 = IG.offset(crv2, offsetDist); IG.extrude(offCrv2, -height).clr(map5.clr((i+0.5)*uinc, (j+0.5)*vinc)); } else{ ICurve crv = new ICurve(new IVec[]{ pt1, pt2, pt4 }, degree, true); ICurve offCrv = IG.offset(crv, offsetDist); IG.extrude(offCrv, -height).clr(map5.clr((i+0.5)*uinc, (j+0.5)*vinc)); ICurve crv2 = new ICurve(new IVec[]{ pt2, pt3, pt4 }, degree, true); ICurve offCrv2 = IG.offset(crv2, offsetDist); IG.extrude(offCrv2, -height).clr(map5.clr((i+0.5)*uinc, (j+0.5)*vinc)); } } } } surf.del(); }