home processing download documents tutorial python tutorial gallery source about
 チュートリアル (トピック一覧へ戻る)

パネル化アルゴリズム例

     パネル化アルゴリズム例その10

この例では、複数の画像によって高さや色やランダム化など幾何学オブジェクトの様々な面を制御する例を示します。 以下の入力曲面は正方形ですが、内部の制御点を大きく撹拌してあるので、 サンプルされた点は変形された格子の上に並びます。 最初のコードではこの入力曲面上に間隔をあけて四角形パネルを生成します。

surface11.3dm

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();
}


(トピック一覧へ戻る)

HOME
FOR PROCESSING
DOWNLOAD
DOCUMENTS
TUTORIALS (Java / Python)
GALLERY
SOURCE CODE(GitHub)
PRIVACY POLICY
ABOUT/CONTACT