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
0
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

はじめに

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

これまでに説明したように, POV-Rayでは次のようにオブジェクトを宣言できるのでした.

#declare obj1=box{<0,0,0>,<1,1,1>}

しかし, obj1の色を後から変更したい/色を変えて複数並べたい場合の方法はまだ記述していませんでした.

今日はこの事について書きます.

公式ドキュメントでは以下が近いです.
http://www.povray.org/documentation/3.7.0/r3_4.html#r3_4_5
http://www.povray.org/documentation/3.7.0/r3_3.html#r3_3_1_12

object

これを実現するためにはobjectを使います.

#declare obj1=box{<0,0,0>,<1,1,1>}
object{
    obj1
    pigment{rgb<1,0,0>}
}

このようにobject{}内の引数としてオブジェクトを取り, 省略可能な引数としてpigmentなども与えられます.

objectは何度重ねても問題ありませんが, 次のように書けばpigmentが上書きされます.
pigmentを上書きさせないためにはunionを使います. (後述)

#declare obj1=box{<0,0,0>,<1,1,1>}
object{
    object{
        obj1
        pigment{rgb<1,0,0>}
    }
    pigment{rgb<0,1,0>}
}

transformation

POV-Rayにはオブジェクトの移動や変形に関する命令も用意されています.
こちらもobjectを使います.

scale

原点中心の拡大縮小にはscaleを使います.
scaleの挿入位置はpigmentと基本的には同じで, 次のように書きます.

object{
    OBJECT
    scale <VECTOR>
}

ここで<VECTOR>には3次元のベクトルが入り, それぞれの成分が$x, y, z$方向の伸縮に対応します.
以前述べたようにPOV-Rayではベクトルの代わりに数値を入れる事も可能でしたから, その場合は単なる原点中心の相似拡大縮小となります.

具体例

次の例では, 座表軸の向きが分り易いように3つのcylinderを配置しています.

#declare obj2=box{<.1,.1,-.1>,<.9,.9,-.9>}

object{
    obj2
    pigment{rgb<1,0,0>}
}
object{
    obj2
    scale 1.5
    pigment{rgb<0,1,0>}
}

cylinder{<0,0,0>,<1,0,0>,0.1 pigment{rgb<1,0,0>}}
cylinder{<0,0,0>,<0,1,0>,0.1 pigment{rgb<0,1,0>}}
cylinder{<0,0,0>,<0,0,1>,0.1 pigment{rgb<0,0,1>}}

translate

平行移動のための命令がtranslateです.
構文は上記sacleと同様で, <VECTOR>で指定したベクトルで平行移動します.

具体例

#declare obj2=box{<.1,.1,-.1>,<.9,.9,-.9>}

object{
    obj2
    pigment{rgb<1,0,0>}
}
object{
    obj2
    translate <0,0,1>
    pigment{rgb<0,1,0>}
}

cylinder{<0,0,0>,<1,0,0>,0.1 pigment{rgb<1,0,0>}}
cylinder{<0,0,0>,<0,1,0>,0.1 pigment{rgb<0,1,0>}}
cylinder{<0,0,0>,<0,0,1>,0.1 pigment{rgb<0,0,1>}}

rotate

$x,y,z$軸周りの回転を表す命令がrotateです.
構文もやはり上記と同様なのですが,

  • 角度が度数法で指定されること
  • $SO(3)$が非可換であること

に注意が必要です.

具体例

まずは簡単な例を述べましょう.

#declare obj2=box{<.1,.1,-.1>,<.9,.9,-.9>}

object{
    obj2
    pigment{rgb<1,0,0>}
}
object{
    obj2
    rotate <45,0,0>
    pigment{rgb<0,1,0>}
}

cylinder{<0,0,0>,<1,0,0>,0.1 pigment{rgb<1,0,0>}}
cylinder{<0,0,0>,<0,1,0>,0.1 pigment{rgb<0,1,0>}}
cylinder{<0,0,0>,<0,0,1>,0.1 pigment{rgb<0,0,1>}}

このように, 変形後のオブジェクト(緑色)が$x$軸(赤色)周りに$45^\circ$回転しています.

さて, 前に少し触れましたが, POV-Rayではデフォルトで左手系なので, 少し紛らわしい例になっていました.
右手系に変更する話は次回とします.

SO(3)の非可換性

<VECTOR>で指定したベクトルを回転軸としてオブジェクトが回転される訳ではありません.

次の2つのrotateの例はPOV-Rayでは等価に解釈されます.

object{
    OBJECT
    rotate <a,b,c>
}
object{
    OBJECT
    rotate <a,0,0>
    rotate <0,b,0>
    rotate <0,0,c>
}

つまり, POV-Rayでは$x$軸の回転→$y$軸の回転→$z$軸の回転と順に行います.
そのため, コードの可読性を考えればrotateを使う際には標準基底の定数倍を指定する方が良いです.

また, POV-Rayではx, y, zがそれぞれ<1,0,0>, <0,1,0>, <0,0,1>を表す組み込み定数として扱われるため, 次にようにも書けます.

object{
    OBJECT
    rotate a*x
    rotate b*y
    rotate c*z
}

matrix

以上ではscale, translate, rotateの3つの変形を扱いましたが, これらを含む最も一般的な変形(アフィン変換)がmatrixです.
数式で書けば

\begin{align}
    \begin{pmatrix}
    x' \\
    y' \\
    z'
    \end{pmatrix}
    =
    \begin{pmatrix}
    a_1 &b_1 &c_1 \\
    a_2 &b_2 &c_2 \\
    a_3 &b_3 &c_3 \\
    \end{pmatrix}
    \begin{pmatrix}
    x' \\
    y' \\
    z'
    \end{pmatrix}
    +
    \begin{pmatrix}
    d_1 \\
    d_2 \\
    d_3
    \end{pmatrix}
\end{align}

を表す変形で, POV-Rayでは次のように書きます.

object{
    OBJECT
    matrix <a1, a2, a3,
    b1, b2, b3,
    c1, c2, c3,
    d1, d2, d3>
}

union

複数のオブジェクトをまとめて

  • 色の変更
  • 移動, 変形

をするためにはunionを使います.
unionは複数のオブジェクトをまとめて扱うための命令で, 次のように書きます.

union{
    OBJECT1
    OBJECT2
    ..
    OBJECTn
}

具体例

#declare obj1=box{<0,0,0>,<1,1,1>}

union{
    object{obj1 pigment{rgb<0,1,0>}}
    object{obj1 pigment{rgb<0,0,1>} translate <0.2,0.2,-0.2>}
    object{obj1 translate <-0.2,-0.2,0.2>}
    pigment{rgb<1,0,0>}
}

この例ではunionで3つのオブジェクトを1つにまとめてpigmentで着色しています.
unionの内側で予め色が指定されている場合は外側のpigment{rgb<1,0,0>}で色は変更されませんが, 色が未定義となっている3つ目のオブジェクトには赤色が着色されています.

pigmentと同様に変形の指定をここで行う事も可能です.

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
0
Help us understand the problem. What are the problem?