演習2 立体の形状

いろいろな形状の立体を作ってみよう

文法上の詳しい説明は
VRMLの文法
◆VRMLの構造(PROTO,EXTERNPROTO)
◆Shape(Extrusion,IndexedFaceSet)
◆Transform(座標変換)
◆Viewpoint(視点と視線)
◆Viewpointの例
を参照してください。

ドーナツ型のはちまきを作ろう

 次のような立体を作ります。平面の円の形状を大きな円周が中心となるように押し出した形をしています。端の部分を細くしてリボン状にしています。

 押し出した形を作るには、Extrusionノードを使用します。Extrusionノードの形を設定するフィールドは、crossSectionフィールド、spineフィールド、scaleフィールドです。

crossSectionフィールド
押し出す基本の平面(多角形)の形を与えるフィールドです。
y=0 平面上の多角形の頂点のx,z座標の組を記述します。
ここではドーナツの太さの円の円周の座標です。
spineフィールド
平面の形を押し出す軌跡のラインをx,y,z座標で与えます。
ここではドーナツの大きさの円の円周の座標ですが、初めと終わりに結び目の部分の座標を加えています。
ここでは、z=0 平面上の円で与えるのでz座標は0にしてあります。
scaleフィールド
押し出す基本の平面の形のスケール(x方向,z方向の組)を spineフィールドの押し出す軌跡の座標に対応させて記述します。
ここではドーナツ部分は0.3,0.3、結び目の部分は細くして、 結んだ後は平たくしています。
 ドーナツ型はちまきを作成するVRMLファイルの例を次に示します。crossSectionフィールドとspineフィールドは省略してあります。


#VRML V2.0 utf8
#doughnut     filename=ex02_doughnut.wrl

 Shape {
   appearance Appearance {
     material Material {
                diffuseColor 0.3  0.8  0
   }}  
   geometry Extrusion {
     crossSection [
            1.0000  0.0000    0.9808  0.1951    0.9239  0.3827
            0.8315  0.5556    0.7071  0.7071    0.5556  0.8315
                                  省略
            0.5556 -0.8315    0.7071 -0.7071    0.8315 -0.5556
            0.9239 -0.3827    0.9808 -0.1951    1.0000  0.0000
      ]
      spine [1.4 -0.2 0 1.2 -0.1 0
            1.0000  0.0000 0    0.9808  0.1951 0    0.9239  0.3827 0
            0.8315  0.5556 0    0.7071  0.7071 0    0.5556  0.8315 0
                                  省略
            0.5556 -0.8315 0    0.7071 -0.7071 0    0.8315 -0.5556 0
            0.9239 -0.3827 0    0.9808 -0.1951 0    1.0000  0.0000 0
            1.4 0.2 0 1.2 0.1 0
      ]
      scale [
              0.1 0.01 0.1 0.01 
              0.1 0.1 0.2 0.2 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3
              0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3
              0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3
              0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3
              0.3 0.3 0.3 0.3 0.3 0.3 0.2 0.2 0.1 0.1 0.01 0.1 0.01 0.1 

      ]
      solid FALSE
 }}

doughnut (ファイルをダウンロードするには右クリックします)


サッカーボールを作ろう

 次のような立体を作ります。切頭20面体(正6角形が20枚と正5角形が12枚)で、正6角形の部分を白、正5角形の部分を黒にしています。

 多面体(平面)を作るには、IndexedFaceSetノードを使用します。IndexedFaceSetノードの形を設定するフィールドは、coord フィールドとcoordIndexフィールドです。色はcolor フィールドで設定します。

coordフィールド
Coordinateノードのpointフィールドで多面体の頂点の座標(x,y,z座標)を記述します。
記述した順に0から番号が付けられます(pointフィールドで使用する)。
ここでは、切頭20面体(サッカーボール)の頂点の座標を設定します。
coordIndexフィールド
面を構成する頂点の番号を面の表側から見て左回りに記述し、 最後に-1を付けます。
ここでは正6角形が20枚、正5角形が12枚あります。
colorPerVertexフィールド
TRUEのときはcolorフィールドで指定された色を頂点に付け、FALSE のときは面に付けます。ここでは面に色を付けるのでFALSEにします。
colorフィールド
Colorノードのcolorフィールドで面の色を面の数だけ指定します。 colorフィールドに記述した色の順番が coordIndexフィールドで指定した面の順番に対応します。 ここでは正6角形を白に、正5角形を黒にしています。
 サッカーボールを作成するVRMLファイルの例を次に示します。ここで設定している次の文
Background { skyColor 1 0.8 0.8 }
は、背景が黒だとサッカーボールが見えにくいため背景の色を変更しています。Backgroundノードについては背景を参照してください。
coord フィールドとcoordIndexフィールドは省略してあります。


#VRML V2.0 utf8
#soccerball  filename=ex02_soccer.wrl

Background { skyColor 1 0.8 0.8 }
  Shape {
     appearance Appearance {
       material Material{ 
           diffuseColor 1 1 1 }}
       geometry IndexedFaceSet {
         coord Coordinate {
           point [
               1.694   0.130   1.021,
               1.447   0.891   1.021,
                           省略
               0.400  -1.912   0.340,
               0.800  -1.782  -0.340,
         ]}
         coordIndex [
              0,  1,  2,  3,  4,  5, -1,
              6,  7,  8,  9,  3,  2, -1,
                           省略
             31, 30, 55, 54, 49, 48, -1,
             35, 34, 59, 58, 53, 52, -1,
              0,  5, 19, 57, 42, -1,
              2,  1, 41, 46,  6, -1,
                           省略
             34, 37, 39, 56, 59, -1,
             24, 23, 36, 32, 28, -1,
        ]
       color Color { color [1 1 1, 1 1 1, 1 1 1, 1 1 1, 1 1 1, 
                            1 1 1, 1 1 1, 1 1 1, 1 1 1, 1 1 1,  
                            1 1 1, 1 1 1, 1 1 1, 1 1 1, 1 1 1,  
                            1 1 1, 1 1 1, 1 1 1, 1 1 1, 1 1 1,  
                            0 0 0, 0 0 0, 0 0 0, 0 0 0, 0 0 0, 
                            0 0 0, 0 0 0, 0 0 0, 0 0 0, 0 0 0, 
                            0 0 0, 0 0 0 
        ] }
       colorPerVertex FALSE
 }}

soccerball (ファイルをダウンロードするには右クリックします)


演習1で作成したファイルと合わせよう

 演習1で作成したファイル(人形ex01_puppet2.wrl)と今回作成した2つのファイルをInlineノードで組み込みます。組み込んだVRMLファイルの例を次に示します(ex01_puppet2.wrlのURLは各自の作成したものに合わせて変更すること)。

 人形は、スケール(0.8 0.8 0.8)に縮小して座標の中心に置きます。はちまきはスケール(0.35 0.35 0.35)に縮小して円錐の帽子に巻き付けます。サッカーボールはスケール(0.2 0.2 0.2)に縮小して足元に置きます。


#VRML V2.0 utf8
#合わせた形(Inline)   filename=ex02_puppet_inline.wrl

Background { skyColor 1 0.8 0.8 }

#
Transform {
  scale 0.8 0.8 0.8 
  children [ Inline { url "../ex01wrl/ex01_puppet2.wrl"} ]
}

Transform {
  rotation 0 0 -1 0.375
  children [ 
    Transform {
      translation -0.27 1.5 0
      rotation -1 0 0  1.57
      scale 0.35 0.35 0.35 
      children [ Inline { url "ex02_doughnut.wrl"} ]  }
]}

Transform {
  translation -0.3 -1.5 0.4
  scale 0.2 0.2 0.2 
  children [ Inline { url "ex02_soccer.wrl"} ]
}











ユーザ定義のノードを作成してみよう(PROTO)

 はちまきとサッカーボールを新しいノードとして定義してみましょう。PROTOノードを使います。
 Inlineノードで定義されたままでは新しいノードに定義できませんので、はちまきのファイル(ex02_doughnut.wrl)とサッカーボールのファイル(ex02_soccer.wrl)の内容をコピーして次の例に示すように変更します。

はちまきは、次のように定義しています。

PROTO Doughnut
 [ exposedField SFColor doughnutColor 0.3 0.8 0 ]
{  Shape 省略
       diffuseColor IS doughnutColor
        省略
}
PROTOノードは、PROTOの次に新しく定義するノードの名前を記述します。ここではDoughnutとしました。{ }の中に定義するノードを記述します。ここでは、はちまきを定義しているShapeノードです。[ ]の中には、値を受け渡すフィールドを定義します。はちまきの色を定義しています。exposedField(フィールドの属性)、SFColor(フィールドの型)、doughnutColor(フィールド名)、初期値の順に記述します。フィールドの属性と型は受け渡すフィールドによります。名前はユニークなものを自由に付けられます。Shapeノードの中でその色を使用するdiffuseColorフィールドに定義したフィールド名をIS文で記述します。

サッカーボールは、次のように定義しています。

PROTO Soccerball
  [ exposedField MFColor soccerballColor
[1 1 1, 1 1 1, 1 1 1, 1 1 1, 1 1 1,
1 1 1, 1 1 1, 1 1 1, 1 1 1, 1 1 1,
1 1 1, 1 1 1, 1 1 1, 1 1 1, 1 1 1,
1 1 1, 1 1 1, 1 1 1, 1 1 1, 1 1 1,
0 0 0, 0 0 0, 0 0 0, 0 0 0, 0 0 0,
0 0 0, 0 0 0, 0 0 0, 0 0 0, 0 0 0,
0 0 0, 0 0 0 ]
  ]
{  Shape 省略
color Color { color IS soccerballColor }
    省略
}
ノードの名前はSoccerballとしました。[ ]の中に、サッカーボールの色を受け渡すように定義しています。フィールドの属性はexposedField、SFColorフィールドの型はMFColor(複数の値を持つ)、フィールド名はsoccerballColor、初期値は32面の色(白と黒)です。{ }の中に定義するノードは、サッカーボールを定義しているShapeノードです。Shapeノードの中でその色を使用するcolorフィールドに定義したフィールド名をIS文で記述します。

 定義したノードを使用するには、他のノードと同じように

Doughnut { }
と記述します。{ }の中が空のときはフィールド値は初期値(デフォルト値)になります。

 次にPROTOノードを使用したVRMLファイル全体を示します。


#VRML V2.0 utf8
#PROTO   filename=ex02_puppet_proto.wrl

Background { skyColor 1 0.8 0.8 }

#doughnut
PROTO Doughnut                      
     [ exposedField SFColor doughnutColor 0.3  0.8  0 ]
{ Shape {                
   appearance Appearance {
     material Material {
                diffuseColor IS doughnutColor
   }}  
   geometry Extrusion {
                           省略
  }}
}

#soccerball
PROTO Soccerball                      
     [ exposedField MFColor soccerballColor 
                           [1 1 1, 1 1 1, 1 1 1, 1 1 1, 1 1 1, 
                            1 1 1, 1 1 1, 1 1 1, 1 1 1, 1 1 1,  
                            1 1 1, 1 1 1, 1 1 1, 1 1 1, 1 1 1,  
                            1 1 1, 1 1 1, 1 1 1, 1 1 1, 1 1 1,  
                            0 0 0, 0 0 0, 0 0 0, 0 0 0, 0 0 0, 
                            0 0 0, 0 0 0, 0 0 0, 0 0 0, 0 0 0, 
                            0 0 0, 0 0 0 ]
     ]
{  Shape {
     appearance Appearance {
       material Material{ 
           diffuseColor 1 1 1 }}
       geometry IndexedFaceSet {
         coord Coordinate {  
                           省略
         }
         coordIndex [
                           省略
         ]
         color Color { color IS soccerballColor }
         colorPerVertex FALSE
 }}
}

#puppet
Transform {
  scale 0.8 0.8 0.8 
  children [ Inline { url "../ex01wrl/ex01_puppet2.wrl"} ]
}

Transform {
  rotation 0 0 -1 0.375
  children [ 
    Transform {
      translation -0.27 1.5 0
      rotation -1 0 0  1.57
      scale 0.35 0.35 0.35 
      children [ Doughnut { } ] }
]}

Transform {
  translation -0.3 -1.5 0.4
  scale 0.2 0.2 0.2 
  children [ Soccerball { } ]
}

 表示結果は前の例と同じです。



色を変えてみよう

 先ほどPROTOノードで定義したノードの色を変えてみましょう。その例を次に示します。PROTOノードで定義した部分は前の例と同じですので省略しました。DoughnutノードのdoughnutColorフィールドとSoccerballノードのsoccerballColorフィールドに色を設定しています。


#VRML V2.0 utf8
#PROTO   filename=ex02_puppet_proto2.wrl
#色を指定

Background { skyColor 1 0.8 0.8 }

#doughnut
       PROTO Doughnut    省略                      

#soccerball
       PROTO Soccerball  省略                      

#puppet
Transform {
  scale 0.8 0.8 0.8 
  children [ Inline { url "../ex01wrl/ex01_puppet2.wrl"} ]
}

Transform {
  rotation 0 0 -1 0.375
  children [ 
    Transform {
      translation -0.27 1.5 0
      rotation -1 0 0  1.57
      scale 0.35 0.35 0.35 
      children [ Doughnut { doughnutColor 1 0.2 0.6 } ] }
]}

Transform {
  translation -0.3 -1.5 0.4
  scale 0.2 0.2 0.2 
  children [ Soccerball { soccerballColor
                           [1 1 0, 1 1 0, 1 1 0, 1 1 0, 1 1 0,  
                            1 1 0, 1 1 0, 1 1 0, 1 1 0, 1 1 0,  
                            1 1 0, 1 1 0, 1 1 0, 1 1 0, 1 1 0,  
                            1 1 0, 1 1 0, 1 1 0, 1 1 0, 1 1 0,  
                            0 0 1, 0 0 1, 0 0 1, 0 0 1, 0 0 1, 
                            0 0 1, 0 0 1, 0 0 1, 0 0 1, 0 0 1, 
                            0 0 1, 0 0 1 ]
                          } 
]}











EXTERNPROTOを使ってみよう

 EXTERNPROTOノードを使用すると、PROTOノードが同じファイル内になくてもURLを指定して組み込むことができます。はちまきとサッカーボールをEXTERNPROTOノードで記述してみましょう。
 前の例で、はちまきを定義しているPROTOノードの部分をヘッダー #VRML V2.0 utf8 を付けてファイル名を ex02_doughnut_proto.wrl にして保存しておきます。同じようにサッカーボールを定義しているPROTOノードの部分をヘッダー #VRML V2.0 utf8 を付けてファイル名を ex02_doughnut_proto.wrl にして保存しておきます。
 次にPROTOノードの代わりにEXTERNPROTOノードを記述します。EXTERNPROTOノードは次の例に示すように初めの[ ]はPROTOノードに定義されている内容と全く同じにします。ただし、初期値は設定できません。次の[ ]内にはPROTOノードが記述されているファイルのURLを記述します。


#VRML V2.0 utf8
#EXTERNPROTO   filename=ex02_puppet_exproto.wrl
#色を指定

Background { skyColor 1 0.8 0.8 }

#doughnut
EXTERNPROTO Doughnut                      
     [ exposedField SFColor doughnutColor ]
     [ "ex02_doughnut_proto.wrl" ]


#soccerball
EXTERNPROTO Soccerball                      
     [ exposedField MFColor soccerballColor ]
     [ "ex02_soccer_proto.wrl" ]

#puppet
Transform {
  scale 0.8 0.8 0.8 
  children [ Inline { url "../ex01wrl/ex01_puppet2.wrl"} ]
}

Transform {
  rotation 0 0 -1 0.375
  children [ 
    Transform {
      translation -0.27 1.5 0
      rotation -1 0 0  1.57
      scale 0.35 0.35 0.35 
      children [ Doughnut { doughnutColor 0.4 0.8 0.6 } ] }
]}

Transform {
  translation -0.3 -1.5 0.4
  scale 0.2 0.2 0.2 
  children [ Soccerball { soccerballColor
                           [1 1 0, 1 1 0, 1 1 0, 1 1 0, 1 1 0,  
                            1 1 0, 1 1 0, 1 1 0, 1 1 0, 1 1 0,  
                            1 1 0, 1 1 0, 1 1 0, 1 1 0, 1 1 0,  
                            1 1 0, 1 1 0, 1 1 0, 1 1 0, 1 1 0,  
                            0 0 1, 0 0 1, 0 0 1, 0 0 1, 0 0 1, 
                            0 0 1, 0 0 1, 0 0 1, 0 0 1, 0 0 1, 
                            0 0 1, 0 0 1 ]
                          } 
]}