POV-Rayによる年賀状の製作


POV-Ray (フリーなレイトレーシングソフト)を用いた非常に簡単な年賀状用の絵の製作について。

2001年は蛇年だそうなので、球だけを用いて蛇のオブジェクト を作ってみます。
#以下では、global_setting、camera、light_source 等の設定を省略して書いています。

POV-Ray3.1 における球の構文は、次の通り。

sphere{
    <CENTER>, RADIUS
}
sphere球を指定
<CENTER>球の中心座標
RADIUS球の半径

例えば、原点<0, 0, 0>に半径 1の球を配置するには、

sphere{
    <0, 0, 0>,1
    texture{ pigment{ color rgb<0.4, 0.4, 1>} }
}


とします。textureは、物体の色や質感を指定するものです。 ここでは、非常に簡単に色の指定だけをRGBで行っています。

左図がレンダリング結果です。
次に、球をある曲線に従って連続的に配置することで複雑な 形状を作ります。
蛇っぽい曲線として、ここではア−クタンジェントを用いてみることにします。 ア−クタンジェントによる曲線は次図のようなものです。


球をy-z平面へ配置することにして、球の中心座標を関数 atan2(A, B)に 従って変化させます。
atan2(A, B)は、ア−クタンジェントA/Bを表し、角度をラジアンで返す関数です。 y-z平面でのア−クタンジェントによる曲線は Z = atan2(Y, 1) となります。
POV-Ray では、#declare によってパラメータとしての 識別子を宣言でき、さらに繰り返し文としては #while を用いることができるようです。
以下の例では、変数yの範囲を-5 <= y <= 5 とするために、パラメーターYLENを導入してます。

#declare COUNTS = 0;
#declare CMAX = 100;
#declare YLEN = 10;
#while(COUNTS <= CMAX)
    #declare X = 0;
    #declare Y = ((COUNTS / CMAX) - 0.5) * YLEN; 
    #declare Z = atan2(Y, 1);
    sphere{
        <X, Y, Z>,0.3
        texture{ pigment{ color rgb<0.4, 0.4, 1>} }
    }
    #declare COUNTS = COUNTS + 1;
#end

レンダリングを実行したものが次図。



次に、蛇の頭として最後の球だけ少し大きくし、 scale で一方向に引き延ばして回転楕円体にします。
さらに"エラブ海蛇"っぽく黒と水色のまだらにするために、適当な パラメーターを導入して、黒と水色の球が入り乱れるようにします。

#declare COUNTS = 0;
#declare CMAX = 100;
#declare YLEN = 10;
#declare FAC1 = 7;
#declare FAC2 = 13;
#declare CRI = 1;

#while(COUNTS <= CMAX)
    #declare X = 0;
    #declare Y = ((COUNTS / CMAX) - 0.5) * YLEN; 
    #declare Z = atan2(Y, 1);
    #if(mod(COUNTS, FAC1) = 0)
        #declare CRI = 1;
    #end
    #if(mod(COUNTS, FAC2) = 0)
        #declare CRI = 0;
    #end
    sphere{
        <X, Y, Z>,0.3
        #if(CRI)
            texture{ pigment{ color rgb<0.4, 0.4, 1> } }
        #else
            texture{ pigment{ color rgb<0.25, 0.25, 0.25> } }
        #end
    }
    #if(COUNTS = CMAX)
    sphere{
        <0, 0, 0>,0.5
        texture{ pigment{ color rgb<0.4, 0.4, 1> } }
        scale<1, 1.6, 1>
        translate <X, Y, Z>
    }
    sphere{
        <X + 0.5, Y + 0.1, Z + 0.2>,0.15
        texture{ pigment{ color rgb<1.0, 0, 0>} }
    }
    sphere{
        <X - 0.5, Y + 0.1, Z + 0.2>,0.15
        texture{ pigment{ color rgb<1.0, 0, 0>} }
    }
    #end
    #declare COUNTS = COUNTS + 1;
#end

レンダリングを実行したものが次図。



以上は、100個の黒または水色の球と1個の回転楕円体と2個の赤い球 を配置したものなのですが、後々のために これらを CSG(Constructive Solid Geometry)と呼ばれる集合演算の一つ "ユニオン(ブール和)" でひとまとめにして名前を付けておきます。

#declare COUNTS = 0;
#declare CMAX = 100;
#declare YLEN = 10;
#declare FAC1 = 7;
#declare FAC2 = 13;
#declare CRI = 1;

#declare Snake_1 = union{
    #while(COUNTS <= CMAX)
        #declare X = 0;
        #declare Y = ((COUNTS / CMAX) - 0.5) * YLEN; 
        #declare Z = atan2(Y, 1);
        #if(mod(COUNTS, FAC1) = 0)
            #declare CRI = 1;
        #end
        #if(mod(COUNTS, FAC2) = 0)
            #declare CRI = 0;
        #end
        sphere{
            <X, Y, Z>,0.3
            #if(CRI)
                texture{ pigment{ color rgb<0.4, 0.4, 1> } }
            #else
                texture{ pigment{ color rgb<0.25, 0.25, 0.25> } }
            #end
        } 
        #if(COUNTS = CMAX)
        sphere{
            <0, 0, 0>,0.5
            texture{ pigment{ color rgb<0.4, 0.4, 1> } }
            scale<1, 1.6, 1>
            translate <X, Y, Z>
        }
        sphere{
            <X + 0.5, Y + 0.1, Z + 0.2>,0.15
            texture{ pigment{ color rgb<1.0, 0, 0>} }
        }
        sphere{
            <X - 0.5, Y + 0.1, Z + 0.2>,0.15
            texture{ pigment{ color rgb<1.0, 0, 0>} }
        }
        #end
        #declare COUNTS = COUNTS + 1;
    #end
}

これ以後は、

object{
    Snake_1
    translate<0, 10, 10>
}

とすることで、先ほど宣言した蛇のオブジェクトを好きな 位置に配置することが できます。
translate は平行移動のための命令で、この例では 原点にあった蛇のオブジェクトを、<0, 10, 10>の 位置に移動させます。

次に蛇を使って"2001"という文字を書いてみるために、 次のように少し違う形状の蛇を同様にして宣言します。




あとは、ひたすら translate(平行移動)とrotate(回転)を使いながら所定の位置に蛇を配置してゆきます。
最後に変化をつけるため、一匹だけ顔を持ち上げている蛇を作って、 メッセージ用の吹き出しを書いてやります。
地面には、石のtextureを定義した"stones.inc"を利用して、出来上がりです。
アニメーションエラブウミヘビは こちら




参考サイト