VFIVE (Vector Field Interactive Visualization Environment) は、 CAVE型VRシステムを用いて3次元データを可視化し、 解析するための汎用プログラムである。 ユーザーは自分でプログラミングする手間なしに (コマンド一つ打つだけで)、 自分のシミュレーションデータをすぐに仮想現実化して観察することが出来る。 このプログラムの主要な目的は、 複雑な3次元ベクトル場を3次元のまま解析することである。 このために、 仮想現実(VR)技術の持つ立体感や対話性、 没入感などの特徴を利用した様々な可視化モジュールを開発した。 VFIVEには簡単なメニュー機能があり、 様々な可視化機能やその対象となる場を容易に選択することが可能である。 VFIVEにはまた、曲線や曲面の座標データをオプションとして渡すことによって、 それらの物体をVR空間内に自動的に構成し、 表示させる機能も持つ。 この機能は、 各ユーザーがそれぞれ独自の可視化手法とデータを使ってあらかじめ計算 (定義)済みのオブジェクトを表示させたい場合等に便利である。
VFIVEは本来、 シミュレーションの解析に利用することを想定して開発が始められたが、 入力データ形式やその可視化機能には汎用性があるため、 様々な分野の実験や観測データの解析等にも応用できる。
VFIVEの公開バージョン(Ver.3.72)で解析可能なデータの定義領域は直方体である。 座標はカーテシアン(x,y,z)で与える。 x,y,zの各方向のグリッドは不等間隔でもよい。 一般の曲線座標系上でのデータをVFIVEで可視化する時には、 あらかじめデータをカーテシアン座標上にマップしたものを用意して頂きたい。
ユーザがVFIVEに与える入力データファイルは現在以下のものがある。 それぞれのデータフォーマットについては後述する。
与えられる場の数には以下の制限がある。
グリッドの座標と場のデータは次のテキストファイルに記述する。 以下に2つのベクトル場(磁場と速度場)と 2つのスカラー場(圧力場と密度場)の可視化のための サンプルファイル "test.v5"を示す。 (ファイルの拡張子は何でも良い。)
+------------------------------------------------------------------+ | 入力ファイルの例 始まり % cat test.v5 # test.v5 ('#' で始まる行はコメント) # # 左にキーワード(1カラム目から) スペースが任意個続いて パラメータ値 # n1 60 n2 70 n3 80 nvec 2 nscal 2 scale 1.0 shift_x 0.0 shift_y 0.0 shift_z 0.0 xfile /home/guest/test/test-coord.x yfile /home/guest/test/test-coord.y zfile /home/guest/test/test-coord.z vect0_label MAGNETIC\nField vect0x /home/guest/test/test-magnetic.x vect0y /home/guest/test/test-magnetic.y vect0z /home/guest/test/test-magnetic.z vect1_label VELOCITY\nField vect1x /home/guest/test/test-velocity.x vect1y /home/guest/test/test-velocity.y vect1z /home/guest/test/test-velocity.z scal0_label PRESSURE scal0 /home/guest/test/test-pressure scal1_label DENSITY scal1 /home/guest/test/test-density | 入力ファイルの例 終わり +------------------------------------------------------------------+
それぞれのパラメータの意味をコメントの形で説明する。
+------------------------------------------------------------------+ | コメント付き 入力ファイルの例 始まり # test.v5 ('#' で始まる行はコメント) # # ... x方向のグリッド数 n1 60 # ... y方向のグリッド数 n2 70 # ... z方向のグリッド数 n3 80 # ... ベクトル場の数 2 (磁場と速度場) nvec 2 # ... スカラー場の数 2 (圧力と密度) nscal 2 # ... スケール変換パラメータ (シミュレーション座標系での値に # ... この値を乗じたものがメートルのスケールで CAVE の部屋に表示される。 scale 1.0 # ... 座標平行移動パラメータ (プログラム開始時にこの距離だけ原点を # x方向に移動してからCAVEに表示する。単位はシミュレーション座標系で。) shift_x 0.0 # ... 同様にyとz方向の移動量 shift_y 0.0 shift_z 0.0 # ... x座標値ファイル(倍精度実数。書き方は後述) xfile /home/guest/test/test-coord.x # ... y座標値ファイル(倍精度実数。書き方は後述) yfile /home/guest/test/test-coord.y # ... z座標値ファイル(倍精度実数。書き方は後述) zfile /home/guest/test/test-coord.z # ... 最初のベクトル場のラベル(メニューに書かれる)。 '\n'は改行 vect0_label MAGNETIC\nField # ... 最初のベクトル場のx成分(倍精度実数。書き方は後述) vect0x /home/guest/test/test-magnetic.x # ... 最初のベクトル場のy成分(倍精度実数。書き方は後述) vect0y /home/guest/test/test-magnetic.y # ... 最初のベクトル場のz成分(倍精度実数。書き方は後述) vect0z /home/guest/test/test-magnetic.z # ... 2番目ベクトル場のラベル(メニューに書かれる)。 '\n'は改行 vect1_label VELOCITY\nField # ... 2番目のベクトル場のx成分(倍精度実数。書き方は後述) vect1x /home/guest/test/test-velocity.x # ... 2番目のベクトル場のy成分(倍精度実数。書き方は後述) vect1y /home/guest/test/test-velocity.y # ... 2番目のベクトル場のz成分(倍精度実数。書き方は後述) vect1z /home/guest/test/test-velocity.z # ... 最初のスカラー場のラベル(メニューに書かれる) scal0_label PRESSURE # ... 最初のスカラー場(倍精度実数。書き方は後述) scal0 /home/guest/test/test-pressure # ... 2番目のスカラー場のラベル(メニューに書かれる) scal1_label DENSITY # ... 2番目のスカラー場(倍精度実数。書き方は後述) scal1 /home/guest/test/test-density # -- 以上。 | コメント付き 入力ファイルの例 終わり +------------------------------------------------------------------+
座標データファイル (上の例 "test.v5" では /home/guest/test/test-coord.x 他二つ。) は、
で用意する。下に(倍精度実数の)サンプルプログラムを示す。
+------------------------------------------------------+ | 座標データファイル生成プログラムの例 (Fortran) 始まり implicit none integer nx, ny, nz parameter(nx=60,ny=70,nz=80) integer i, j, k real*8 xpos(nx), ypos(ny), zpos(nz) character*50 xfile, yfile, zfile c xfile = "/home/guest/test/test-coord.x" yfile = "/home/guest/test/test-coord.y" zfile = "/home/guest/test/test-coord.z" c do i = 1 , nx xpos(i) = x座標の定義。不等間隔グリッドも可。 end do c do j = 1 , ny ypos(j) = y座標の定義。不等間隔グリッドも可。 end do c do k = 1 , nz zpos(k) = z座標の定義。不等間隔グリッドも可。 end do c open(11,file=xfile,form='unformatted') open(12,file=yfile,form='unformatted') open(13,file=zfile,form='unformatted') write(11) xpos write(12) ypos write(13) zpos close(13) close(12) close(11) c stop end | 座標データファイル生成プログラムの例(Fortran) 終わり +------------------------------------------------------+ |
+----------------------------------------------------+ | 座標データファイル生成プログラムの例 (C言語) 始まり #include <stdio.h> #include <stdlib.h> const int nx = 60; const int ny = 70; const int nz = 80; int main(int argc, char **argv) { int i, j, k; double xpos[nx], ypos[ny], zpos[nz]; char dummy[4]; FILE *fp; char xfile[] = "/home/guest/test/test-coord.x"; char yfile[] = "/home/guest/test/test-coord.y"; char zfile[] = "/home/guest/test/test-coord.z"; for(i = 0; i < nx ; i++){ xpos[i] = x座標の定義。不等間隔グリッドも可。; } for(j = 0; j < ny; j++){ ypos[j] = y座標の定義。不等間隔グリッドも可。; } for(k = 0; k < nz; k++){ zpos[k] = z座標の定義。不等間隔グリッドも可。; } if((fp=fopen(xfile,"wb")) == NULL){ fputs("Error\n",stderr); exit(1); } fwrite(dummy, 1, 4, fp); fwrite(xpos, sizeof(double), nx, fp); fclose(fp); if((fp=fopen(yfile,"wb")) == NULL){ fputs("Error\n",stderr); exit(1); } fwrite(dummy, 1, 4, fp); fwrite(ypos, sizeof(double), ny, fp); fclose(fp); if((fp=fopen(zfile,"wb")) == NULL){ fputs("Error\n",stderr); exit(1); } fwrite(dummy, 1, 4, fp); fwrite(zpos, sizeof(double), nz, fp); fclose(fp); return 0; } | 座標データファイル生成プログラムの例(C言語) 終わり +----------------------------------------------------+ |
ベクトル場及びスカラー場のデータファイル (上の例 "test.v5" では /home/guest/test/test-magnetic.x 等)も 上述の座標データと同様に
で用意する。下にサンプルプログラムを示す。
+-----------------------------------------------------------+ | 場のデータファイル生成プログラムの例(Fortran) 始まり implicit none integer nx, ny, nz parameter(nx=60,ny=70,nz=80) integer i,j,k real*8 xmag(nx,ny,nz), ymag(nx,ny,nz), zmag(nx,ny,nz) real*8 xvel(nx,ny,nz), yvel(nx,ny,nz), zvel(nx,ny,nz) real*8 pres(nx,ny,nz), dens(nx,ny,nz) character*50 xmfile, ymfile, zmfile character*50 xvfile, yvfile, zvfile character*50 psfile, dnfile c xmfile = "/home/guest/test/test-magnetic.x" ymfile = "/home/guest/test/test-magnetic.y" zmfile = "/home/guest/test/test-magnetic.z" xvfile = "/home/guest/test/test-velocity.x" yvfile = "/home/guest/test/test-velocity.y" zvfile = "/home/guest/test/test-velocity.z" psfile = "/home/guest/test/test-pressure.z" dnfile = "/home/guest/test/test-density.z" c do k = 1 , nz do j = 1 , ny do i = 1 , nx xmag(i,j,k) = 磁場のx成分の定義。 ymag(i,j,k) = 磁場のy成分の定義。 zmag(i,j,k) = 磁場のz成分の定義。 xvel(i,j,k) = 速度場のx成分の定義。 yvel(i,j,k) = 速度場のy成分の定義。 zvel(i,j,k) = 速度場のz成分の定義。 pres(i,j,k) = 圧力場の定義。 dens(i,j,k) = 密度場の定義。 end do end do end do c open(11,file=xmfile,form='unformatted') open(12,file=ymfile,form='unformatted') open(13,file=zmfile,form='unformatted') open(21,file=xvfile,form='unformatted') open(22,file=yvfile,form='unformatted') open(23,file=zvfile,form='unformatted') open(31,file=psfile,form='unformatted') open(32,file=dnfile,form='unformatted') write(11) xmag write(12) ymag write(13) zmag write(21) xvel write(22) yvel write(23) zvel write(31) pres write(32) dens close(32) close(31) close(23) close(22) close(21) close(13) close(12) close(11) c stop end | 場のデータファイル生成プログラムの例 (Fortran) 終わり +-----------------------------------------------------------+ |
+-----------------------------------------------------------+ | 場のデータファイル生成プログラムの例(C言語) 始まり #include <stdio.h> #include <stdlib.h> const int nx = 60; const int ny = 70; const int nz = 80; int main(int argc, char **argv) { int i,j,k; double xmag[nz][ny][nx], ymag[nz][ny][nx], zmag[nz][ny][nx]; double xvel[nz][ny][nx], yvel[nz][ny][nx], zvel[nz][ny][nx]; double pres[nz][ny][nx], dens[nz][ny][nx]; char dummy[4]; FILE *fp; char xmfile[] = "/home/guest/test/test-magnetic.x"; char ymfile[] = "/home/guest/test/test-magnetic.y"; char zmfile[] = "/home/guest/test/test-magnetic.z"; char xvfile[] = "/home/guest/test/test-velocity.x"; char yvfile[] = "/home/guest/test/test-velocity.y"; char zvfile[] = "/home/guest/test/test-velocity.z"; char psfile[] = "/home/guest/test/test-pressure.z"; char dnfile[] = "/home/guest/test/test-density.z"; for(k = 0; k < nz; k++){ for(j = 0; j< ny; j++){ for(i = 0; i < nx; i++){ xmag[k][j][i] = 磁場のx成分の定義。; ymag[k][j][i] = 磁場のy成分の定義。; zmag[k][j][i] = 磁場のz成分の定義。; xvel[k][j][i] = 速度場のx成分の定義。; yvel[k][j][i] = 速度場のy成分の定義。; zvel[k][j][i] = 速度場のz成分の定義。; pres[k][j][i] = 圧力場の定義。; dens[k][j][i] = 密度場の定義。; } } } if((fp=fopen(xmfile,"wb")) == NULL){ fputs("Error\n",stderr); exit(1); } fwrite(dummy, 1, 4, fp); fwrite(xmag, sizeof(double), nx * ny * nz, fp); fclose(fp); .........(略)......... return 0; } | 場のデータファイル生成プログラムの例(C言語) 終わり +-----------------------------------------------------------+ |
マルチスレッド版は、単精度(C/C++のfloat型)のデータも可視化できる。vfive.hの(56,57行目のあたり)
//====== // float or double. // Added on 2008.05.27. by A.K. // typedef float ffloat_; typedef double ffloat_; //=== ===
を
//====== // float or double. // Added on 2008.05.27. by A.K. typedef float ffloat_; // typedef double ffloat_; //=== ===
として、再コンパイルする。座標データと場のデータいずれも単精度にする必要がある。
マルチスレッド版ver.3.72aは、時間発展データを扱うことができる。
時間発展データを扱う場合の入力ファイルは、下記のとおりである。
+----------------------------
n1 256 n2 128 n3 128 ntime 5 nvec 1 nscal 2 scale 1.000 shift_x -6.500 shift_y -3.000 shift_z -3.000 xfile /home/guest/data/coord_x.dat yfile /home/guest/data/coord_y.dat zfile /home/guest/data/coord_z.dat vect0_label vel vect0xt0 /home/guest/data/velx200.dat vect0yt0 /home/guest/data/vely200.dat vect0zt0 /home/guest/data/velz200.dat vect0xt1 /home/guest/data/velx205.dat vect0yt1 /home/guest/data/vely205.dat vect0zt1 /home/guest/data/velz205.dat vect0xt2 /home/guest/data/velx210.dat vect0yt2 /home/guest/data/vely210.dat vect0zt2 /home/guest/data/velz210.dat vect0xt3 /home/guest/data/velx215.dat vect0yt3 /home/guest/data/vely215.dat vect0zt3 /home/guest/data/velz215.dat vect0xt4 /home/guest/data/velx220.dat vect0yt4 /home/guest/data/vely220.dat vect0zt4 /home/guest/data/velz220.dat vectmax0 0.06 vectmin0 0.0 scal0_label pressure scal0t0 /home/guest/data/pre200.dat scal0t1 /home/guest/data/pre205.dat scal0t2 /home/guest/data/pre210.dat scal0t3 /home/guest/data/pre215.dat scal0t4 /home/guest/data/pre220.dat scalmax0 -11.0 scalmin0 -20.0 scal1_label density scal1t0 /home/guest/data/den200.dat scal1t1 /home/guest/data/den205.dat scal1t2 /home/guest/data/den210.dat scal1t3 /home/guest/data/den215.dat scal1t4 /home/guest/data/den220.dat scalmax1 -5.0 scalmin1 -16.0
+----------------------------
コメント付きで、意味の説明をする
+----------------------------
n1 256 n2 128 n3 128 ntime 5 # タイムステップ数 nvec 1 nscal 2 scale 1.000 shift_x -6.500 shift_y -3.000 shift_z -3.000 xfile /home/guest/data/coord_x.dat yfile /home/guest/data/coord_y.dat zfile /home/guest/data/coord_z.dat vect0_label vel vect0xt0 /home/guest/data/velx200.dat #0番目のベクトルデータの時刻0のx成分のデータ vect0yt0 /home/guest/data/vely200.dat #0番目のベクトルデータの時刻0のy成分のデータ vect0zt0 /home/guest/data/velz200.dat #0番目のベクトルデータの時刻0のz成分のデータ vect0xt1 /home/guest/data/velx205.dat #0番目のベクトルデータの時刻1のx成分のデータ vect0yt1 /home/guest/data/vely205.dat #0番目のベクトルデータの時刻1のy成分のデータ vect0zt1 /home/guest/data/velz205.dat #0番目のベクトルデータの時刻1のz成分のデータ vect0xt2 /home/guest/data/velx210.dat #0番目のベクトルデータの時刻2のx成分のデータ vect0yt2 /home/guest/data/vely210.dat #0番目のベクトルデータの時刻2のy成分のデータ vect0zt2 /home/guest/data/velz210.dat #0番目のベクトルデータの時刻2のz成分のデータ vect0xt3 /home/guest/data/velx215.dat #0番目のベクトルデータの時刻3のx成分のデータ vect0yt3 /home/guest/data/vely215.dat #0番目のベクトルデータの時刻3のy成分のデータ vect0zt3 /home/guest/data/velz215.dat #0番目のベクトルデータの時刻3のz成分のデータ vect0xt4 /home/guest/data/velx220.dat #0番目のベクトルデータの時刻4のx成分のデータ vect0yt4 /home/guest/data/vely220.dat #0番目のベクトルデータの時刻4のy成分のデータ vect0zt4 /home/guest/data/velz220.dat #0番目のベクトルデータの時刻4のz成分のデータ vectmax0 0.06 #0番目のベクトルデータの大きさの最大値 vectmin0 0.0 #0番目のベクトルデータの大きさの最小値 scal0_label pressure scal0t0 /home/guest/data/pre200.dat #0番目のスカラーデータの時刻0のデータ scal0t1 /home/guest/data/pre205.dat #0番目のスカラーデータの時刻1のデータ scal0t2 /home/guest/data/pre210.dat #0番目のスカラーデータの時刻2のデータ scal0t3 /home/guest/data/pre215.dat #0番目のスカラーデータの時刻3のデータ scal0t4 /home/guest/data/pre220.dat #0番目のスカラーデータの時刻4のデータ scalmax0 -11.0 #0番目のスカラーデータの最大値 scalmin0 -20.0 #0番目のスカラーデータの最小値 scal1_label density scal1t0 /home/guest/data/den200.dat #1番目のスカラーデータの時刻0のデータ scal1t1 /home/guest/data/den205.dat #1番目のスカラーデータの時刻1のデータ scal1t2 /home/guest/data/den210.dat #1番目のスカラーデータの時刻2のデータ scal1t3 /home/guest/data/den215.dat #1番目のスカラーデータの時刻3のデータ scal1t4 /home/guest/data/den220.dat #1番目のスカラーデータの時刻4のデータ scalmax1 -5.0 #1番目のスカラーデータの最大値 scalmin1 -16.0 #1番目のスカラーデータの最小値
+----------------------------
実行コマンドは "vfive" である。 CAVEの計算機にログインして、
% vfive test.v5
と打てば良い。(Windowsの場合は、コマンドプロンプトで入力する)
オプションは二つある。
例1 曲線の表示:
% vfive test.v5 -l test-lines.v5
例2 曲面の表示:
% vfive test.v5 -s test-surfaces.v5
例3 曲線と曲面の表示:
% vfive test.v5 -l test-lines.v5 -s test-surfaces.v5
曲面と曲線データのフォーマットについては後述する。
CAVEに入りステレオ眼鏡をかけてしばらく待と 境界線を示す直方体が出現する。
データの境界を示す立方体の辺には赤、緑、青の3種類の色がついているが、 これはそれぞれx-軸方向、y-軸方向、z-軸方向を表す。 プログラム開始時には、 正面のスクリーンに向かう方向がy軸、 右がx軸、上がz軸になっている。
VFIVEにはデータを可視化するための機能が複数用意されており、 その基本的な使い方は次のように統一されている。
(ワンドに付属の黒くて大きなボタン)は仮想空間の ナビゲーション(移動と回転)に使われる。
障害物回りの流れデータをVFIVEで解析する時など、 その障害物を3次元物体としてVR空間に表示できることが望ましい。 VFIVEではオプション引数として「-s 曲面データファイル名」を渡すことにより、 そのデータが記述する複数の曲面を表示することが出来る。 曲面データファイルは次の形のテキストファイルである。
% cat test-surf.v5 +------------------------------------------------+ | 曲面データファイル例 始まり # vfive sample surface data surfaceObj:nmen 2 surfaceObj:ni_max 30 surfaceObj:nj_max 50 surfaceObj:xfile /home/guest/test/test.surf.x surfaceObj:yfile /home/guest/test/test.surf.y surfaceObj:zfile /home/guest/test/test.surf.z | 曲面データファイル例 終わり +------------------------------------------------+
上の曲面データファイルには、
表示する面の総数 nmen 一つの面を構成するグリッド数 ni_max * nj_max 各面を構成するグリッドのx座標ファイル xfile 各面を構成するグリッドのy座標ファイル yfile 各面を構成するグリッドのz座標ファイル zfile
を指定する。 グリッドの座標ファイルは、
で用意する。 座標や場のデータは倍精度で与えるが、 曲面データは単精度であることに注意。 これは、すでに計算済みの曲面を仮想空間に表示する場合、 位置の指定にそれほど高い精度が要求されないのに対し、 場や座標のデータに関しては、 力線追跡などの際に高い精度が要求されるためである。
一つの曲面は滑らかな形状であることを仮定している。 球面や円柱の側面などは滑らかな曲面の典型的な例である。 四角柱の側面のように尖った角をもつ曲面は、 複数の曲面(四角柱の場合は四つ)を入力データとして与えることで実現する。
一般にコンピュータグラフィックスでは、 曲面を描く際に、曲面を構成する各頂点の座標データと共に、 各頂点におけるその面の法線ベクトルも指定する必要がある。 VFIVEでは、それぞれの曲面が滑らかであることを仮定して、 頂点座標のデータから法線ベクトルを自動的に計算している。
一つの曲面は二つの整数パラメータ(例えば i と j)で定義し、 複数の曲面を3番目のパラメータで区別する。
例: 1番目の曲面が長方形: x(i,j,1) = i*dx (dxは定数) y(i,j,1) = j*dy (dyは定数) z(i,j,1) = 0.0 2番目の曲面が円筒面: x(i,j,2) = cos(j*dphi) (dphiは定数) y(i,j,2) = sin(j*dphi) z(i,j,2) = i*dz 3番目の曲面が球面: x(i,j,3) = sin(j*dtht)*cos(i*dphi) (dtht, dphiは定数) y(i,j,3) = sin(j*dtht)*sin(i*dphi) z(i,j,3) = cos(j*dtht)
与える曲面のトポロジーは
の3種類を想定している。 これらの違いは境界条件だけである。 これら3種類のトポロジーは入力データからVFIVEが自動的に判断する。 例えば、i=1とi=imaxでのx,y,zの値が全てのjについて正確に一致している (つまり浮動小数点の比較 val(i=1,j) == val(i=imax,j), val=x,y,z, が成り立つ) 場合は円筒面と判断する。 従って、例えば円筒面を10角形で表示する場合、i=1から(10ではなく) i=11のデータを用意し、
x(11,j,men) = x(1,j,men) y(11,j,men) = y(1,j,men) z(11,j,men) = z(1,j,men)
という形で座標値をコピーしておくのがよい。
複数の曲面を表示する場合は、 それぞれの曲面を定義するパラメータiやjの最大値(imax, jmax) が必ずしも一致しなくても良い。 例えば(100グリッド x 200グリッド)の長方形と (80グリッド x 120 グリッド)の長方形を表示する場合は、
real*4 x(100,200,2), y(100,200,2), z(100,200,2)
と宣言しておいて、 2番目(小さい方)の長方形のデータの不要なグリッドには、 ダミーデータを入れておく。 ダミーデータとして
999.
の値を入れる。 実際にはVFIVEは、i=1の軸上をj=1からj=2,3,4と走査していき、 初めて999.に出会う直前のjをその面を定義するの実質上のjmax、 また、j=1の軸上をi=1からi=2,3,4と走査していき、 初めて999.に出会う直前のiをその面を定義する実質上のimaxと解釈する。 つまり、上の例では、
x(81,1,2) = 999. y(81,1,2) = 999. z(81,1,2) = 999. x(1,121,2) = 999. y(1,121,2) = 999. z(1,121,2) = 999.
とだけ入れておけばよい。 以下に、一つのトーラスと一つの曲面(球面の一部、下図参照) を定義するサンプルプログラムを示す。 このプログラムは、上に示した曲面データフィアル test-surf.v5 と、 その座標バイナリデータを同時に生成する。
+----------------------------------------------------------+ | 曲面データ生成プログラム例(Fortran) 始まり parameter(nmen=2,nimax=30,njmax=50) parameter(pi=3.141593,twopi=2*pi) parameter(huge=999.0) character*50 xfile, yfile, zfile, v5file real*4 x(nimax, njmax, nmen) real*4 y(nimax, njmax, nmen) real*4 z(nimax, njmax, nmen) xfile = "/home/guest/test/test.surf.x" yfile = "/home/guest/test/test.surf.y" zfile = "/home/guest/test/test.surf.z" v5file = "/home/guest/test/test-surf.v5" c Torus rmajor = 10.0 rminor = 2.0 x0 = 32.0 y0 = 32.0 z0 = 32.0 dphi = twopi / (nimax-1) dtht = twopi / (njmax-1) do j = 1 , njmax tht = dtht*(j-1) do i = 1 , nimax phi = dphi*(i-1) if (i.eq.nimax) phi = 0.0 if (j.eq.njmax) tht = 0.0 x(i,j,1) = x0 + (rmajor+rminor*cos(tht))*cos(phi) y(i,j,1) = y0 + (rmajor+rminor*cos(tht))*sin(phi) z(i,j,1) = z0 + rminor*sin(tht) end do end do c Psudo-sphere x0 = 10.0 y0 = 10.0 z0 = 10.0 rad = 10.0 niwork = nimax/2 njwork = njmax/2 dphi = twopi / (niwork-1) thtmin = pi*(2/6.) thtmax = pi*(4/6.) dtht = (thtmax-thtmin) / (njwork-1) do j = 1 , njwork tht = thtmax - dtht*(j-1) do i = 1 , niwork phi = dphi*(i-1) if (i.eq.niwork) phi = 0.0 x(i,j,2) = x0 + rad*sin(tht)*cos(phi) y(i,j,2) = y0 + rad*sin(tht)*sin(phi) z(i,j,2) = z0 + rad*cos(tht) end do end do x(niwork+1,1,2) = huge y(niwork+1,1,2) = huge z(niwork+1,1,2) = huge x(1,njwork+1,2) = huge y(1,njwork+1,2) = huge z(1,njwork+1,2) = huge open(11,file=xfile,form='unformatted') open(12,file=yfile,form='unformatted') open(13,file=zfile,form='unformatted') write(11) x write(12) y write(13) z close(13) close(12) close(11) open(10,file=v5file) write(10,8000) "# vfive sample surface data write(10,8001) "surfaceObj:nmen ", nmen write(10,8001) "surfaceObj:ni_max ", nimax write(10,8001) "surfaceObj:nj_max ", njmax write(10,8002) "surfaceObj:xfile ", xfile write(10,8002) "surfaceObj:yfile ", yfile write(10,8002) "surfaceObj:zfile ", zfile close(10) 8000 format(a) 8001 format(a, i5) 8002 format(a, a) stop end | 曲面データ生成プログラム例(Fortran) 終わり +----------------------------------------------------------+ |
+----------------------------------------------------------+ | 曲面データ生成プログラム例(C++言語) 始まり #include <stdio.h> #include <stdlib.h> #include <math.h> const int nmen = 2; const int nimax = 30; const int njmax = 50; const double pi = 3.141593; const double twopi = 2.0*pi; const float huge = 999.0; int main(int argc, char **argv){ int i,j; float x[nmen][njmax][nimax]; float y[nmen][njmax][nimax]; float z[nmen][njmax][nimax]; char xfile[] = "/home/guest/test/test.surf.x"; char yfile[] = "/home/guest/test/test.surf.y"; char zfile[] = "/home/guest/test/test.surf.z"; char v5file[] = "/home/guest/test/test-surf.v5"; // Torus float rmajor = 10.0; float rminor = 2.0; float x0 = 32.0; float y0 = 32.0; float z0 = 32.0; double dphi = twopi / (nimax-1); double dtht = twopi / (njmax-1); for(j = 0; j< njmax; j++){ double tht = dtht*j; for(i = 0; i< nimax; i++){ double phi = dphi*i; if (i == nimax -1) phi = 0.0; if (j == njmax -1) tht = 0.0; x[0][j][i] = x0 + (rmajor+rminor*cos(tht))*cos(phi); y[0][j][i] = y0 + (rmajor+rminor*cos(tht))*sin(phi); z[0][j][i] = z0 + rminor*sin(tht); } } // Psudo-sphere x0 = 10.0; y0 = 10.0; z0 = 10.0; float rad = 10.0; int niwork = nimax/2; int njwork = njmax/2; dphi = twopi / (niwork-1); double thtmin = pi*(2/6.); double thtmax = pi*(4/6.); dtht = (thtmax-thtmin) / (njwork-1); for(j = 0; j<njwork;j++){ double tht = thtmax - dtht*j; for(i = 0; i < niwork;i++){ double phi = dphi*i; if (i == niwork-1) phi = 0.0; x[1][j][i] = x0 + rad*sin(tht)*cos(phi); y[1][j][i] = y0 + rad*sin(tht)*sin(phi); z[1][j][i] = z0 + rad*cos(tht); } } x[1][0][niwork] = huge; y[1][0][niwork] = huge; z[1][0][niwork] = huge; x[1][njwork][0] = huge; y[1][njwork][0] = huge; z[1][njwork][0] = huge; char dummy[4]; FILE *fp; if((fp=fopen(xfile,"wb")) == NULL){ fputs("Error\n",stderr); exit(1); } fwrite(dummy, 1, 4, fp); fwrite(&x[0][0][0], sizeof(float), nmen*nimax*njmax, fp); fclose(fp); .........(略)......... if((fp=fopen(v5file,"w")) == NULL){ fputs("Error\n",stderr); exit(1); } fprintf(fp, "# vfive sample surface data\n"); fprintf(fp, "surfaceObj:nmen %d\n", nmen); fprintf(fp, "surfaceObj:ni_max %d\n", nimax); fprintf(fp, "surfaceObj:nj_max %d\n", njmax); fprintf(fp, "surfaceObj:xfile %s\n", xfile); fprintf(fp, "surfaceObj:yfile %s\n", yfile); fprintf(fp, "surfaceObj:zfile %s\n", zfile); fclose(fp); return 0; } | 曲面データ生成プログラム例(C++言語) 終わり +----------------------------------------------------------+ |
あらかじめ計算済みの曲線をVFIVEで表示する場合には、 曲線データとして次のようなテキストファイルを用意する。
+------------------------------------------------------------------+ | 曲線データファイル例 始まり % cat test-lines.v5 # vfive sample curve data curveObj:nhon 3 curveObj:ntenmax 100 curveObj:xfile /home/guest/test/test-lines.x curveObj:yfile /home/guest/test/test-lines.y curveObj:zfile /home/guest/test/test-lines.z curveObj:cfile /home/guest/test/test-lines.c | 曲線データファイル例 終わり +------------------------------------------------------------------+
上の例では3本の曲線を定義している。 一本の曲線は最大100点の頂点からから構成され、 xfile, yfile, zfileには、 各曲線の頂点の座標値がバイナリデータで 保存する。 cfileは現在のVFIVEでは読み込みはするが、使用しない。 xfile, yfile, zfileと同じ大きさのダミーを用意する。 将来のバージョンではcfileの値を曲線に色をつけることなどに利用する予定である。 これらのファイルは、
で用意する。
各曲線を構成する頂点数は異なっても構わない。 その場合、最大の頂点数を ntenmx、本数をnhon として、
real*4 x(ntenmx, nhon) real*4 y(ntenmx, nhon) real*4 z(ntenmx, nhon) real*4 c(ntenmx, nhon)
という配列を用意し、少ない頂点数の曲線には不要な頂点座標にダミーデータ を入れる。ダミーデータの値は、曲面データと同様に
999.0
を用いる。 以下に3本の曲線データを作るサンプルプログラムを示す。
+--------------------------------------------------------+ | 曲線データ生成プログラム例(Fortrn) 始まり implicit none integer ntenmx, nhon parameter(ntenmx=100,nhon=3) real*4 x(ntenmx,nhon),y(ntenmx,nhon),z(ntenmx,nhon) real*4 c(ntenmx,nhon) real*4 pi, twopi, theta, phase integer i,j character*50 xfile, yfile, zfile, cfile, v5file c xfile = "/home/guest/test/test-lines.x" yfile = "/home/guest/test/test-lines.y" zfile = "/home/guest/test/test-lines.z" cfile = "/home/guest/test/test-lines.c" v5file = "/home/guest/test/test-lines.v5" pi = atan(1.)*4 twopi = pi*2 c ... Define triple helix. do j = 1 , nhon phase = twopi / nhon * (j-1) do i = 1 , ntenmx theta = twopi*float(i-1)/ntenmx x(i,j) = 5.0*cos(theta + phase) y(i,j) = 5.0*sin(theta + phase) z(i,j) = 20.0 / ntenmx * (i-1) c(i,j) = 0.0 end do end do c ... The 3rd line is short. x(ntenmx/2,3) = 999. y(ntenmx/2,3) = 999. z(ntenmx/2,3) = 999. c(ntenmx/2,3) = 999. c ... Make binary data file open(11,file=xfile,form='unformatted') open(12,file=yfile,form='unformatted') open(13,file=zfile,form='unformatted') open(14,file=cfile,form='unformatted') write(11) x write(12) y write(13) z write(14) c close(14) close(13) close(12) close(11) c make text data file open(10,file=v5file) write(10,8000) "# vfive sample curve data" write(10,8001) "curveObj:nhon ", nhon write(10,8001) "curveObj:ntenmax ", ntenmx write(10,8002) "curveObj:xfile ", xfile write(10,8002) "curveObj:yfile ", yfile write(10,8002) "curveObj:zfile ", zfile write(10,8002) "curveObj:cfile ", cfile close(10) 8000 format(a) 8001 format(a, i5) 8002 format(a, a) stop end | 曲線データ生成プログラム例(Fortran) 終わり +--------------------------------------------------------+ |
+--------------------------------------------------------+ | 曲線データ生成プログラム例(C++言語) 始まり #include <stdio.h> #include <stdlib.h> #include <math.h> const int ntenmx = 100; const int nhon = 3; int main(int argc, char **argv){ float x[nhon][ntenmx],y[nhon][ntenmx],z[nhon][ntenmx]; float c[nhon][ntenmx]; double pi, twopi, theta, phase; int i,j; char xfile[] = "/home/guest/test/test-lines.x"; char yfile[] = "/home/guest/test/test-lines.y"; char zfile[] = "/home/guest/test/test-lines.z"; char cfile[] = "/home/guest/test/test-lines.c"; char v5file[] = "/home/guest/test/test-lines.v5"; pi = 3.14159; twopi = pi*2.0; // ... Define triple helix. for(j = 0; j < nhon; j++){ phase = twopi / nhon * j; for(i = 0; i < ntenmx; i++){ theta = twopi*(double)i/ntenmx; x[j][i] = 5.0*cos(theta + phase); y[j][i] = 5.0*sin(theta + phase); z[j][i] = 20.0 / ntenmx * i; c[j][i] = 0.0; } } // ... The 3rd line is short. x[2][ntenmx/2] = 999.; y[2][ntenmx/2] = 999.; z[2][ntenmx/2] = 999.; c[2][ntenmx/2] = 999.; // ... Make binary data file char dummy[4]; FILE *fp; if((fp=fopen(xfile,"wb")) == NULL){ fputs("Error\n",stderr); exit(1); } fwrite(dummy, 1, 4, fp); fwrite(&x[0][0], sizeof(float), ntenmx*nhon, fp); fclose(fp); ..........(略)......... // make text data file if((fp=fopen(v5file,"w")) == NULL){ fputs("Error\n",stderr); exit(1); } fprintf(fp, "# vfive sample curve data\n"); fprintf(fp, "curveObj:nhon %d\n", nhon); fprintf(fp, "curveObj:ntenmax %d\n", ntenmx); fprintf(fp, "curveObj:xfile %s\n", xfile); fprintf(fp, "curveObj:yfile %s\n", yfile); fprintf(fp, "curveObj:zfile %s\n", zfile); fprintf(fp, "curveObj:cfile %s\n", cfile); fclose(fp); return 0; } | 曲線データ生成プログラム例(C++言語) 終わり +--------------------------------------------------------+ |
VFIVEのメニューパネルで使用されているテクスチャデータの生成には、 核融合研のCOE研究員、 坂井豊一博士作成のプログラムを利用させていただいたことをここに記し、 感謝する。