■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
                      2008年08月10日

    楽しいJava講座 - 初心者から達人へのパスポート
                  vol.115

                                セルゲイ・ランダウ
 バックナンバー: http://www.flsi.co.jp/Java_text/
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■


[このメールマガジンは、画面を最大化して見てください。]


========================================================
◆ 01.3Dグラフィックスのアプリケーション開発
========================================================

さて、前回は球体にいくつかの方向から白色光を当てて見てみましたが、
このとき、球体が少しいびつに見えたはずです。

実は、この球体は実際にいびつに作られているのです。
しかし、球体が小さかったし、光の色や照射する方向のせいで、あまり
いびつさが目立たなかったのです。


では、球体をSphere(0.5f)というように半径を大きくし、光の色を
黄色で少し暗いColor3f(3.0f, 3.0f, 0.0f)に変え、照射する向きを
Vector3f(-1.0f, -1.0f, -1.0f)に変えてみましょう。

つまり、次のようにinitialize()メソッドを書き換えてみてください。

--------------------------------------------------------
   private void initialize() {
      this.setSize(300, 200);
      this.setContentPane(getJContentPane());
      this.setTitle("立方体と球体");

      GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
      Canvas3D canvas = new Canvas3D(config);
      SimpleUniverse universe = new SimpleUniverse(canvas);
      BranchGroup group = new BranchGroup();
      TransformGroup transGroup = new TransformGroup();
      transGroup.addChild(new ColorCube(0.3));
      Transform3D trans = new Transform3D();
      trans.setTranslation(new Vector3d(-2.0, -1.0, -5.0));
      transGroup.setTransform(trans);
      group.addChild(transGroup);

      BranchGroup group2 = new BranchGroup();
      Sphere sphere = new Sphere(0.5f);
      group2.addChild(sphere);
      Color3f color = new Color3f(3.0f, 3.0f, 0.0f);
      BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 1.0);
      Vector3f lightDirection = new Vector3f(-1.0f, -1.0f, -1.0f);
      DirectionalLight light   = new DirectionalLight(color, lightDirection);
      light.setInfluencingBounds(bounds);
      group2.addChild(light);
      group.addChild(group2);

      universe.getViewingPlatform().setNominalViewingTransform();
      group.compile();
      universe.addBranchGraph(group);
      getJContentPane().add(canvas);
   }
--------------------------------------------------------

編集が終わったら、保管して実行してみてください。球体の表面が複数の
三角形を組み合わせて作られた凸凹状に見えるでしょう。

実は、このSphereという球体の表面は、複数の三角形を組み合わせて
作られているのです。


一般にJava 3Dでは、複雑な形状は多角形(polygon)を複数組み合わせる
ことによって作成するのですが、多角形の一番単純なものが三角形ですね。

┌補足─────────────────────────┐
多角形は、三角形、四角形、五角形、六角形、・・・・のように
複数の角を持つ図形のことです。その中で一番単純なものが三角形
ですね。
この多角形(polygon)のことをコンピューターのグラフィックス
関係の専門書では、英単語をカタカナ書きに変えただけの
「ポリゴン」という言葉で表記していることが多いようです。
専門書を読んでいてポリゴンという言葉が出てきたら、多角形
のことだと理解してください。
└───────────────────────────┘


というわけで、複雑な形状は、ほとんどの場合は三角形を複数組み合わせる
ことによって成形します。
そして、これらの多角形(三角形)を複数組み合わせたときに網の目のように
なりますから、この網状のものをメッシュ(mesh)と呼びます。メッシュ(mesh)
とは文字通り、網の意味ですね。

Sphereという球体もこの多角形(三角形)によるメッシュで作られるのですが、
デフォルトでは、メッシュが粗い(三角形の数が少ない)ためにいびつさが目立つ
のです。
メッシュを細かく(三角形の数を多く)すれば、いびつさは目立たなくなります。

┌補足─────────────────────────┐
このメッシュという言葉は、グラフィックスの他に、CAE(Computer
Aided Engineering)における構造解析などでもよく使われます。
構造解析というのは、建築物や工業的製造物の強度などを調べる
ための解析で、複雑な形状をした製造物をそのまま解析することは
困難なので、製造物をメッシュに、つまり、複数のポリゴンに
分割して、解析が行われます。
└───────────────────────────┘


では、ソース・コードを書き換えて、メッシュを細かくしてみましょう。
メッシュの網目の数を増やすべく、Sphereのコンストラクターの指定を
Sphere(0.5f, Sphere.GENERATE_NORMALS, 100)
に変えてみましょう。(この二つ目の引数は図形の幾何学的特性に関するフラグで、
三つ目の引数は網目の数に対応します。このフラグはPrimitiveという(基本図形を
表現する)クラスで定義されていますが、詳しいことは後述します。)

つまり、次のようにinitialize()メソッドを書き換えてみてください。

--------------------------------------------------------
   private void initialize() {
      this.setSize(300, 200);
      this.setContentPane(getJContentPane());
      this.setTitle("立方体と球体");

      GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
      Canvas3D canvas = new Canvas3D(config);
      SimpleUniverse universe = new SimpleUniverse(canvas);
      BranchGroup group = new BranchGroup();
      TransformGroup transGroup = new TransformGroup();
      transGroup.addChild(new ColorCube(0.3));
      Transform3D trans = new Transform3D();
      trans.setTranslation(new Vector3d(-2.0, -1.0, -5.0));
      transGroup.setTransform(trans);
      group.addChild(transGroup);

      BranchGroup group2 = new BranchGroup();
      Sphere sphere = new Sphere(0.5f, Sphere.GENERATE_NORMALS, 100);
      group2.addChild(sphere);
      Color3f color = new Color3f(3.0f, 3.0f, 0.0f);
      BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 1.0);
      Vector3f lightDirection = new Vector3f(-1.0f, -1.0f, -1.0f);
      DirectionalLight light   = new DirectionalLight(color, lightDirection);
      light.setInfluencingBounds(bounds);
      group2.addChild(light);
      group.addChild(group2);

      universe.getViewingPlatform().setNominalViewingTransform();
      group.compile();
      universe.addBranchGraph(group);
      getJContentPane().add(canvas);
   }
--------------------------------------------------------

編集が終わったら、保管して実行してみてください。球体の表面がなめらかに
なって、球面らしくなりましたね。



では、今日はここまでにします。

何か、わからないところがありましたら、下記のWebページまで質問を
お寄せください。



┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
★ホームページ:
      http://www.flsi.co.jp/Java_text/
★このメールマガジンは
     「まぐまぐ(http://www.mag2.com)」
 を利用して発行しています。
★バックナンバーは
      http://www.flsi.co.jp/Java_text/
 にあります。
★このメールマガジンの登録/解除は下記Webページでできます。
      http://www.mag2.com/m/0000193915.html
★このメールマガジンへの質問は下記Webページにて受け付けて
 います。わからない所がありましたら、どしどしと質問をお寄
 せください。
      http://www.flsi.co.jp/Java_text/
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

Copyright (C) 2008 Future Lifestyle Inc. 不許無断複製