2018年6月24日(日) 02:52 JST

パラメータバッファでN角柱 -GDLメモ vol.6

  • 2015年3月25日(水) 15:58 JST
  • 投稿者:

不定期記事とはいえ、前回のGDLメモからずいぶん間があいてしまいました。さて、先日紹介させていただいた、GDL教科書のkindle化にあたって、初級編である当教科書では割愛したトピックの記憶が蘇りましたので、ここ、GDLメモで紹介していきたいと思います。今回はパラメータバッファを題材にします。

パラメータバッファは配列型の内蔵データ構造です。その名のとおりパラメータのバッファなのですが、ここでいうパラメータとは所謂GDLオブジェクトのパラメータでなく、GDLコマンドの引数を指すのだと思います。コマンドの引数というのはコマンドに渡す変数のことですので、「BRICK 1, 2, 3」の「1, 2, 3」の部分にあたります。また、バッファとはコンピュータ用語で一時的なデータの保管場所を指しますので、パラメータバッファ≒一時的な引数(群)の置き場所、ということになるでしょうか。では、早速サンプルを見てみましょう。

PUT 1
PUT 2
PUT 3
BRICK USE( 3 )

ちょうどBRICKを例に出したので、このサンプルでは直方体をパラメータバッファを使って描いてみました。一行目の「PUT 1」のところで、パラメータバッファに値を格納しています。二行目、三行目も同じです。三行目までを「PUT 1, 2, 3」のようにカンマ区切りで格納することもできます。パラメータバッファは一つのGDLオブジェクトにつき一つという決まりのようですので、変数名がない点(言い換えれば、変数名を付けて区別する必要がない)に注意してください。

格納した値を使う際は、四行目のように「USE( 3 )」と記述をします。「( 3 )」は先頭から三つ使うという意味です。このように、いくつ使うというふうに数字で指定することもできますし、格納した値をあるだけ使うという場合は「( NSP )」と指定することもできます。また、パラメータバッファに格納した値を使う際、USEともう一つGETというコマンドがあります。こちらはUSEとは異なり、使った後に削除するというコマンドです。ちょっとおさらいを兼ねて、下記のようなコードを実行してみましょう。

PUT 1, 2, 3
PRINT NSP !!①
BRICK USE( NSP )
PRINT NSP !!②
ADDX 3
BRICK GET( NSP )
PRINT NSP !!③
ADDX 3
PUT 1, 2, 3
dummy = GET( 1 ) !!④
BRICK GET( 2 ), 4 !!⑤

①~③にてPRINTを使ってNSP、つまりパラメータバッファに格納している値の個数を出力しています。実行してみると①では3、②でも3、③では0と出力されるはずです。③では、直前のBRICKでUSEでなくGETを使っているので値を使った後に削除されているからです。また、コマンドに渡すのではなく、④のように適当なダミー変数にGET(1)で値を代入しても、同じく代入後に削除されます。ここでは先頭の「1」がdummyに代入(コピー)され、パラメータバッファから削除されます。続いて、⑤のBRICKでは、パラメータバッファの先頭から二つを使い、最後の引数は「4」を与えていますので、「BRICK 2, 3, 4」ということになります。三次元モデルもそのようになっているはずです。

以上のようにパラメータバッファでは、コマンドの引数(群)を格納しておき、USEないしGETを使ってまとめて渡す、といったことが可能です。では、パラメータバッファを使って正N角柱を描くスクリプトを作成してみましょう。下記のようになります。変数nの値を変えると、自由にN角柱を描くことができることを確かめておきましょう。

n = 12
r = 1 : h = 1
FOR i = 1 TO n
	PUT r * COS( i * 360 / n ),  r * SIN( i * 360 / n )
NEXT i

PRISM N, h, GET( NSP )

ところで、教科書の8章「他言語からGDLをつかう」では、地形のようなメッシュを生成するサンプルがあります。MESHコマンドでM×Nのメッシュを記述する際には、M×N個引数を渡す必要がありますが、このような場合もパラメータバッファは有効です。教科書のような自然地形をパラメータバッファを利用して記述すると下記のようになります。①のところで乱数を400個(xSize×ySize個)パラメータバッファに格納し、②のところでGET( NSP )して呼び出しています。

xLen = 100 : yLen = 100
xSize = 20 : ySize = 20

FOR i = 1 TO xSize
	FOR j = 1 TO ySize
		PUT RND( 2 ) + 4.0 !!①4.0から6.0の間の乱数 
	NEXT j
NEXT i

MESH xLen, yLen, xSize, ySize, 1 + 4 + 16 + 32, GET( NSP ) !!②

このように結構便利なパラメータバッファですが、やはりできない(やりにくい)こともあります。例えば、先のN角柱で、PRISMの後に同じくPLANEでN角形を描こうとすると、PRISMでは「x1, y1, x2, y2…」、PLANEでは「x1, y1, z1, x2, y2, z2…」と引数の並び方が違うので、そのままでは使えません。また、パラメータバッファは常に先頭からしか使えない、という決まりもあります。適所適コマンドといったところではありますがパラメータバッファ、覚えておいて損はないかと思います。