Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
3
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

Organization

POV-Rayでのアニメーションの作り方

はじめに

これは POV-Rayによる数学お絵かき入門 Advent Calendar 2017 の9日目の記事です.

今日の記事ではPOV-Rayでアニメーションを作る方法を述べます.

最初の例

POV-Rayではアニメーションを作るための変数clockが用意されています.
この変数を使うためにはコマンドライン引数に+KFFnを与えます. (nには自然数が入ります)
コマンドライン引数はpovray.iniに書けば良い(第3回)のでしたから, 例えば次のように書いてみましょう.

povray.ini
Width=400
Height=300
Antialias=On
+KFF11

このように設定してpovファイルをレンダリングすると, 11枚の連番画像が生成されます.
この連番画像の過程で変化しているパラメータがclockであり, デフォルトで$0$から$1$までに線形に変化します.
今回の例では連番最初でのclockの値は0.0であり, 順に0.1ずつ増えて連番最後では1.0の値になっています.

ここで具体例を1つ上げます.
次のコードをレンダリングすると連番画像が得られます.

clock1.pov
camera{
    location <4,2,4>
    look_at <0,0,0>
}
light_source{
    <2,3,4>
    color rgb<1,1,1>
}
background{rgb<1,1,1>}
sphere{<0,0,clock>,0.2}

次節で連番画像からgifアニメーションに変換方法を述べます.

gifアニメーションの作り方

gifアニメーションへの変換はImageMagicで出来ます.
今回の例ではコマンドラインで次のように入力します.

convert -delay 10 clock1*.png movie.gif

出力画像は次です.

Windowsであればgiamを使えばGUIで作成する事も可能です.

frame_number

ここでclockと同程度重要なframe_number, initial_frame, final_frameを次に紹介します.

  • frame_number : 連番画像毎に変わる変数.
  • initial_frame : 連番最初の番号. デフォルトで1.
  • final_frame : 連番最後の番号. KFFnで指定したn.

clockはデフォルトでは(frame_number-1)/(final_frame-initial_frame)に等しいです.

frame_numberの有用性は第15回に予定している2重振り子の作例が分り易いと思います.

他のパラメータやアニメーションのコマンドラインオプションに関する情報は以下にあります.
http://www.povray.org/documentation/3.7.0/r3_2.html#r3_2_1
http://www.povray.org/documentation/3.7.0/r3_3.html#r3_3_1_5

easing tips

easingとは物体の動きを自然に見せるの手法の事です.
例えば次のサイトが参考になると思います.
http://easings.net/ja

POV-Rayで作るアニメーションでは, 複数の動きを如何にして滑らかに繋ぐかが問題になります.
例えば以下の例では, パラメータに$\sin$を与えて滑らかに繋いでいます.

上の例のような単なる往復に関しては$\sin$で十分でしたが, 次のような複雑な動きを伴う場合にはそう上手く行きません.

(ちなみに, 上画像は$\sum k^3$の可視化です: http://hyrodium.tumblr.com/post/94237657514)

以下では大体の状況で使える便利な関数を紹介します.

\begin{align}
f(x)&=\begin{cases}e^{-\frac{1}{x}} &(x>0) \\0&(x\le 0)\end{cases} \\
g(x)&=\frac{f\left(\frac{2}{\sqrt{3}}x\right)}{f\left(\frac{2}{\sqrt{3}}x\right)+f\left(\frac{2}{\sqrt{3}}(1-x)\right)} \\
h_{(a,b)}(x)&=g\left(\frac{x-a}{b-a}\right)
\end{align}

これらの関数は次の性質があります.

  • $f\in C^\infty(\mathbb{R})$が成り立つ.
  • $g\in C^\infty(\mathbb{R})$は区間$[0,1]$で単調増加, $(-\infty, 0]$で常に$0$, $[1,+\infty)$で常に$1$を返す.
  • $h_{(a,b)}\in C^\infty(\mathbb{R})$は区間$[a,b]$で単調増加, $(-\infty, a]$で常に$0$, $[b,+\infty)$で常に$1$を返す.

Desmosで描いたグラフは次です.

https://www.desmos.com/calculator/6aymjmlpot

関数$g$での$\frac{2}{\sqrt{3}}$は変曲点で滑らかに繋ぐための係数です.

これをPOV-Rayのmacroで書けば次のようになります.

#macro smootha(a)
    #if(a>0)
        #local b=exp(-1/a);
    #else
        #local b=0;
    #end
    b
#end

#macro usmooth(a,b,s)
    smootha((2/sqrt(3))*((s-a)/(b-a)))/(smootha((2/sqrt(3))*((s-a)/(b-a)))+smootha((2/sqrt(3))*(1-(s-a)/(b-a))))
#end

このusmoothが上で定義した$h$に相当します.
関数$h$は区間$(a,b)$で単調増加でかつ, $a,b$において定数関数と滑らかに繋がっているため都合が良いという訳です.

具体例

上から順に

  • 等速運動
  • 単振動 (正弦関数 $\sin$)
  • usmooth

のアニメーションです.

この出力のためのコードは次です.

camera{
    orthographic
    location <0,0,10>
    right -3*x
    up 1.5*y
    sky y
    look_at <0,0,0>
}
light_source{
    <0,0,10>
    color rgb<1,1,1>
    parallel
    point_at 0
}
background{rgb<1,1,1>}

#macro smootha(a)
    #if(a>0)
        #local b=exp(-1/a);
    #else
        #local b=0;
    #end
    b
#end

#macro usmooth(a,b,s)
    smootha((2/sqrt(3))*((s-a)/(b-a)))/(smootha((2/sqrt(3))*((s-a)/(b-a)))+smootha((2/sqrt(3))*(1-(s-a)/(b-a))))
#end

#declare Time=2*clock;

sphere{<2*abs(Time-1)-1,0.5,0>,0.2}
sphere{<cos(pi*Time),0,0>,0.2}
sphere{<1-2*usmooth(0,1,Time)+2*usmooth(1,2,Time),-0.5,0>,0.2}
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
3
Help us understand the problem. What are the problem?