2025年1月20日(月) 04:38 JST

2014年度第3回GDL講習会

  • 2014年5月 4日(日) 09:20 JST
  • 投稿者:
    ゲストユーザ

第3回 配列と媒介変数

第3回の講習では配列に媒介変数を用いて値を格納し、図形を描画する練習をしました。今回学んだことを使えば自由なメッシュ曲面を作成することができるようになります。これまでのような単純にコマンドからのモデルの生成でなく、徐々にプログラミングらしくなってきました。課題は昨年のシェルコンテスト作品から紹介します。 去年と重複する部分もございますので、こちらのページもご覧ください。



今回の講習では、配列を作成するDIMコマンドやそれを描画するためにLIN_コマンドやPLANEコマンドを扱いました。

DIM x[], y[], z[]

DIMコマンドは配列を宣言して、値を格納する箱を作成することができます。ただしこの配列の添え字は1以上となっており、 0番目の配列は存在しません。 そのため描画時に終点の結び方を工夫しなければいけません。この次の例で解説します。

LIN_ x1, y1, z1, x2, y2, z2 

LIN_コマンドは始点と終点のxyz座標を渡すことでその間に線を描画することができるコマンドです。 またPEN (数字) で描画する線の色を変えることができます。

PLANE n, x1, y1, z1, x2, y2, z2, x3, y3, z3, …

PLANEコマンドは頂点数と座標を渡してその頂点で結ばれる面を描画するコマンドです。 平面を作成するとき、同一平面上に座標点は存在しなければならないため三角形面で描画することが多いです。
DIMコマンドで配列を作成してそこに値を格納します。しかしそのままでは数値は配列の中に入っていますが、グラフィックとして描画はされていません。 そこでLIN_コマンドやPLANEコマンドを扱って格納した点を結んで図形を描画していきます。

SPHERE

例として単純な球を扱いましょう。

球の媒介変数は
x = COS( θ ) * COS( φ )
y = COS( θ ) * SIN( φ )
z = SIN( θ )
{0 <=θ<= 2π}
{0 <=φ<= π}
となります。

以下のコードを見ると、配列への格納と、描画に分かれていることがわかると思います。配列へ格納は基本的にこのような操作になっています。 格納時と描画時のFOR文のループ数が異なっているのは、LIN_コマンドではある点とその次の点を描画しているので同じ回数回すと最後の点が 格納されていない配列を参照することになるのを避けるためです。 また描画時の負担を下げるために分割数を減らしています。LIN_のつなぎ方を変えることでさまざまに描画できます。
dim x[][],y[][],z[][]		!!配列の宣言
div = 10			!!描画する線の密度(1のとき最高)
deg = 180


!!配列への値の格納
for i=1 to 2*deg/div +1
	for j=1 to deg/div + 1
		x[ i ][ j ] = cos( div * i )*cos(div * j)
		y[ i ][ j ] = cos( div * i )*sin(div * j)
		z[ i ][ j ] = sin( div * i )
	next j
next i

!!描画
for i=1 to 2*deg/div
	for j=1 to deg/div
		lin_ x[i][j],y[i][j],z[i][j],x[i+1][j],y[i+1][j],z[i+1][j]	!!経線
		lin_ x[i][j],y[i][j],z[i][j],x[i][j+1],y[i][j+1],z[i][j+1]	!!緯線
	next j
next i

球を少し変えて金平糖のような形状を作ってみましょう。

先ほどの球の式に( 1 + (cos(a*n) + sin(a*m))/hida_h)  という項をかけてみると、球の表面が波打つようになります。このように簡単な調整で形状を大きく 変えることができるので、様々に試してみると面白いモデルが作れるかもしれません。このモデルは昨年のシェルコンテストの優勝作品を参考に作成しました。 面をPLANEコマンドで張るとき、三点が破綻なく結べなければならないため、結ぶ順番をよく考慮しなければなりません。
dim x[][],y[][],z[][]	!!配列の宣言
div = 3				!!描画する線の密度(1のとき最高)
a = 12 : b = 12 	!!ひだの数
sphere_r = 100	!!球の直径
hida_h = 10		!!ひだの高さ
deg = 180


!!配列への値の格納
for i=1 to 2*deg/div +1
	for j=1 to deg/div+1
		n = div * (i-1) : m = div * (j-1)
		x[ i ][ j ] = sphere_r * ( 1 + (cos(a*n) + sin(a*m))/hida_h) *sin(n)*cos(m)
		y[ i ][ j ] = sphere_r * ( 1 + (cos(a*n) + sin(a*m))/hida_h) *sin(n)*sin(m)
		z[ i ][ j ] = sphere_r * ( 1 + (cos(a*n) + sin(a*m))/hida_h) *cos(n)
	next j
next i

!!線の描画
for i=1 to 2*deg/div
	for j=1 to deg/div
		lin_ x[i][j],y[i][j],z[i][j],x[i+1][j],y[i+1][j],z[i+1][j]
		lin_ x[i][j],y[i][j],z[i][j],x[i][j+1],y[i][j+1],z[i][j+1]
	next j
next i

!!面の描画
for i=1 to (deg/div)-1
	for j=1 to (deg/div)
	PLANE 3,
	x[i][j],y[i][j],z[i][j],
	x[i+1][j],y[i+1][j],z[i+1][j],
	x[i+1][j+1],y[i+1][j+1],z[i+1][j+1]
	next j
next i

for i=2 to (deg/div)
	for j=1 to (deg/div)
	PLANE 3,
	x[i][j],y[i][j],z[i][j],
	x[i+1][j+1],y[i+1][j+1],z[i+1][j+1],
	x[i][j+1],y[i][j+1],z[i][j+1]
	next j
next i
次にアステロイド曲線を用いたものをモデリングしてみましょう。 媒介変数を用いた図形には面白い形状がいろいろとあります。媒介変数を変えて面白い形状や曲面を作成してみてください。

DIM x[][],y[][],z[][]
deg = 360
div = 5
FOR i=1 to deg/div + 1
	FOR j=1 to deg/div + 1 
		x[i][j]=sin(div*i)^3*cos(div*j)^3
		y[i][j]=cos(div*i)^3*cos(div*j)^3
		z[i][j]=sin(div*j)^3
	NEXT j
NEXT i

FOR i=1 to deg/div
	FOR j=1 to deg/div
		LIN_ x[i][j],y[i][j],z[i][j],x[i+1][j],y[i+1][j],z[i+1][j]
		LIN_ x[i][j],y[i][j],z[i][j],x[i][j+1],y[i][j+1],z[i][j+1]
	NEXT j
NEXT i

いよいよ次回はシェルコンテストです。自分の作品を人に見てもらうことはとてもいい機会ですので受講生の皆さんはがんばりましょう。

以下のコメントは、その投稿者が所有するものでサイト管理者はコメントに関する責任を負いません。