集合演算
CGで立体形状を記述する方法にCSG(Constructive Solid Geometry)と呼ばれる方法があります。ここでは、様々な立体を組み合わせて新しい形状をつくっていきましょう。
以下では、円柱と立方体を利用して集合演算を行います。
和集合
和集合では、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はオブジェクト内部の境界線が取り除かれることです。透明な物体では、こちらの方が自然な画像になりますね。以下にコードとunionとmergeの違いを画像で表しています。
#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}
積集合
積集合では、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}