カテゴリー
POV-Ray

POV-Ray(Step2-2)

集合演算

CGで立体形状を記述する方法にCSG(Constructive Solid Geometry)と呼ばれる方法があります。ここでは、様々な立体を組み合わせて新しい形状をつくっていきましょう。

以下では、円柱と立方体を利用して集合演算を行います。

円柱(Disk_Y)
立方体(Cube)

和集合

和集合では、2つのオブジェクトを1つにしたものが新しい形状として出来上がります。和集合にはunionという命令を使います。記述は以下のようになります。

union{
 物体A
 物体B
  ・
 ・
 ・
}

このunion命令を使って和集合をつくってみましょう。以下がコードになります。

#include "colors.inc"  
#include "shapes.inc"


camera{
    location<0, 3, -8>   
    look_at<0, 0, 0>
    angle 60 
}

light_source{
    <0, 10, -10>
    color rgb<1,1,1>    
    
}   
       

union{
    object{
        Disk_Y
        pigment{color Blue}
    }
    
    object{
        Cube
        rotate 45*x
        rotate 45*y
        pigment{color Red}
    }
}

background{color White}

ここでは、画像の背景を白くするために、最後にbackground{color White}を記述しています。また、1つのオブジェクトになったので、以下のようにコードを書き換えると、命令1つで、移動や拡大を行うことができるようになります。

union{
    object{
        Disk_Y
        pigment{color Blue}
    }
    
    object{
        Cube
        rotate 45*x
        rotate 45*y
        pigment{color Red}
    }  
    translate<1,0,0> //変更箇所
}

union命令と同じように、2つ以上のオブジェクトを1つにする命令としてmergeがあります。違いとしては、mergeはオブジェクト内部の境界線が取り除かれることです。透明な物体では、こちらの方が自然な画像になりますね。以下にコードとunionmergeの違いを画像で表しています。

#include "colors.inc"  
#include "shapes.inc"  
#include "glass.inc"


camera{
    location<0, 3, -6>   
    look_at<0, 0, 0>
    angle 60 
}

light_source{
    <0, 10, -10>
    color rgb<1,1,1>    
    
}   
       
merge{
    object{
        Sphere
        translate<0.5,0,0>
        texture{T_Glass1}
        interior{I_Glass}
      
    }
    
    object{
        Sphere
        translate<-0.5,0,0>
        texture{T_Glass1}
        interior{I_Glass}
    }  
}

background{color White}
merge命令による形状
union命令による形状

積集合

積集合では、2つのオブジェクトの重なった部分が新しい形状となります。積集合はintersection命令を使います。

intersection{
 物体A
 物体B
  ・
 ・
 ・
}

次にintersection命令で、積集合をつくってみましょう。以下がコードになります。

#include "colors.inc"  
#include "shapes.inc"


camera{
    location<0, 3, -8>   
    look_at<0, 0, 0>
    angle 60 
}

light_source{
    <0, 10, -10>
    color rgb<1,1,1>    
    
}   
       

intersection{
    object{
        Disk_Y
        pigment{color Blue}
    }
    
    object{
        Cube
        rotate 45*x
        rotate 45*y
        pigment{color Red}
    }
}

background{color White}

intersection命令でも、複数のオブジェクトを1つの形状で扱えるので、translate命令等で扱うことができます。

差集合

差集合では、2つのオブジェクトの重なった部分を取り除いた形状になります。命令はdifference命令を用います。この命令では、最後に記述したオブジェクトから2番目に記述したオブジェクトを削り取った形状が得られます。物体に穴を開ける時などに使えます。

difference{
 物体A
 物体B
  ・
 ・
 ・
}

difference命令で、差集合を作りましょう。以下がコードと実行結果になります。また、命令内の記述する順序を変えると結果が変わってきますので、合わせてその結果も記しておきます。

#include "colors.inc"  
#include "shapes.inc"


camera{
    location<0, 3, -8>   
    look_at<0, 0, 0>
    angle 60 
}

light_source{
    <0, 10, -10>
    color rgb<1,1,1>    
    
}   
       

difference{
    object{
        Disk_Y
        pigment{color Blue}
    }
    
    object{
        Cube
        rotate 45*x
        rotate 45*y
        pigment{color Red}
    }
}

background{color White}
差集合実行結果
差集合の順序を変えた結果

複雑な図形をつくる

ここまでは、集合演算を一種類だけ行う場合を説明してきましたが、複数の集合演算を組み合わせて複雑な形を作ることも出来ます。以下の画像のようなコップを作るにはどうしたらいいでしょうか?順序よく見ていきましょう。

まずは、筒の部分に注目しましょう。水色の筒の中がくり抜かれているのがわかると思います。そこで、differenceを使ってこの形を作ってみましょう。

difference{
    
        object{
            Disk_Y
            pigment{color Cyan}
        } 
    
        object{
            Disk_Y  
            scale 0.9
            pigment{color Yellow}  
            translate<0,0.4,0>
        }
    }    

次に取手部分です。この形に使えそうなのは何でしょうか?円環ですよね。これを半分にしたら、取手として使えるではないですか。 differenceを使って次にこの形を作ってみましょう。

difference{

        object{
            torus{1,0.2}  
            scale 0.5
            pigment{color Cyan}  
            rotate<90,0,90>
            translate<-1,0.1,0>
        }  
    
        object{
            Disk_Y
            pigment{color Cyan}
        } 
 
    }

最後にこれを合体して1つのオブジェクトにしましょう。unionで1つにまとめましょう。これで、1つの形状として動かすこともできるようになります。以下が全コードになるので、実行して確認してみましょう。

#include "colors.inc"  
#include "shapes.inc"


camera{
    location<0, 5, -5>   
    look_at<0, 0, 0>
    angle 60 
}

light_source{
    <0, 10, -10>
    color rgb<1,1,1>    
    
}   


union{
       
    difference{
    
        object{
            Disk_Y
            pigment{color Cyan}
        } 
    
        object{
            Disk_Y  
            scale 0.9
            pigment{color Yellow}  
            translate<0,0.4,0>
        }
    
 
    }   

    difference{

        object{
            torus{1,0.2}  
            scale 0.5
            pigment{color Cyan}  
            rotate<90,0,90>
            translate<-1,0.1,0>
        }  
    
        object{
            Disk_Y
            pigment{color Cyan}
        } 
 
    }
}

background{color White}