2018年9月26日(水) 06:34 JST

2015年度第3回GDL講習会

  • 2015年5月22日(金) 12:00 JST
  • 投稿者:
    ゲストユーザ

第3回は配列に座標点を格納し、図形を描画する練習をしました。FOR文・媒介変数を用いて関数曲線を表現できるようになり、プログラミングによるモデルの生成らしくなってきました。今回の課題は昨年のシェルコンテストの作品から一つと、アステロイドを変形してデルトイドを作ってもらいました。

images images

今回の講習では配列(DIM)とLIN_による線の描画コマンドを用いています。これらのコマンドについては、GDL教科書やKindle版に掲載されているので、こちらの記事では割愛させていただきます。また、シェルを作る際に基本となる球のモデリングやアステロイドについてはこちらをご覧ください。

四葉曲線

x = sin(2*θ)*cos(θ)
y = sin(2*θ)*cos(θ)
{0 < θ < 180}

上記の四葉曲線の式を基にして、四葉のクローバーのようなカタチを作成してもらいました。これは昨年のシェルコンテストの作品の一つです。このカタチのポイントは葉が中心に向かって収束している、ということです。半径と高さの関係だけでなく、平面座標と高さとの関係も配慮しなくてはなりません。

高さを正確にコントロールするために、曲線がどのような軌道で描かれるのかを理解する必要があるので、実際に配列に値を格納してLIN_で描いてみます。まずは、単純に球のように曲線の式のx,y座標にcosを、z座標にsinをかけて厚みを出してみます。

DIM x[][],y[][],z[]
FOR i = 1 to 36+1
	FOR j = 1 to 18+1
		theta = (j - 1)*10	!0~90°を10°刻み
		phi = (i - 1)*10
		x[i][j] = cos(phi)*sin(2*theta )*cos(theta)
		y[i][j] = cos(phi)*sin(2*theta)*sin(theta)
		z[i] = 0.1*sin(phi)
	NEXT j
NEXT i

FOR i = 1 to 36
	FOR j = 1 to 18
		LIN_ x[i][j], y[i][j], z[i], x[i+1][j], y[i+1][j], z[i+1]
		LIN_ x[i][j], y[i][j], z[i], x[i][j+1], y[i][j+1], z[i]
	NEXT j
NEXT i
images

中心でも高さのあるカタチとなっていることが分かります。そこで、phi=0の時にcos=0でsin=maxになっているところをcos=0の時もsin=0となる必要があるので、sinの周期を2倍にします。


z[i] = 0.1*sin(2*phi)

半径と高さの関係は整理できたので、次に平面座標と高さの関係を見るために曲線がどのようなタイミングで原点にくるのかを確認します。

DIM x[],y[]
FOR j = 1 to 18+1
	theta = (j - 1)*10	
	x[j] = sin(2*theta )*cos(theta)
	y[j] = sin(2*theta)*sin(theta)
NEXT j

FOR j = 1 to 9
	LIN_ x[j], y[j], 0, x[j+1], y[j+1], 0
NEXT j

FOR j = 1 to 18
	LIN_ x[j], y[j], 0, x[j+1], y[j+1], 0
NEXT j

images

このように、曲線は、0°から始まり90°ごとに曲線は原点に戻ってくることが分かります。このタイミングで高さ方向を"0"にするために、z座標にsin(2*theta)かけます。


z[i][j] = 0.1*sin(2*phi )*sin(2*theta)


images

これで四葉のクローバーの完成です。


デルトイド(内サイクロイド)

x = 2*cos(θ)+cos(2*θ)
y = 2*sin(θ)-sin(2*θ)

次にデルトイド(内サイクロイド)をモデリングしてもらいました。アステロイドの平面形状をデルトイドに変えるだけですが、うまくカタチにするのは難しく工夫が必要です。ポイントは位相をずらしてカタチを合わせることと、z方向に綺麗なカーブを出すというところです。

まずは、四葉曲線の時のように単純に曲線の式のx,y座標にcosを、z座標に関してはアステロイドと同様にsin^3をかけてみます。

FOR i = 1 to 36+1
	FOR j = 1 to 36+1
		theta = (j - 1)*10
		phi = (i - 1)*10
		x[i][j] = cos(phi)*(2*cos(theta)+cos(2*theta))
		y[i][j] = cos(phi)*(2*sin(theta)-sin(2*theta))
		z[i] = 6*sin(phi)^3
	NEXT j
NEXT i

FOR i = 1 to 18
	FOR j = 1 to 36
		LIN_ x[i][j], y[i][j], z[i], x[i+1][j], y[i+1][j], z[i+1]
		LIN_ x[i][j], y[i][j], z[i], x[i][j+1], y[i][j+1], z[i]
	NEXT j
NEXT i
images

すると、本来ならz座標の負の領域にできて欲しい部分も、正の領域にできてしまっています。そこで、phiの位相をπ/2ずらすことで、sinを(-1~1)の値で動かします。


phi = (i - 10)*10

images

正の領域で折り重なっていた部分が、負の領域にできてだいぶカタチが整ってきました。しかし、まだ胴長でz方向の綺麗なカーブが描けていません。形状をよく見ると、z座標の値が大きい部分のエッジが弱いことがわかります。これは、sinはπ/2~πの間では増加量が少ないためであると考えられます。そこで、sinを-π~π間ではなく-π/2~π/2で動かすように変更します。


z[i] = 6*sin(phi/2)^3


images

これで、デルトイドの完成です。今回の課題は難しかったかもしれませんが、自分の作りたい形のために元の関数に手を加えていく練習になったと思います。使う関数によっては一発で完成形を出すことが難しい場合がよくあります。そのような時は、今回のように自分のしたい操作を分けて考えてみると良いかもしれません。次回はシェルコンテストです。今回使った考え方などを参考に自分の作りたいシェルを完成させてみてください。