その3 "while" を使って、ズラリとモノを並べてみよう!
POV-Rayのプログラミング言語も、CやFortranのような言語と同じように、ループや条件文なんかがあります。これらをちょっと使っただけでも、けっこう面白い作品ができます。今回はこのうちループ文を使って、ズラリとモノを並べてみましょう。といっても何も難しいことはなくて、次のようにするだけです。たとえば "J" という変数を、1から8まで変化させるためのループは、POV-RAYでは次のように記述します。
#declare J=1;
#while(J<=8):
#declare J=J+1;
#endちょっとCやFortranをかじったことのある人ならなんとなく大丈夫だとおもうので、さっそくやってみましょう!前の章までにつくった.povファイルに上記の "while" 命令を加えて、ボールが8個ならんだシーンを作ってみます。赤字の部分が、変更した箇所です。(左がソースファイル、右はレンダリングの結果)
#include "colors.inc" light_source { <-20, 50, -20>, color White*2 } camera{ location <-20,15,0> look_at <0,0,0> } #declare J=1; #while(J<=8) sphere{ <0,0,0>,1.5 texture{ pigment{color Blue} finish{ phong 0.4 reflection 0.2 } } translate<0,0,4*(J-4.5)> // 球をz軸方向に4x(J-4.5)だけ移動 } #declare J=J+1; #end plane{ <0,1,0>,-1.5 texture{ pigment{ checker color Black White scale 4.0 } finish{ phong 0.2 reflection 0.4 } } }
"translate<x,y,z>" は、オブジェクトを<x,y,z>だけ移動させる命令です。単純ですがPOV-RAYをやるうえでは、もうしょっちゅう使います。
オブジェクトを移動させる命令は、ほかにも "rotate<q,f,j>" というのもあります。これは、x軸のまわりにq度、y軸のまわりにf度、z軸のまわりにj度、それぞれ回転させるという命令で、こちらもしょっちゅう使います。たとえば "rorate" を使うと、ボールを円状にならべることもできます。
#include "colors.inc" light_source { <-20, 50, -20>, color White*2 } camera{ location <-20,15,0> look_at <0,0,0> } #declare J=1; #while(J<=8) sphere{ <0,0,0>,1.5 texture{ pigment{color Blue} finish{ phong 0.4 reflection 0.2 } } translate<8,0,0> rotate<0,360/8*J,0> } #declare J=J+1; #end plane{ <0,1,0>,-2 texture{ pigment{ checker color Black White scale 4.0 } finish{ phong 0.2 reflection 0.4 } } }
"translate" と "rotate" がいっしょくたになっててちょっとややこしいですが、右図のように考えるとわかりやすいと思います。要は円周の半径分だけ "translate" で移動させて、"rotate" で原点まわりに回転させてる、ということですね。
"translate" と "rotate" の組み合わせは、何度もいろいろと遊んでるうちにコツみたいなものがつかめてきますから、ぜひ、いろいろとチャレンジしてみてください!
さて、ループ変数 "J" は、なにも "translate" や "rotate" だけじゃなくて、ほかにもいろいろとできます。たとえばオブジェクトの色を指定する rgb や rgbt を、数値で指定していたことを思い出すと、こんなこともできちゃいます。
#include "colors.inc" light_source { <-20, 50, -20>, color White*2 } camera{ location <-20,15,0> look_at <0,0,0> } #declare J=1; #while(J<=16) sphere{ <0,0,0>,1.5 texture{ pigment{color rgbt<0,0,1,1/15*(J-1)>} finish{ phong 0.4 reflection 0.2 } } translate<8,0,0> rotate<0,360/16*J,0> } #declare J=J+1; #end plane{ <0,1,0>,-2 texture{ pigment{ checker color Black White scale 4.0 } finish{ phong 0.2 reflection 0.4 } } }ここでは rgbt の透明度の値をループ変数 "J" で制御して、だんだんとフェードアウトしていくようにしています。このへんの命令をうまく使うと、POV-RAYのアニメーション機能と組み合わせて映画「マトリックス」のあの場面がつくれそうな気がします(だれかやってくれないかなぁ...)。
とうぜん、色指定を "J" で制御すると、またちょっと雰囲気のちがった作品ができます。ちょっとやってみると・・・
#include "colors.inc" light_source { <-20, 50, -20>, color White*2 } camera{ location <-20,15,0> look_at <0,0,0> } #declare N1=16; #declare J=1; #while(J<=N1) sphere{ <0,0,0>,1.5 texture{ pigment{ color rgb<0.5*(1+sin(2*pi/N1*J)),0.5,0.5*(1+cos(2*pi/N1*J))> } finish{ phong 0.4 reflection 0.2 } } translate<8,0,0> rotate<0,360/N1*J,0> } #declare J=J+1; #end plane{ <0,1,0>,-2 texture{ pigment{ checker color Black White scale 4.0 } finish{ phong 0.2 reflection 0.4 } } }
最後に、"while" ループを2重に重ねて、"translate" と "rotate" をうまく使うと、こんなこともできるという簡単な例を示します。一見ちょっと複雑に見えますが、"translate" と "rotate" での動きさえわかれば、やってること自体は見た目ほど複雑ではありません。
#include "colors.inc" light_source { <-20, 50, -20>, color White*2 } camera{ location <-20,15,0> look_at <0,0,0> } #declare N1=32; #declare N2=8; #declare K=1; #while(K<=N2) #declare J=1; #while(J<=N1) sphere{ <0,0,0>,0.5 texture{ pigment{ color rgb<0.5*(1+sin(2*pi/N1*J+0.05*(K*N1+J))),0.8,0.5*(1+cos(2*pi/N1*J))> } finish{ phong 0.4 reflection 0.2 } } translate<2,0,0> rotate<0,360/N1*J,0> translate<0,0,6> rotate<360/(N2*N1)*(K*N1+J),0,0> rotate<0,30,-60> translate<0,1,0> } #declare J=J+1; #end #declare K=K+1; #end plane{ <0,1,0>,-8 texture{ pigment{ checker color Black White scale 4.0 } finish{ phong 0.2 reflection 0.4 } } }
さて、次回はちょっと趣向をかえて、あまり他では書かれていない、POV-RAYで作品をつくるときのちょっとした工夫(?)を書いてみたいとおもいます。おたのしみに!
(つづく)