情報科学科演習3 第3期西田研課題

11007 片岡ハルカ

各課題のアプレットとソース

  1. 等高線の描画(アプレット)(ソース)(解説)
  2. 等値面の多角形描画(アプレット)(ソース)(解説)
  3. voxel splattingの描画(アプレット)(ソース)(解説)
  4. (3-b)voxel splattingの描画テストバージョン(アプレット)

解説

課題1.等高線の描画

marching squares 法を用いてメッシュデータの等高線を表示します。配付されたテキストの506p.~507p.のソースを参考に作られています。(実行例の画像)

ソースファイルの解説

AbstractMeshData.java
メッシュデータの抽象クラス。メソッドheightFieldによって、0からfieldXSize(),fieldYSize()までの整数値で与えられるメッシュのx,y位置に対して、0から1のdouble値を返します。
GaussMeshData.java
2つのガウス分布によるこぶのあるメッシュデータ
FractalMeshData.java
フラクタルにより補間したハイトフィールドのメッシュデータ。初期化時に、中点変位法により3x3の初期値データを補完し、メッシュデータを作ります。heightField実行時にデータを0~1に正規化して返します。
ContourCurvesPanel.java
メッシュデータの等高線を表示するPanel、marching squares法を用いています。メッシュ内での線を引く位置は格子点の値によって線形補間されています。線の引き方の場合わけがambiguousな場合はメッシュを4分割して再帰しています。
ContourCurves.java
アプレットのメイン、GaussMeshDataとFractalMeshDataのインスタンスをそれぞれ作成し、ContourCurvesPanelを用いて表示します。スライダーの値によってコンストラクタに与える初期値を変化させる事が出来ます。

課題2.等値面の多角形描画

marching cubes 法を用いて3次元のメッシュデータの等値面を表示します。(実行例の画像)

等値面をポリゴン等で表示するには、ボクセル内部の等値面を三角形か四角形に分割する必要があり、その為にはボクセルの頂点8つのしきい値に対する大小によって「2^8通りの場合わけ」→「反転、回転パターンを統合した14通りの場合わけ」を考える必要があります。

しかし、この課題の場合ラインで面を表現するだけですので、「等値面とボクセルの表面の交わる線」だけを表示するだけで、十分面を表現できる上、余分な線が少ない分見やすい表現になります。
そして、「等値面とボクセルの表面の交わる線」は、ボクセルの6つの面についてmarching squares法で等高線を引く事で描く事ができるので、課題1のソースを流用できます。
さらに、となりあったボクセルはそれぞれ1つの面を共有していますので、各ボクセルについて3つの面を描画すれば、重複無く全部の面を表示する事が出来ます。

ソースファイルの解説

Point3.java
doubleのx,y,z座標点を表すクラスです。2つのPoint3の距離の二乗を返す関数、ベクトルの定数倍を返す関数、2つのPoint3を足す関数がついてます。
Trans.java
昔の駒場の総合科目での西田先生の課題のサンプルより流用した、基準座標のPoint3を指定した視点から見た座標のPoint3に変換するクラスです。(当然Point3も流用です、関数はいろいろ加えましたが)
MetaBall.java
メタボールのクラス、Point3によってその座標でのメタボールの(ガウス分布の)値を取得できます。
Abstract3DMesh.java
3次元メッシュデータの抽象クラス。メソッドmeshFieldによって、0からfieldSize()までの整数値で与えられるメッシュのx,y,z位置に対して、0から1のdouble値を返します。
MetaBall3DMesh.java
メタボールが3つあるサンプルデータのクラス。計算を高速化できる様に生成時点で各格子での値を配列にメモリーしています。
MarchingCubesPanel.java
Abstract3DMeshに対してmarching cubes法によって等値面を表示します。この表示は上記の様に各ボクセルに対してmarching squares法の1メッシュの描画を3面分行います。そのため描画関数の中身の大半は課題1のものを流用し、線を描画する命令を独自のg_drawLineに置換して、g_drawLineの中で座標をTransクラスで変換して描画しています。
MarchingCube.java
アプレットのメイン、MetaBall3DMeshのインスタンスを作成し、MarchingCubesPanelを用いて表示します。スライダーの値によってコンストラクタに与える初期値を変化させる事が出来ます。

課題3.voxel splattingの描画

voxel splattingによって3次元メッシュデータを可視化します。(実行例の画像)

voxelの形状は立方体で、footprintを描画するためにvoxelの6面の投影を重ねて書き込んでいます。JavaのColorクラスのアルファ値設定を利用して半透明処理を行っています。ボクセルの値はボクセルの8個の頂点の平均とし、色は赤→青が値の高低を表し、スライダーで指定した値を中心にガウス分布で不透明度を与えています。

尚、MicrosoftのJavaVMでこの半透明処理が上手く動かないらしい(画面が黒いまま)という報告があります。(テストバージョン--半透明カラーを使わず、不透明度が0.5以上になるボクセルのみ不透明カラーで描画する様にしたバージョン--が動く事からの推測です)

ソースファイルの解説

これらのクラスは課題2の物と同じ物を流用しています。
Trans3DMeshProject.java
この課題ではTransクラスにメッシュの格子点でしかアクセスされない事を利用し、あらかじめTransの出力を配列にメモリーして置く事で高速化するTransの派生クラス。このクラスからTransの出力を読み出すには配列x[][][],y[][][]に直接アクセスします。
VoxelSplatterPanel.java
Abstract3DMeshをvoxel splattingで表示します。各ボクセルに対して、奥から手前の順になる様にアクセスしながらvoxelのfootprintを書き込んでいきます。
VoxelSplatter.java
アプレットのメイン、MetaBall3DMeshのインスタンスを作成し、VoxelSplatterPanelを用いて表示します。スライダーの値によってコンストラクタに与える初期値を変化させる事が出来ます。