File: s_59.html

package info (click to toggle)
povray 1%3A3.6.1-6
  • links: PTS
  • area: non-free
  • in suites: etch, etch-m68k
  • size: 31,052 kB
  • ctags: 20,305
  • sloc: ansic: 110,032; cpp: 86,573; sh: 13,595; pascal: 5,942; asm: 2,994; makefile: 1,747; ada: 1,637
file content (429 lines) | stat: -rw-r--r-- 13,237 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429

<!--  This file copyright Persistence of Vision Raytracer Pty. Ltd. 2003-2004  -->
<html> 
<head>
  
<!--  NOTE: In order to users to help find information about POV-Ray using  -->
 
<!--  web search engines, we ask you to *not* let them index documentation  -->
 
<!--  mirrors because effectively, when searching, users will get hundreds  -->
 
<!--  of results containing the same information! For this reason, the two  -->
 
<!--  meta tags below disable archiving and indexing of this page by all  -->
 
<!--  search engines that support these meta tags.  -->
 
 <meta content="noarchive" name="robots">
   
 <meta content="noindex" name="robots">
   
 <meta content="no-cache" http-equiv="Pragma">
   
 <meta content="0" http-equiv="expires">
   
<title>2.2.3 CSG Objects</title>
 <link href="povray35.css" rel="stylesheet" type="text/css"> 
</head>
 <body> 
<table class="NavBar" width="100%">
  
 <tr>
   
  <td align="left" nowrap="" valign="middle" width="32">
    <a href="s_58.html"><img alt="previous" border="0" src="prev.png"></a> 
   
  </td>
   
  <td align="left" valign="middle" width="30%">
    <a href="s_58.html">2.2.2 Basic Shapes</a> 
  </td>
   
  <td align="center" valign="middle">
    <strong class="NavBar">POV-Ray 3.6 for UNIX documentation</strong><br> <strong>2.2.3 
   CSG Objects</strong> 
  </td>
   
  <td align="right" valign="middle" width="30%">
    <a href="s_60.html">2.2.4 The Light Source</a> 
  </td>
   
  <td align="right" nowrap="" valign="middle" width="32">
    <a href="s_60.html"><img alt="next" border="0" src="next.png"></a> 
   
  </td>
   
 </tr>
  
</table>
 
<h3><a name="s02_02_03">2.2.3 </a>CSG Objects</h3>
<a name="s02_02_03_i1">
<dl class="famousquote">
 
 <dt>
   <em>You know you have been raytracing too long when ...<br> ... Your friends are used to the fact that you will 
  suddenly stop walking in order to look at objects and figure out how to do them as CSGs.</em> 
 <dd>
   <em>-- Jeff Lee</em> 
</dl>

<p>
  Constructive Solid Geometry, or CSG, is a powerful tool to combine primitive objects to create more complex objects 
 as shown in the following sections. 
</p>

<h4><a name="s02_02_03_01">2.2.3.1 </a>What is CSG?</h4>
<a name="s02_02_03_01_i1">
<p>
  <em>CSG</em> stands for <em>Constructive Solid Geometry</em>. POV-Ray allows us to construct complex solids by 
 combining primitive shapes in four different ways. In the <code><a href="s_110.html#s03_04_06_02">union</a></code> 
 statement, two or more shapes are added together. With the <code><a href="s_110.html#s03_04_06_03">intersection</a></code> 
 statement, two or more shapes are combined to make a new shape that consists of the area common to both shapes. The <code><a href="s_110.html#s03_04_06_04">difference</a></code> 
 statement, an initial shape has all subsequent shapes subtracted from it. 
</p>

<p>
  And last but not least <code><a href="s_110.html#s03_04_06_05">merge</a></code>, which is like a union where the 
 surfaces inside the union are removed (useful in transparent CSG objects). We will deal with each of these in detail 
 in the next few sections. 
</p>

<p>
  CSG objects can be extremely complex. They can be deeply nested. In other words there can be unions of differences 
 or intersections of merges or differences of intersections or even unions of intersections of differences of merges... 
 ad infinitum. CSG objects are (almost always) finite objects and thus respond to auto-bounding and can be transformed 
 like any other POV primitive shape. 
</p>

<h4><a name="s02_02_03_02">2.2.3.2 </a>CSG Union</h4>
<a name="s02_02_03_02_i1"><a name="s02_02_03_02_i2">
<p>
  Let's try making a simple union. Create a file called <code> csgdemo.pov</code> and edit it as follows: 
</p>

<pre>
  #include &quot;colors.inc&quot;
  camera {
    location &lt;0, 1, -10&gt;
    look_at 0
    angle 36
  }
  light_source { &lt;500, 500, -1000&gt; White }
  plane { y, -1.5
    pigment { checker Green White }
  }
</pre>

<p>
  Let's add two spheres each translated 0.5 units along the x-axis in each direction. We color one blue and the other 
 red. 
</p>

<pre>
  sphere { &lt;0, 0, 0&gt;, 1
    pigment { Blue }
    translate -0.5*x
  }
  sphere { &lt;0, 0, 0&gt;, 1
    pigment { Red }
    translate 0.5*x
  }
</pre>

<p>
  We trace this file and note the results. Now we place a union block around the two spheres. This will create a 
 single CSG union out of the two objects. 
</p>

<pre>
  union{
    sphere { &lt;0, 0, 0&gt;, 1
      pigment { Blue }
      translate -0.5*x
    }
    sphere { &lt;0, 0, 0&gt;, 1
      pigment { Red }
      translate 0.5*x
    }
  }
</pre>

<p>
  We trace the file again. The union will appear no different from what each sphere looked like on its own, but now 
 we can give the entire union a single texture and transform it as a whole. Let's do that now. 
</p>

<pre>
  union{
    sphere { &lt;0, 0, 0&gt;, 1
      translate -0.5*x
    }
    sphere { &lt;0, 0, 0&gt;, 1
      translate 0.5*x
    }
    pigment { Red }
    scale &lt;1, .25, 1&gt;
    rotate &lt;30, 0, 45&gt;
  }
</pre>

<p>
  We trace the file again. As we can see, the object has changed dramatically. We experiment with different values of 
 scale and rotate and try some different textures. 
</p>

<p>
  There are many advantages of assigning only one texture to a CSG object instead of assigning the texture to each 
 individual component. First, it is much easier to use one texture if our CSG object has a lot of components because 
 changing the objects appearance involves changing only one single texture. Second, the file parses faster because the 
 texture has to be parsed only once. This may be a great factor when doing large scenes or animations. Third, using 
 only one texture saves memory because the texture is only stored once and referenced by all components of the CSG 
 object. Assigning the texture to all n components means that it is stored n times. 
</p>

<h4><a name="s02_02_03_03">2.2.3.3 </a>CSG Intersection</h4>
<a name="s02_02_03_03_i1"><a name="s02_02_03_03_i2">
<p>
  Now let's use these same spheres to illustrate the<code>intersection</code> CSG object. We change the word <code>union</code> 
 to <code>intersection</code> and delete the <code>scale</code> and <code>rotate</code> statements: 
</p>

<pre>
  intersection {
    sphere { &lt;0, 0, 0&gt;, 1
      translate -0.5*x
    }
    sphere { &lt;0, 0, 0&gt;, 1
      translate 0.5*x
    }
    pigment { Red }
  }
</pre>

<p>
  We trace the file and will see a lens-shaped object instead of the two spheres. This is because an intersection 
 consists of the area shared by both shapes, in this case the lens-shaped area where the two spheres overlap. We like 
 this lens-shaped object so we will use it to demonstrate differences. 
</p>

<h4><a name="s02_02_03_04">2.2.3.4 </a>CSG Difference</h4>
<a name="s02_02_03_04_i1"><a name="s02_02_03_04_i2">
<p>
  We rotate the lens-shaped intersection about the y-axis so that the broad side is facing the camera. 
</p>

<pre>
  intersection{
    sphere { &lt;0, 0, 0&gt;, 1
      translate -0.5*x
    }
    sphere { &lt;0, 0, 0&gt;, 1
      translate 0.5*x
    }
    pigment { Red }
    rotate 90*y
  }
</pre>

<p>
  Let's create a cylinder and stick it right in the middle of the lens. 
</p>

<pre>
  cylinder { &lt;0, 0, -1&gt; &lt;0, 0, 1&gt;, .35
    pigment { Blue }
  }
</pre>

<p>
  We render the scene to see the position of the cylinder. We will place a <code>difference</code> block around both 
 the lens-shaped intersection and the cylinder like this: 
</p>

<pre>
  difference {
    intersection {
      sphere { &lt;0, 0, 0&gt;, 1
        translate -0.5*x
      }
      sphere { &lt;0, 0, 0&gt;, 1
        translate 0.5*x
      }
      pigment { Red }
      rotate 90*y
    }
    cylinder { &lt;0, 0, -1&gt; &lt;0, 0, 1&gt;, .35
      pigment { Blue }
    }
  }
</pre>

<p>
  We render the file again and see the lens-shaped intersection with a neat hole in the middle of it where the 
 cylinder was. The cylinder has been <code>subtracted</code> from the intersection. Note that the pigment of the 
 cylinder causes the surface of the hole to be colored blue. If we eliminate this pigment the surface of the hole will 
 be black, as this is the default color if no color is specified. 
</p>

<p>
  OK, let's get a little wilder now. Let's declare our perforated lens object to give it a name. Let's also eliminate 
 all textures in the declared object because we will want them to be in the final union instead. 
</p>

<pre>
  #declare Lens_With_Hole = difference {
    intersection {
      sphere { &lt;0, 0, 0&gt;, 1
        translate -0.5*x
      }
      sphere { &lt;0, 0, 0&gt;, 1
        translate 0.5*x
      }
      rotate 90*y
    }
    cylinder { &lt;0, 0, -1&gt; &lt;0, 0, 1&gt;, .35 }
  }
</pre>

<p>
  Let's use a union to build a complex shape composed of copies of this object. 
</p>

<pre>
  union {
    object { Lens_With_Hole translate &lt;-.65, .65, 0&gt; }
    object { Lens_With_Hole translate &lt;.65, .65, 0&gt; }
    object { Lens_With_Hole translate &lt;-.65, -.65, 0&gt; }
    object { Lens_With_Hole translate &lt;.65, -.65, 0&gt; }
    pigment { Red }
  }
</pre>

<p>
  We render the scene. An interesting object to be sure. But let's try something more. Let's make it a 
 partially-transparent object by adding some filter to the pigment block. 
</p>

<pre>
  union {
    object { Lens_With_Hole translate &lt;-.65, .65, 0&gt; }
    object { Lens_With_Hole translate &lt;.65, .65, 0&gt; }
    object { Lens_With_Hole translate &lt;-.65, -.65, 0&gt; }
    object { Lens_With_Hole translate &lt;.65, -.65, 0&gt; }
    pigment { Red filter .5 }
  }
</pre>

<p>
  We render the file again. This looks pretty good... only... we can see parts of each of the lens objects inside the 
 union! This is not good. 
</p>

<h4><a name="s02_02_03_05">2.2.3.5 </a>CSG Merge</h4>
<a name="s02_02_03_05_i1"><a name="s02_02_03_05_i2">
<p>
  This brings us to the fourth kind of CSG object, the <code>merge</code>. Merges are the same as unions, but the 
 geometry of the objects in the CSG that is inside the merge is not traced. This should eliminate the problem with our 
 object. Let's try it. 
</p>

<pre>
  merge {
    object { Lens_With_Hole translate &lt;-.65, .65, 0&gt; }
    object { Lens_With_Hole translate &lt;.65, .65, 0&gt; }
    object { Lens_With_Hole translate &lt;-.65, -.65, 0&gt; }
    object { Lens_With_Hole translate &lt;.65, -.65, 0&gt; }
    pigment { Red filter .5 }
  }
</pre>

<p>
  Sure enough, it does! 
</p>

<h4><a name="s02_02_03_06">2.2.3.6 </a>CSG Pitfalls</h4>
<a name="s02_02_03_06_i1">
<p>
  There is a severe pitfall in the CSG code that we have to be aware of. 
</p>

<h5><a name="s02_02_03_06_01">2.2.3.6.1 </a>Co-incident Surfaces</h5>
<a name="s02_02_03_06_01_i1">
<p>
  POV-Ray uses inside/outside tests to determine the points at which a ray intersects a CSG object. A problem arises 
 when the surfaces of two different shapes coincide because there is no way (due to the computer's floating-point 
 accuracy) to tell whether a point on the coincident surface belongs to one shape or the other. 
</p>

<p>
  Look at the following example where a cylinder is used to cut a hole in a larger box. 
</p>

<pre>
  difference {
    box { -1, 1 pigment { Red } }
    cylinder { -z, z, 0.5 pigment { Green } }
  }
</pre>

<p class="Note">
  <strong>Note:</strong> that the vectors -1 and 1 in the box definition expand to &lt;-1,-1,-1&gt; and 
 &lt;1,1,1&gt; respectively. 
</p>

<p>
  If we trace this object we see red speckles where the hole is supposed to be. This is caused by the coincident 
 surfaces of the cylinder and the box. One time the cylinder's surface is hit first by a viewing ray, resulting in the 
 correct rendering of the hole, and another time the box is hit first, leading to a wrong result where the hole 
 vanishes and red speckles appear. This problem can be avoided by increasing the size of the cylinder to get rid of the 
 coincidence surfaces. This is done by: 
</p>

<pre>
  difference {
    box { -1, 1 pigment { Red } }
    cylinder { -1.001*z, 1.001*z, 0.5 pigment { Green } }
  }
</pre>

<p>
  In general we have to make the subtracted object a little bit larger in a CSG difference. We just have to look for 
 coincident surfaces and increase the subtracted object appropriately to get rid of those surfaces. 
</p>

<p>
  The same problem occurs in CSG intersections and is also avoided by scaling some of the involved objects. 
</p>
 <br> 
<table class="NavBar" width="100%">
  
 <tr>
   
  <td align="left" nowrap="" valign="middle" width="32">
    <a href="s_58.html"><img alt="previous" border="0" src="prev.png"></a> 
   
  </td>
   
  <td align="left" valign="middle" width="30%">
    <a href="s_58.html">2.2.2 Basic Shapes</a> 
  </td>
   
  <td align="center" valign="middle">
    <strong>2.2.3 CSG Objects</strong> 
  </td>
   
  <td align="right" valign="middle" width="30%">
    <a href="s_60.html">2.2.4 The Light Source</a> 
  </td>
   
  <td align="right" nowrap="" valign="middle" width="32">
    <a href="s_60.html"><img alt="next" border="0" src="next.png"></a> 
   
  </td>
   
 </tr>
  
</table>
 </body> </html>