Obsah
1. Použití konstruktivní geometrie těles v praxi
2. Popis operací sjednocení, sloučení, průniku a rozdílu
3. Základní demonstrační scéna
4. Demonstrační příklad sjednocení (union) dvou těles
5. Demonstrační příklad sloučení (merge) dvou těles
6. Demonstrační příklad průniku (intersection) dvou těles
7. Demonstrační příklad rozdílu (difference) dvou těles
8. Kombinace sjednocení a rozdílu při tvorbě složitého tělesa pomocí CSG
9. Obsah následující části seriálu
1. Čtyři základní operace CSG
V předchozí části tohoto seriálu jsme si popsali základy takzvané konstruktivní geometrie těles (CSG – Constructive Solid Geometry. Pomocí této poměrně vyspělé a přitom snadno použitelné modelovací techniky je možné vytvářet různé typy modelů, především umělé (technické) objekty a artefakty. Dnes si na několika demonstračních příkladech ukážeme, jakým způsobem je možné konstruktivní geometrii těles použít v praxi, a to i bez pomoci modelovacího programu s grafickým uživatelským rozhraním. První demonstrační příklady budou poměrně jednoduché – bude se vždy jednat o dvě základní geometrická tělesa zkombinovaná pomocí množinových operací – ale ukážeme si také dva příklad složitější, ve kterém bude ukázán způsob vytvoření přesného modelu ventilu pomocí zdrojového kódu, jehož velikost nepřesáhne 3 kB. Druhý složitější příklad posloužil k vytvoření rozříznutého modelu kuličkového ložiska.

Z teorie množin známe několik množinových operací, mezi něž patří především sjednocení, průnik, rozdíl a doplněk množiny. Konstruktivní geometrie těles je sice založena na teorii množin, ovšem sada dostupných operací je poněkud odlišná. V dalším textu se zaměříme především na program POV-Ray a jeho specifika. V něm jsou implementovány čtyři CSG operace. Tyto operace je možné provádět pouze nad tělesy, u nichž je jasně definován jejich vnitřek a vnějšek. To je případ uzavřených těles (ty jsme si popsali minule – jedná se o kvádr, kouli, válec, kužel a toroid), implicitních ploch, superelipsoidů (budou popsány v dalším pokračování tohoto seriálu) a překvapivě také nekonečného tělesa „poloprostor“, což není nic jiného než rovina s normálovým vektorem, který určuje, která část prostoru patří dovnitř a která vně. Oněmi čtyřmi základními operacemi použitelnými v POV-Rayi jsou:
- sjednocení (union) dvou či více těles
- sloučení (merge) dvou či více těles
- průnik (intersection) dvou či více těles
- rozdíl (difference) dvou či více těles
2. Popis operací sjednocení, sloučení, průniku a rozdílu
Sjednocení (union)
CSG operace sjednocení (union) je poměrně jednoduchá. Dvě nebo více těles se pomocí této operace skutečně sjednotí, tj. lze s nimi pracovat jako s novým tělesem. Podobnou operaci nabízí ve 2D provedení prakticky všechny vektorové editory (InkScape, CorelDraw!, OpenOffice.org Draw atd.). Způsobů využití této operace je skutečně mnoho, typické je však použití takto sjednoceného tělesa v dalších CSG operacích popsaných dále. Od dále popsané operace sloučení (merge) se union odlišuje především v tom, že jsou zachovány všechny hranice těles. To mj. znamená, že při sjednocení dvou koulí (zobrazených na následujícím obrázku v řezu jako kružnice) jsou ve výsledném tělese přítomny i ty části stěn koulí, které se nachází uvnitř. V případě neprůhledných objektů nám to samozřejmě nevadí, ovšem pokud by se sjednocovaly objekty průhledné, byly by „vnitřní“ stěny viditelné, což většinou není žádoucí. Na druhou stranu je operace union velmi rychlá, proto je doporučeno ji pro neprůhledné objekty upřednostnit.

Příklad aplikace operace union v 2D
Sloučení (merge)
CSG operace sloučení (merge) je velmi podobná operaci sjednocení. Už v předchozím odstavci jsem se zmínil o tom, že při sjednocování těles dochází k zachování vnitřních stěn těchto těles, což může způsobit vytváření nechtěných vizuálních artefaktů při volbě průhledného materiálu. Naproti tomu při aplikaci operace merge dojde k odstranění vnitřních stěn, takže výsledné těleso je opravu jednolité. Mohlo by se tedy zdát, že je vždy výhodnější použít operaci merge a ne union. Ovšem merge je výpočetně náročnější, protože se při raytracingu musí neustále zjišťovat, které stěny se mají ignorovat a které nikoli, proto se pro neprůhledné objekty doporučuje upřednostnit union.

Příklad aplikace operace merge v 2D
Průnik (intersection)
Zatímco předchozí dvě CSG operace byly z hlediska vytváření nových tvarů poměrně „nezáživné“ (s podobným výsledkem se totiž tělesa dají pouze překrýt), je CSG operace průniku (intersection) již mnohem zajímavější, protože její vhodnou aplikací mohou vznikat i docela složité tvary. Ze dvou nebo více těles, které jsou podrobeny této operaci, zbude pouze ta část, která leží uvnitř všech těchto těles, tj. je společná pro všechna tělesa. Průnikem krychle a koule může vzniknout při vhodném poměru velikostí hrací kostka do hry „Člověče nezlob se“ atd. Velmi zajímavé je použití průniku více poloprostorů (v podstatě rovin), protože se dají vytvářet nejenom řezy různými tělesy, ale jednoduše modelovat i takové objekty, jakými jsou dokonalá tělesa atd. Jednotlivé poloprostory totiž z celkového objemu „ukusují“ další části, až zbude pouze ta část, která je všem poloprostorům společná, což je technika, kterou si ukážeme příště.

Příklad aplikace operace intersection v 2D
Rozdíl (difference)
Poslední CSG operací, která je v POV-Rayi podporovaná, je rozdíl (difference). V případě aplikace této transformace je jedno těleso „vykousnuto“ druhým tělesem. Průběh operace vlastně odpovídá obrábění – první těleso představuje zpracovávaný materiál, druhé těleso pak nástroj (například frézovací hlavu), která materiál obrábí. Způsobů použití této operace je velmi mnoho, typická je tvorba otvorů do již vymodelovaných částí. Všimněte si, že v případě hraniční reprezentace těles (trojúhelníkové sítě či NURBS) se jedná o potenciálně velmi složitou operaci, při níž je zapotřebí kompletně přepočítat plášť tělesa, zatímco v CSG jde o operaci velmi jednoduchou. To je ostatně jeden z důvodů, proč se CSG zavádělo například do programů typu CAD, zejména ve strojírenství: operace difference odpovídá obrábění a operace union a merge pak lepení či svařování.

Příklad aplikace operace difference v 2D
3. Základní demonstrační scéna
V dalších kapitolách si budeme mj. ukazovat vliv jednotlivých CSG operací na dvě tělesa – kouli a krychli – která jsou vytvořena z materiálu podobného zelenému sklu. Základní scéna bez uvedení CSG operace a krychle má následující tvar:
// ------------------------------------------------------------
// Jednoduchá scéna s jedním uzavřeným objektem, jedním nekonečným
// objektem, trojicí světel a jednou kamerou (pozorovatelem)
//
// Založeno na souboru původně vytvořeném Danem Farmerem (leden 2002)
//
// rendering lze spustit příkazem:
// povray +W800 +H600 +B100 +FN +D +Iscena2.pov +Oscena2.png
// (pro náhled postačí zadat povray scena2.pov)
// ------------------------------------------------------------
// globální nastavení parametrů scény
global_settings {
assumed_gamma 2.2
max_trace_level 5
}
// načtení všech potřebných externích souborů
#include "colors.inc"
#include "stones.inc"
#include "glass.inc"
// nastavení kamery (pozorovatele)
camera {
location <1.65, 5.5, -5.0> // pozice kamery
up <0.0, 1.0, 0.0> // vektor směřující vzhůru
right <4/3, 0.0, 0.0> // vektor směřující doprava
look_at <0, 0.5, -1.0> // bod, na který kamera směřuje
}
// tři světelné zdroje
light_source {
<-30, 11, 20> // pozice světelného zdroje
color White // barva světla
}
light_source {
< 31, 12, -20> // pozice světelného zdroje
color White // barva světla
}
light_source {
< 32, 11, -20> // pozice světelného zdroje
color LightGray // barva světla
}
// jediný uzavřený objekt ve scéně - zelená skleněná koule
sphere {
<0, 0, 0>, // souřadnice středu koule
1.75 // poloměr koule
interior { // vlastnosti "vnitřku" koule
caustics 1.0 // světelná "prasátka"
ior 1.5 // index lomu
}
texture { // textura - povrch koule
T_Glass1 // definováno v externím souboru
pigment {
color green 0.90 filter 0.85 // barva povrchu
}
finish { // optické vlastnosti materiálu
phong 1 // velikost a síla odlesků
phong_size 300
reflection 0.15 // odrazivost
}
}
}
// druhý objekt - nekonečná rovina
plane {
y, // orientace roviny
-1.5 // vzdálenost od počátku
texture { // textura - vlastnosti povrchu
T_Stone1 // definováno v externím souboru
pigment { // vlastní vzorek textury
octaves 3 // modifikace procedurálního vzorku
rotate 90*z
}
finish { // optické vlastnosti materiálu
reflection 0.10
}
}
}
// ------------------------------------------------------------
// finito
// ------------------------------------------------------------
Obrázek vzniklý vykreslením základní demonstrační scény
4. Demonstrační příklad sjednocení (union) dvou těles
Jak jsme si již řekli v první kapitole, jsou při operaci sjednocení zachovány všechny stěny sjednocovaných těles, tj. i stěny vnitřní. To je jasně patrné v následující scéně, ve které je sjednocena krychle a koule, protože dvojité vnitřní stěny zcela změní charakter výsledného průhledného objektu. Všimněte si způsobu zápisu sjednocení, který je obdobný pro všechny CSG operace: tělesa, které se operaci podrobí, jsou umístěna do bloku, který nese název dané operace. V tomto případě se jedná o blok union. Vzhledem k tomu, že jsou tělesa umístěna v jednom bloku, lze je například současně otáčet:
// ------------------------------------------------------------
// Aplikace CSG operace sjednocení koule a krychle
//
// Založeno na souboru původně vytvořeném Danem Farmerem (leden 2002)
//
// rendering lze spustit příkazem:
// povray +W800 +H600 +B100 +FN +D +Iscena2.pov +Oscena2.png
// (pro náhled postačí zadat povray scena2.pov)
// ------------------------------------------------------------
// globální nastavení parametrů scény
global_settings {
assumed_gamma 2.2
max_trace_level 5
}
// načtení všech potřebných externích souborů
#include "colors.inc"
#include "stones.inc"
#include "glass.inc"
// nastavení kamery (pozorovatele)
camera {
location <1.65, 5.5, -5.0> // pozice kamery
up <0.0, 1.0, 0.0> // vektor směřující vzhůru
right <4/3, 0.0, 0.0> // vektor směřující doprava
look_at <0, 0.5, -1.0> // bod, na který kamera směřuje
}
// tři světelné zdroje
light_source {
<-30, 11, 20> // pozice světelného zdroje
color White // barva světla
}
light_source {
< 31, 12, -20> // pozice světelného zdroje
color White // barva světla
}
light_source {
< 32, 11, -20> // pozice světelného zdroje
color LightGray // barva světla
}
#declare VEL=1.4; // velikost krychle
union {
box {
<-VEL, -VEL, -VEL> // jeden z vrcholů krychle na tělesové úhlopříčce
< VEL, VEL, VEL> // druhý z vrcholů krychle na tělesové úhlopříčce
interior { // vlastnosti "vnitřku" koule
caustics 1.0
ior 1.5
}
texture { // textura - povrch krychle
T_Glass1 // definováno v externím souboru
pigment {
color green 0.90 filter 0.85 // barva povrchu
}
finish { // optické vlastnosti materiálu
phong 1 // velikost a síla odlesků
phong_size 300
reflection 0.15 // odrazivost
}
}
}
sphere {
<0, 0, 0>, // souřadnice středu koule
1.8 // poloměr koule
interior { // vlastnosti "vnitřku" koule
caustics 1.0
ior 1.5
}
texture { // textura - povrch koule
T_Glass1 // definováno v externím souboru
pigment {
color green 0.90 filter 0.85 // barva povrchu
}
finish { // optické vlastnosti materiálu
phong 1 // velikost a síla odlesků
phong_size 300
reflection 0.15 // odrazivost
}
}
}
rotate <0,45,0> // rotace výsledného "dvojtělesa"
}
// druhý objekt - nekonečná rovina
plane {
y, // orientace roviny
-1.5 // vzdálenost od počátku
texture { // textura - vlastnosti povrchu
T_Stone1 // definováno v externím souboru
pigment { // vlastní vzorek textury
octaves 3 // modifikace procedurálního vzorku
rotate 90*z
}
finish { // optické vlastnosti materiálu
reflection 0.10
}
}
}
// ------------------------------------------------------------
// finito
// ------------------------------------------------------------
Výsledek sjednocení průhledné krychle a koule
5. Demonstrační příklad sloučení (merge) dvou těles
Zatímco při sjednocení průhledných objektů docházelo ke vzniku nežádoucích optických poruch, operace sloučení již proběhne zcela v pořádku, ovšem za cenu prodloužení času renderingu, tj. výpočtu celé scény. Slučovaná tělesa jsou umístěna v bloku nazvaném merge:
// ------------------------------------------------------------
// Aplikace CSG operace sloučení koule a krychle
//
// Založeno na souboru původně vytvořeném Danem Farmerem (leden 2002)
//
// rendering lze spustit příkazem:
// povray +W800 +H600 +B100 +FN +D +Iscena2.pov +Oscena2.png
// (pro náhled postačí zadat povray scena2.pov)
// ------------------------------------------------------------
// globální nastavení parametrů scény
global_settings {
assumed_gamma 2.2
max_trace_level 5
}
// načtení všech potřebných externích souborů
#include "colors.inc"
#include "stones.inc"
#include "glass.inc"
// nastavení kamery (pozorovatele)
camera {
location <1.65, 5.5, -5.0> // pozice kamery
up <0.0, 1.0, 0.0> // vektor směřující vzhůru
right <4/3, 0.0, 0.0> // vektor směřující doprava
look_at <0, 0.5, -1.0> // bod, na který kamera směřuje
}
// tři světelné zdroje
light_source {
<-30, 11, 20> // pozice světelného zdroje
color White // barva světla
}
light_source {
< 31, 12, -20> // pozice světelného zdroje
color White // barva světla
}
light_source {
< 32, 11, -20> // pozice světelného zdroje
color LightGray // barva světla
}
#declare VEL=1.4; // velikost krychle
merge {
box {
<-VEL, -VEL, -VEL> // jeden z vrcholů krychle na tělesové úhlopříčce
< VEL, VEL, VEL> // druhý z vrcholů krychle na tělesové úhlopříčce
interior { // vlastnosti "vnitřku" koule
caustics 1.0
ior 1.5
}
texture { // textura - povrch krychle
T_Glass1 // definováno v externím souboru
pigment {
color green 0.90 filter 0.85 // barva povrchu
}
finish { // optické vlastnosti materiálu
phong 1 // velikost a síla odlesků
phong_size 300
reflection 0.15 // odrazivost
}
}
}
sphere {
<0, 0, 0>, // souřadnice středu koule
1.8 // poloměr koule
interior { // vlastnosti "vnitřku" koule
caustics 1.0
ior 1.5
}
texture { // textura - povrch koule
T_Glass1 // definováno v externím souboru
pigment {
color green 0.90 filter 0.85 // barva povrchu
}
finish { // optické vlastnosti materiálu
phong 1 // velikost a síla odlesků
phong_size 300
reflection 0.15 // odrazivost
}
}
}
rotate <0,45,0> // rotace výsledného "dvojtělesa"
}
// druhý objekt - nekonečná rovina
plane {
y, // orientace roviny
-1.5 // vzdálenost od počátku
texture { // textura - vlastnosti povrchu
T_Stone1 // definováno v externím souboru
pigment { // vlastní vzorek textury
octaves 3 // modifikace procedurálního vzorku
rotate 90*z
}
finish { // optické vlastnosti materiálu
reflection 0.10
}
}
}
// ------------------------------------------------------------
// finito
// ------------------------------------------------------------
Výsledek sloučení průhledné krychle a koule
6. Demonstrační příklad průniku (intersection) dvou těles
Pomocí průniku koule a krychle lze mj. vymodelovat i jednoduchý model kostky pro hru „Člověče nezlob se“, jak je ukázáno na dalším příkladu. Vzhledem k tomu, že u průhledných těles nevynikne výsledný tvar, byly v této scéně použity odlišené textury a zvolen neprůhledný materiál. Tělesa podrobené operaci průniku jsou umístěna do uzlu nazvaného intersection:
// ------------------------------------------------------------
// Aplikace CSG operace průniku koule a krychle
//
// Založeno na souboru původně vytvořeném Danem Farmerem (leden 2002)
//
// rendering lze spustit příkazem:
// povray +W800 +H600 +B100 +FN +D +Iscena2.pov +Oscena2.png
// (pro náhled postačí zadat povray scena2.pov)
// ------------------------------------------------------------
// globální nastavení parametrů scény
global_settings {
assumed_gamma 2.2
max_trace_level 5
}
// načtení všech potřebných externích souborů
#include "colors.inc"
#include "stones.inc"
#include "glass.inc"
// nastavení kamery (pozorovatele)
camera {
location <1.65, 5.5, -5.0> // pozice kamery
up <0.0, 1.0, 0.0> // vektor směřující vzhůru
right <4/3, 0.0, 0.0> // vektor směřující doprava
look_at <0, 0.5, -1.0> // bod, na který kamera směřuje
}
// tři světelné zdroje
light_source {
<-30, 11, 20> // pozice světelného zdroje
color White // barva světla
}
light_source {
< 31, 12, -20> // pozice světelného zdroje
color White // barva světla
}
light_source {
< 32, 11, -20> // pozice světelného zdroje
color LightGray // barva světla
}
#declare VEL=1.4; // velikost krychle
intersection {
box {
<-VEL, -VEL, -VEL> // jeden z vrcholů krychle na tělesové úhlopříčce
< VEL, VEL, VEL> // druhý z vrcholů krychle na tělesové úhlopříčce
interior { // vlastnosti "vnitřku" koule
caustics 1.0
ior 1.5
}
texture { // textura - povrch krychle
T_Stone1
finish { // optické vlastnosti materiálu
phong 1 // velikost a síla odlesků
phong_size 300
reflection 0.15 // odrazivost
}
}
}
sphere {
<0, 0, 0>, // souřadnice středu koule
1.8 // poloměr koule
texture { // textura - povrch koule
T_Stone1
finish { // optické vlastnosti materiálu
phong 1 // velikost a síla odlesků
phong_size 300
reflection 0.15 // odrazivost
}
}
}
rotate <0,45,0> // rotace výsledného "dvojtělesa"
}
// druhý objekt - nekonečná rovina
plane {
y, // orientace roviny
-1.5 // vzdálenost od počátku
texture { // textura - vlastnosti povrchu
pigment {
crackle
}
finish { // optické vlastnosti materiálu
reflection 0.10
}
}
}
// ------------------------------------------------------------
// finito
// ------------------------------------------------------------
Výsledek průniku krychle a koule
Výsledek průniku toroidu a koule
7. Demonstrační příklad rozdílu (difference) dvou těles
Výsledek CSG operace rozdílu dvou těles je vcelku předvídatelný, ovšem je zapotřebí dát pozor na to, které těleso je „odečítáno“, tj. na pořadí těles v bloku nazvaném difference:
// ------------------------------------------------------------
// Aplikace CSG operace rozdílu koule a krychle
//
// Založeno na souboru původně vytvořeném Danem Farmerem (leden 2002)
//
// rendering lze spustit příkazem:
// povray +W800 +H600 +B100 +FN +D +Iscena2.pov +Oscena2.png
// (pro náhled postačí zadat povray scena2.pov)
// ------------------------------------------------------------
// globální nastavení parametrů scény
global_settings {
assumed_gamma 2.2
max_trace_level 5
}
// načtení všech potřebných externích souborů
#include "colors.inc"
#include "stones.inc"
#include "glass.inc"
// nastavení kamery (pozorovatele)
camera {
location <1.65, 5.5, -5.0> // pozice kamery
up <0.0, 1.0, 0.0> // vektor směřující vzhůru
right <4/3, 0.0, 0.0> // vektor směřující doprava
look_at <0, 0.5, -1.0> // bod, na který kamera směřuje
}
// tři světelné zdroje
light_source {
<-30, 11, 20> // pozice světelného zdroje
color White // barva světla
}
light_source {
< 31, 12, -20> // pozice světelného zdroje
color White // barva světla
}
light_source {
< 32, 11, -20> // pozice světelného zdroje
color LightGray // barva světla
}
#declare VEL=1.45; // velikost krychle
difference {
box {
<-VEL, -VEL, -VEL> // jeden z vrcholů krychle na tělesové úhlopříčce
< VEL, VEL, VEL> // druhý z vrcholů krychle na tělesové úhlopříčce
texture { // textura - povrch krychle
T_Glass1 // definováno v externím souboru
pigment {
color green 0.90 filter 0.85 // barva povrchu
}
finish { // optické vlastnosti materiálu
phong 1 // velikost a síla odlesků
phong_size 300
reflection 0.15 // odrazivost
}
}
}
sphere {
<0, 0, 0>, // souřadnice středu koule
1.8 // poloměr koule
interior { // vlastnosti "vnitřku" koule
caustics 1.0
ior 1.5
}
texture { // textura - povrch koule
T_Glass1 // definováno v externím souboru
pigment {
color green 0.90 filter 0.85 // barva povrchu
}
finish { // optické vlastnosti materiálu
phong 1 // velikost a síla odlesků
phong_size 300
reflection 0.15 // odrazivost
}
}
}
rotate <0,45,0> // rotace výsledného "dvojtělesa"
}
// druhý objekt - nekonečná rovina
plane {
y, // orientace roviny
-1.5 // vzdálenost od počátku
texture { // textura - vlastnosti povrchu
T_Stone1 // definováno v externím souboru
pigment { // vlastní vzorek textury
octaves 3 // modifikace procedurálního vzorku
rotate 90*z
}
finish { // optické vlastnosti materiálu
reflection 0.10
}
}
}
// ------------------------------------------------------------
// finito
// ------------------------------------------------------------
Výsledek rozdílu krychle a koule
Nyní je od koule „odečítána“ krychle
Výsledek rozdílu koule a toroidu
8. Kombinace sjednocení a rozdílu při tvorbě složitého tělesa pomocí CSG
Následuje poměrně složitý příklad, ve kterém jsou použity CSG operace sjednocení a rozdílu pro tvorbu skupiny těles představující ventil. Zdrojový soubor je uspořádaný tak, aby bylo možné provést animaci otevírání a zavírání ventilu, tvorbu animací si však ukážeme až někdy příště. Díky použití CSG vznikl přesný model (žádné plošky) a přitom je velikost souboru pouhé 3 kB (po odstranění přebytečného formátování i o něco méně):
// Persistence of Vision Ray Tracer Scene Description File
// File: Butterfly_Valve.pov
// Vers: 3.1
// Desc: Basic Scene Example
// Date: 29/04/01
// Auth: siegfriedfeterowsky@web.de
// Good for animation. Let clock run from 0 to 1.
#declare winkel = clock*360*3;
#declare rotall = clock*360;
#declare winkel = 45;
global_settings { assumed_gamma 1.0 number_of_waves 1 }
#include "colors.inc"
#include "shapes.inc"
#include "textures.inc"
#include "metals.inc"
camera {
location <-20.0, 30.0,-75>
direction z * 3
up y
right x*4/3
look_at < -1, 0, 0>
}
plane {
y, -5
pigment {
Navy * .1
}
}
light_source {
<10.0, 50.0, 35.0>
color White
}
light_source {
<-35.0, 30.0, -150.0>
color White
}
#declare loch =difference {
cylinder {
<0,-4,0>, <0,-5,0>, 1
texture {
T_Chrome_5D
}
}
cylinder {
<0,-3.9,0>, <0,-5.1,0>,.5
texture {
T_Chrome_1A
}
}
}
union {
cone {
<-7,0,0>, 2.6, <-6.2,0,0>, 3.2
texture {
T_Chrome_5D
}
}
cylinder {
<-6.2,0,0>, <-4.4,0,0>, 3.2
texture {
T_Chrome_5D
}
}
difference {
union {
object {
loch
translate <-5,9,-3.2>
}
object {
loch
translate <4.5,9,-2.4>
}
object {
loch
translate <-0.7,9,5.3>
}
cylinder {
<-.4,-4,0>, <-.4,5,0>, 5
texture {
T_Chrome_5D
}
}
}
cylinder {
<-.4,-4.1,0>, <-.4,5.1,0>, 4
texture {
T_Chrome_5D
}
}
plane {
<0,0,1>,-3.2
texture {
T_Chrome_5D
}
}
}
difference {
cylinder {
<-.4,-4,0>, <-.4,-5,0>, 5
texture {
T_Chrome_5D
}
}
cylinder {
<-.4,-3.9,0>, <-.4,-5.1,0>, 4
texture {
T_Chrome_5D
}
}
}
cylinder {
<3.6 0,0>, <5.6,0,0> ,1.8
texture {
T_Chrome_5D
}
}
// Mountings
object {
loch
translate <-5,0,-3.2>
}
object {
loch
translate <4.5,0,-2.4>
}
object {
loch
translate <-0.7,0,5.3>
}
#declare welle = union {
cylinder {
<-9.2,0,0> , <5.8,0,0>, .6
texture {
T_Copper_5A
}
finish {
metallic
}
}
cylinder {
<-.4,0,-.2>, <-.4,0,.2>, 4
texture {
T_Copper_5A
}
finish {
metallic
}
}
cylinder {
<-9.,0,0>, <-7.,0,0>, 1.8
texture {
T_Copper_5E
}
}
cylinder {
<-9.1,-1,0>, <-9.1,1,0>, .1
texture {
T_Copper_5E
}
}
box {
<-8.5, -1.8, 0>
<-7.5, 1.8, -10>
texture {
T_Copper_5E
}
}
difference {
cylinder {
<-9.,0,-10>, <-7,0,-10>, 1.8
texture {
T_Copper_5E
}
}
cylinder {
<-9.1,0,-10>, <-6.9,0,-10>, .9
texture {
T_Copper_5E
}
}
}
}
object {
welle
rotate <winkel,0,0>
}
rotate rotall*y
}
Ventil vytvořený s pomocí výše uvedeného popisu scény
Dnešní poslední příklad je ještě rozsáhlejší než příklad předchozí. Je na něm ukázána tvorba kuličkového ložiska i se všemi jeho součástmi, včetně věnečku, který slouží k pravidelnému rozmístění kuliček po obvodu. Jak vlastní model, tak i jeho rozříznutí je vytvořeno za pomoci CSG. Za zmínku také stojí analytický popis modelu pomocí číselných výrazů – v příkladu se nevyskytují „magické hodnoty“, ale pouze číselné výrazy využívající několik předem nadefinovaných hodnot, takže tvar ložiska je možné měnit pomocí příkazů #declare umístěných na začátku souboru.
// This is a Ball Bearing on a checker floor.
// To render the whole object search for "remove this!"
// in the file "BallBearing.INC" and comment out the two lines.
// Diego Krota, 1998.
// dkrota@geocities.com
// http://www.geocities.com/SiliconValley/Way/2419
#version 2.5
#include "colors.inc"
#include "textures.inc"
#declare bigradius = 6
#declare bigradiusint = 5
#declare smallradius = 4
#declare smallradiusint = 3
#declare tickness = 2
#declare sphereradius = .8
#declare bigsphereradius = sphereradius + sphereradius/4
#declare smallsphereradius = sphereradius + sphereradius/10
#declare bevel = .2
#declare epsilon = .01
#declare bigring =
difference{
difference{
cylinder{<0, 0, tickness/2>, <0, 0, -tickness/2>, bigradius}
cylinder{<0, 0, tickness/2 + epsilon>, <0, 0, -(tickness/2 + epsilon)>, bigradiusint}
cone{<0, 0, -(bigradius + 1 - bevel)>, 0, <0, 0, 1 + bevel>, bigradius + 2 inverse}
cone{<0, 0, bigradius + 1 - bevel>, 0, <0, 0, -(1 + bevel)>, bigradius + 2 inverse}
merge{
cone{<0, 0, -((bigradiusint - 1) + bevel)>, 0, <0, 0, -((bigradiusint - 1) + bevel) + bigradius>, bigradius}
cone{<0, 0, (bigradiusint - 1) + bevel>, 0, <0, 0, (bigradiusint - 1) + bevel - bigradius>, bigradius}
}
}
torus{
(bigradiusint + smallradius) / 2,
sphereradius
rotate x * 90
}
box{<0, 0, -1000>, <1000, 1000, 1000>} // remove this! (To render the whole Ball Bearing)
}
#declare smallring =
difference{
difference{
cylinder{<0, 0, tickness/2>, <0, 0, -tickness/2>, smallradius}
cylinder{<0, 0, tickness/2 + epsilon>, <0, 0, -(tickness/2 + epsilon)>, smallradiusint}
cone{<0, 0, -(smallradius + 1 - bevel)>, 0, <0, 0, 1 + bevel>, smallradius + 2 inverse}
cone{<0, 0, smallradius + 1 - bevel>, 0, <0, 0, -(1 + bevel)>, smallradius + 2 inverse}
merge{
cone{<0, 0, -((smallradiusint - 1) + bevel)>, 0, <0, 0, -((smallradiusint - 1) + bevel) + smallradius>, smallradius}
cone{<0, 0, (smallradiusint - 1) + bevel>, 0, <0, 0, (smallradiusint - 1) + bevel - smallradius>, smallradius}
}
}
torus{
(bigradiusint + smallradius) / 2,
sphereradius
rotate x * 90
}
box{<0, 0, -1000>, <1000, 1000, 1000>} // remove this! (To render the whole Ball Bearing)
}
#declare spheres =
union{
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
sphereradius
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
sphereradius
rotate z * 1 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
sphereradius
rotate z * 2 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
sphereradius
rotate z * 3 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
sphereradius
rotate z * 4 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
sphereradius
rotate z * 5 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
sphereradius
rotate z * 6 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
sphereradius
rotate z * 7 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
sphereradius
rotate z * 8 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
sphereradius
rotate z * 9 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
sphereradius
rotate z * 10 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
sphereradius
rotate z * 11 * 30
}
}
#declare bigspheres =
union{
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
bigsphereradius
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
bigsphereradius
rotate z * 1 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
bigsphereradius
rotate z * 2 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
bigsphereradius
rotate z * 3 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
bigsphereradius
rotate z * 4 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
bigsphereradius
rotate z * 5 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
bigsphereradius
rotate z * 6 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
bigsphereradius
rotate z * 7 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
bigsphereradius
rotate z * 8 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
bigsphereradius
rotate z * 9 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
bigsphereradius
rotate z * 10 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
bigsphereradius
rotate z * 11 * 30
}
}
#declare smallspheres =
union{
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
smallsphereradius
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
smallsphereradius
rotate z * 1 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
smallsphereradius
rotate z * 2 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
smallsphereradius
rotate z * 3 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
smallsphereradius
rotate z * 4 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
smallsphereradius
rotate z * 5 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
smallsphereradius
rotate z * 6 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
smallsphereradius
rotate z * 7 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
smallsphereradius
rotate z * 8 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
smallsphereradius
rotate z * 9 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
smallsphereradius
rotate z * 10 * 30
}
sphere{
<0, (bigradiusint + smallradius) / 2, 0>,
smallsphereradius
rotate z * 11 * 30
}
}
#declare cage =
union{
difference{
object{bigspheres}
object{smallspheres}
cylinder{<0, 0, tickness/2>, <0, 0, -tickness/2>, 4.1}
cylinder{<0, 0, tickness/2>, <0, 0, -tickness/2>, 4.9 inverse}
}
difference{
cylinder{<0, 0, tickness/10>, <0, 0, -tickness/10>, 4.9}
cylinder{<0, 0, tickness/2>, <0, 0, -tickness/2>, 4.1}
object{smallspheres}
}
}
#declare Ball_Bearing =
union{
object{bigring texture{Chrome_Metal}}
object{smallring texture{Chrome_Metal}}
object{spheres texture{Polished_Chrome}}
object{cage texture{Polished_Chrome}}
}
camera{
location <0, 8, -12>
look_at <0, 0, 0>
}
light_source{ <6, 6, -20> color White * 2}
object{
Ball_Bearing
bounded_by {
difference{
cylinder{<0, 0, -tickness/2 - epsilon>, <0, 0, +tickness/2 + epsilon>, bigradius + epsilon}
cylinder{<0, 0, -tickness/2 - epsilon>, <0, 0, +tickness/2 + epsilon>, smallradiusint - epsilon}
}
}
rotate y * 40
}
plane{ // The checker floor
y, -bigradius
texture{
pigment{
checker
color White
color Black
scale 10
rotate y * 40
}
}
}
Model kuličkového ložiska
9. Obsah následující části seriálu
V další části seriálu o raytraceru POV-Ray si popíšeme (už minule slibované) velmi užitečné těleso nazvané superellipsoid, které lze použít v mnoha případech, například modelování krychle se zaoblenými hranami, jehlanu se zaoblenými hranami, střechy východního stylu atd., ve kterých by se jinak muselo použít CSG či modelování pomocí parametrických ploch. Přednost superelipsoidů spočívá jak v jednoduchosti jejich popisu (jedná se o pouhé dvě reálné hodnoty definující tvar tělesa), tak i v možnostech kombinace s dalšími tělesy pomocí CSG. Na závěr si ukážeme použití CSG spolu s poloprostorem.
Vybrané tvary superelipsoidů ve scéně popsané v příští části seriálu