File: pov30008.htm

package info (click to toggle)
povray-manual 3.0.20-1
  • links: PTS
  • area: main
  • in suites: hamm, potato, slink
  • size: 2,724 kB
  • ctags: 1,285
  • sloc: makefile: 31
file content (440 lines) | stat: -rw-r--r-- 19,426 bytes parent folder | download
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
430
431
432
433
434
435
436
437
438
439
440
<html>
<body text="#000000" bgcolor="#C0C0C0" background="backgrnd.gif">
<a name="ref 193 pri 0"><a name="ref 194 pri 0"><a name="ref 195 pri 1"><center><h3><a name="section 4.4.9">
Section 4.4.9<br>Surface of Revolution Object</h3></center>
Bottles, vases and glasses make nice objects in ray-traced scenes. We want to create a golden cup using the <a name="ref 196 pri 3"><strong>surface of revolution</strong> object (SOR object).<p>
We first start by thinking about the shape of the final object. It is quite difficult to come up with a set of points that describe a given curve without the help of a modelling program supporting POV-Eay's surface of revolution object. If such a program is available we should take advantage of it.<p>
<center><img src="pov30015.gif" border=0 width=320 height=240><br><cite>The point configuration of our cup object.</cite></center><br> <p>
We will use the point configuration shown in the figure above. There are eight points describing the curve that will be rotated about the y-axis to get our cup. The curve was calculated using the method described in the reference section (see <a href="pov30021.htm#ref 196 pri 1">&quot;Surface of Revolution&quot;</a>).<p>
Now it is time to come up with a scene that uses the above SOR object. We edit a file called <b>sordemo.pov</b> and enter the following text.<p>
<listing>
  #include &quot;colors.inc&quot;
  #include &quot;golds.inc&quot;

  global_settings { assumed_gamma 2.2 }

  camera {
    location &lt;10, 15, -20&gt;
    look_at &lt;0, 5, 0&gt;
    angle 45
  }

  background { color rgb&lt;0.2, 0.4, 0.8&gt;  }

  light_source { &lt;100, 100, -100&gt; color rgb 1 }

  plane { y, 0
    pigment { checker color Red, color Green scale 10 }
  }

  sor {
    8,
    &lt;0.0,  -0.5&gt;,
    &lt;3.0,   0.0&gt;,
    &lt;1.0,   0.2&gt;,
    &lt;0.5,   0.4&gt;,
    &lt;0.5,   4.0&gt;,
    &lt;1.0,   5.0&gt;,
    &lt;3.0,  10.0&gt;,
    &lt;4.0,  11.0&gt;
    texture { T_Gold_1B }
  }
</listing>
<p>
The scene contains our cup object resting on a checkered plane. Tracing this scene at a resolution of 320x200 results in the image below.<p>
<center><img src="pov30016.gif" border=0 width=320 height=240><br><cite>A surface of revolution object.</cite></center><br> <p>
The surface of revolution is described by starting with the number of points followed by the points with ascending heights. Each point determines the radius the curve for a given height. E. g. the first point tells POV-Ray that at height -0.5 the radius is 0. We should take care that each point has a larger height than its predecessor. If this is not the case the program will abort with an error message.<hr>
<a name="ref 197 pri 0"><a name="ref 198 pri 0"><a name="ref 199 pri 1"><center><h3><a name="section 4.4.10">
Section 4.4.10<br>Text Object</h3></center>
Creating <a name="ref 199 pri 3"><strong>text</strong> objects using POV-Ray always used to mean that the letters had to be built either from CSG, a painstaking process or by using a black and white image of the letters as a height field, a method that was only somewhat satisfactory. Now, for POV-Ray 3.0, a new primitive has been introduced that can use any TrueType font to create text objects. These objects can be used in CSG, transformed and textured just like any other POV primitive.<p>
For this tutorial, we will make two uses of the text object. First, let's just make some block letters sitting on a checkered plane. Any TTF font should do, but for this tutorial, we will use the ones bundled with POV-Ray 3.0.<p>
We create a file called <b>textdemo.pov</b> and edit it as follows:<p>
<listing>
  #include &quot;colors.inc&quot;

  camera {
    location &lt;0, 1, -10&gt;
    look_at 0
    angle 35
  }

  light_source { &lt;500,500,-1000&gt; White }

  plane { y,0
    pigment { checker Green White }
  }
</listing>
<p>
Now let's add the text object. We will use the font <b>timrom.ttf</b> and we will create the string <strong>POV-RAY 3.0</strong>. For now, we will just make the letters red. The syntax is very simple. The first string in quotes is the font name, the second one is the string to be rendered. The two floats are the thickness and offset values. The thickness float determines how thick the block letters will be. Values of .5 to 2 are usually best for this. The offset value will add to the kerning distance of the letters. We will leave this a 0 for now.<p>
<listing>
  text { ttf &quot;timrom.ttf&quot; &quot;POV-RAY 3.0&quot; 1, 0
    pigment { Red }
  }
</listing>
<p>
Rendering this at 200x150 <a name="ref 89 pri 8"><strong>-A</strong>, we notice that the letters are off to the right of the screen. This is because they are placed so that the lower left front corner of the first letter is at the origin. To center the string we need to translate it -x some distance. But how far? In the docs we see that the letters are all 0.5 to 0.75 units high. If we assume that each one takes about 0.5 units of space on the x-axis, this means that the string is about 6 units long (12 characters and spaces). Let's translate the string 3 units along the negative x-axis.<p>
<listing>
  text { ttf &quot;timrom.ttf&quot; &quot;POV-RAY 3.0&quot; 1, 0
    pigment { Red }
    translate -3*x
  }
</listing>
<p>
That's better. Now let's play around with some of the parameters of the text object. First, let's raise the thickness float to something outlandish... say 25!<p>
<listing>
  text { ttf &quot;timrom.ttf&quot; &quot;POV-RAY 3.0&quot; 25, 0
    pigment { Red }
    translate -2.25*x
  }
</listing>
<p>
Actually, that's kind of cool. Now let's return the thickness value to 1 and try a different offset value. Change the offset float from 0 to 0.1 and render it again.<p>
Wait a minute?! The letters go wandering off up at an angle! That is not what the docs describe! It almost looks as if the offset value applies in both the x- and y-axis instead of just the x axis like we intended. Could it be that a vector is called for here instead of a float? Let's try it. We replace <strong>0.1</strong> with <strong>0.1*x</strong> and render it again.<p>
That works! The letters are still in a straight line along the x-axis, just a little further apart. Let's verify this and try to offset just in the y-axis. We replace <strong>0.1*x</strong> with <strong>0.1*y</strong>. Again, this works as expected with the letters going up to the right at an angle with no additional distance added along the x-axis. Now let's try the z-axis. We replace <strong>0.1*y</strong> with <strong>0.1*z</strong>. Rendering this yields a disappointment. No offset occurs! The offset value can only be applied in the x- and y-directions.<p>
Let's finish our scene by giving a fancier texture to the block letters, using that cool large thickness value, and adding a slight y-offset. For fun, we will throw in a sky sphere, dandy up our plane a bit, and use a little more interesting camera viewpoint (we render the following scene at 640x480 <a name="ref 192 pri 9"><strong>+A0.2</strong>):<p>
<listing>
  #include &quot;colors.inc&quot;

  camera {
    location &lt;-5,.15,-2&gt;
    look_at &lt;.3,.2,1&gt;
    angle 35
  }

  light_source { &lt;500,500,-1000&gt; White }

  plane { y,0
    texture {
      pigment { SeaGreen }
      finish { reflection .35 specular 1 }
      normal { ripples .35 turbulence .5 scale .25 }
    }
  }

  text { ttf &quot;timrom.ttf&quot; &quot;POV-RAY 3.0&quot; 25, 0.1*y
    pigment { BrightGold }
    finish { reflection .25 specular 1 }
    translate -3*x
  }

  #include &quot;skies.inc&quot;

  sky_sphere { S_Cloud5 }
</listing>
<p>
Let's try using text in a CSG object. We will attempt to create an inlay in a stone block using a text object. We create a new file called <b>textcsg.pov</b> and edit it as follows:<p>
<listing>
  #include &quot;colors.inc&quot;
  #include &quot;stones.inc&quot;

  background { color rgb 1 }

  camera {
    location &lt;-3, 5, -15&gt;
    look_at 0
    angle 25
  }

  light_source { &lt;500,500,-1000&gt; White }
</listing>
<p>
Now let's create the block. We want it to be about eight units across because our text string (<strong>POV-RAY 3.0</strong>) is about six units long. We also want it about four units high and about one unit deep. But we need to avoid a potential coincident surface with the text object so we will make the first z-coordinate 0.1 instead of 0. Finally, we will give this block a nice stone texture.<p>
<listing>
  box { &lt;-3.5, -1, 0.1&gt;, &lt;3.5, 1, 1&gt;
    texture { T_Stone10 }
  }
</listing>
<p>
Next, we want to make the text object. We can use the same object we used in the first tutorial except we will use slightly different thickness and offset values.<p>
<listing>
  text { ttf &quot;timrom.ttf&quot; &quot;POV-RAY 3.0&quot; 0.15, 0
    pigment { BrightGold }
    finish { reflection .25 specular 1 }
    translate -3*x
  }
</listing>
<p>
We remember that the text object is placed by default so that its front surface lies directly on the x-y-plane. If the front of the box begins at z=0.1 and thickness is set at 0.15, the depth of the <strong>inlay</strong> will be 0.05 units. We place a difference block around the two objects.<p>
<listing>
  difference {
    box { &lt;-3.5, -1, 0.1&gt;, &lt;3.5, 1, 1&gt;
      texture { T_Stone10 }
    }
    text { ttf &quot;timrom.ttf&quot; &quot;POV-RAY 3.0&quot; 0.15, 0
      pigment { BrightGold }
      finish { reflection .25 specular 1 }
      translate -3*x
    }
  }
</listing>
<p>
<center><img src="pov30017.gif" border=0 width=320 height=240><br><cite>Text carved from stone.</cite></center><br> <p>
We render this at 200x150 <a name="ref 89 pri 15"><strong>-A</strong>. We can see the inlay clearly and that it is indeed a bright gold color. We re-render at 640x480 <a name="ref 192 pri 17"><strong>+A0.2</strong> to see the results more clearly, but be forewarned... this trace will take a little time.<hr>
<a name="ref 200 pri 0"><a name="ref 201 pri 0"><a name="ref 202 pri 3"><center><h3><a name="section 4.4.11">
Section 4.4.11<br>Torus Object</h3></center>
A <a name="ref 202 pri 7"><strong>torus</strong> can be thought of as a donut or an inner-tube. It is a shape that is vastly useful in many kinds of CSG so POV-Ray has adopted this 4th order quartic polynomial as a primitive shape. The syntax for a torus is so simple that it makes it a very easy shape to work with once we learn what the two float values mean. Instead of a lecture on the subject, let's create one and do some experiments with it.<p>
We create a file called <b>tordemo.pov</b> and edit it as follows:<p>
<listing>
  #include &quot;colors.inc&quot;

  camera {
    location &lt;0, .1, -25&gt;
    look_at 0
    angle 30
  }

  background { color Gray50 } // to make the torus easy to see

  light_source{ &lt;300, 300, -1000&gt; White }

  torus { 4, 1        // major and minor radius
    rotate -90*x      // so we can see it from the top
    pigment { Green }
  }
</listing>
<p>
We trace the scene. Well, it's a donut alright. Let's try changing the major and minor radius values and see what happens. We change them as follows:<p>
<listing>
  torus { 5, .25      // major and minor radius
</listing>
<p>
That looks more like a hula-hoop! Let's try this:<p>
<listing>
  torus { 3.5, 2.5    // major and minor radius
</listing>
<p>
Whoa! A donut with a serious weight problem!<p>
With such a simple syntax, there isn't much else we can do to a torus besides change its texture... or is there? Let's see...<p>
Torii are very useful objects in CSG. Let's try a little experiment. We make a difference of a torus and a box:<p>
<listing>
  difference {
    torus { 4, 1
      rotate x*-90  // so we can see it from the top
    }
    box { &lt;-5, -5, -1&gt;, &lt;5, 0, 1&gt; }
    pigment { Green }
  }
</listing>
<p>
Interesting... a half-torus. Now we add another one flipped the other way. Only, let's declare the original half-torus and the necessary transformations so we can use them again:<p>
<listing>
  #declare Half_Torus = difference {
    torus { 4, 1
      rotate -90*x  // so we can see it from the top
    }
    box { &lt;-5, -5, -1&gt;, &lt;5, 0, 1&gt; }
    pigment { Green }
  }

  #declare Flip_It_Over = 180*x

  #declare Torus_Translate = 8  // twice the major radius
</listing>
<p>
Now we create a union of two <strong>Half_Torus</strong> objects:<p>
<listing>
  union {
    object { Half_Torus }
    object { Half_Torus
      rotate Flip_It_Over
      translate Torus_Translate*x
    }
  }
</listing>
<p>
This makes an <strong>S</strong>-shaped object, but we can't see the whole thing from our present camera. Let's add a few more links, three in each direction, move the object along the +z-direction and rotate it about the +y-axis so we can see more of it. We also notice that there appears to be a small gap where the half torii meet. This is due to the fact that we are viewing this scene from directly on the x-z-plane. We will change the camera's y-coordinate from 0 to 0.1 to eliminate this.<p>
<listing>
  union {
    object { Half_Torus }
    object { Half_Torus
      rotate Flip_It_Over
      translate x*Torus_Translate
    }
    object { Half_Torus
      translate x*Torus_Translate*2
    }
    object { Half_Torus
      rotate Flip_It_Over
      translate x*Torus_Translate*3
    }
    object { Half_Torus
      rotate Flip_It_Over
      translate -x*Torus_Translate
    }
    object { Half_Torus
      translate -x*Torus_Translate*2
    }
    object { Half_Torus
      rotate Flip_It_Over
      translate -x*Torus_Translate*3
    }
    object { Half_Torus
      translate -x*Torus_Translate*4
    }
    rotate y*45
    translate z*20
  }
</listing>
<p>
Rendering this we see a cool, undulating, snake-like something-or-other. Neato. But we want to model something useful, something that we might see in real life. How about a chain?<p>
Thinking about it for a moment, we realize that a single link of a chain can be easily modeled using two half toruses and two cylinders. We create a new file. We can use the same camera, background, light source and declared objects and transformations as we used in <b>tordemo.pov</b>:<p>
<listing>
  #include &quot;colors.inc&quot;

  camera {
    location &lt;0, .1, -25&gt;
    look_at 0
    angle 30
  }

  background { color Gray50 }

  light_source{ &lt;300, 300, -1000&gt; White }

  #declare Half_Torus = difference {
    torus { 4,1
      sturm
      rotate x*-90  // so we can see it from the top
    }
    box { &lt;-5, -5, -1&gt;, &lt;5, 0, 1&gt; }
    pigment { Green }
  }

  #declare Flip_It_Over = x*180

  #declare Torus_Translate = 8
</listing>
<p>
Now, we make a complete torus of two half toruses:<p>
<listing>
  union {
    object { Half_Torus }
    object { Half_Torus rotate Flip_It_Over }
  }
</listing>
<p>
This may seem like a wasteful way to make a complete torus, but we are really going to move each half apart to make room for the cylinders. First, we add the declared cylinder before the union:<p>
<listing>
  #declare Chain_Segment = cylinder { &lt;0, 4, 0&gt;, &lt;0, -4, 0&gt;, 1
    pigment { Green }
  }
</listing>
<p>
We then add two <strong>chain segments</strong> to the union and translate them so that they line up with the minor radius of the torus on each side:<p>
<listing>
  union {
    object { Half_Torus }
    object { Half_Torus rotate Flip_It_Over }
    object { Chain_Segment translate  x*Torus_Translate/2 }
    object { Chain_Segment translate -x*Torus_Translate/2 }
  }
</listing>
<p>
Now we translate the two half toruses +y and -y so that the clipped ends meet the ends of the cylinders. This distance is equal to half of the previously declared <strong>Torus_Translate</strong>:<p>
<listing>
  union {
    object { Half_Torus
      translate y*Torus_Translate/2
    }
    object { Half_Torus
      rotate Flip_It_Over
      translate -y*Torus_Translate/2
    }
    object { Chain_Segment
      translate x*Torus_Translate/2
    }
    object { Chain_Segment
      translate -x*Torus_Translate/2
    }
  }
</listing>
<p>
We render this and viola! A single link of a chain. But we aren't done yet! Whoever heard of a green chain? We would rather use a nice metallic color instead. First, we remove any pigment blocks in the declared toruses and cylinders. Then we add the following before the union:<p>
<listing>
  #declare Chain_Gold = texture {
    pigment { BrightGold }
    finish {
      ambient .1
      diffuse .4
      reflection .25
      specular 1
      metallic
    }
  }
</listing>
<p>
We then add the texture to the union and declare the union as a single link:<p>
<listing>
  #declare Link = union {
    object { Half_Torus
      translate y*Torus_Translate/2
    }
    object { Half_Torus
      rotate Flip_It_Over
      translate -y*Torus_Translate/2
    }
    object { Chain_Segment
      translate x*Torus_Translate/2
    }
    object { Chain_Segment
      translate -x*Torus_Translate/2
    }
    texture { Chain_Gold }
  }
</listing>
<p>
Now we make a union of two links. The second one will have to be translated +y so that its inner wall just meets the inner wall of the other link, just like the links of a chain. This distance turns out to be double the previously declared <strong>Torus_Translate</strong> minus 2 (twice the minor radius). This can be described by the expression:<p>
<listing>
  Torus_Translate*2-2*y
</listing>
<p>
We declare this expression as follows:<p>
<listing>
  #declare Link_Translate = Torus_Translate*2-2*y
</listing>
<p>
In the object block, we will use this declared value so that we can multiply it to create other links. Now, we rotate the second link <strong>90*y</strong> so that it is perpendicular to the first, just like links of a chain. Finally, we scale the union by 1/4 so that we can see the whole thing:<p>
<listing>
  union {
    object { Link }
    object { Link translate y*Link_Translate rotate y*90 }
    scale .25
  }
</listing>
<p>
We render this and we will see a very realistic pair of links. If we want to make an entire chain, we must declare the above union and then create another union of this declared object. We must be sure to remove the scaling from the declared object:<p>
<listing>
  #declare Link_Pair =
  union {
    object { Link }
    object { Link translate y*Link_Translate rotate y*90 }
  }
</listing>
<p>
Now we declare our chain:<p>
<listing>
  #declare Chain = union {
    object { Link_Pair}
    object { Link_Pair translate  y*Link_Translate*2 }
    object { Link_Pair translate  y*Link_Translate*4 }
    object { Link_Pair translate  y*Link_Translate*6 }
    object { Link_Pair translate -y*Link_Translate*2 }
    object { Link_Pair translate -y*Link_Translate*4 }
    object { Link_Pair translate -y*Link_Translate*6 }
  }
</listing>
<p>
And finally we create our chain with a couple of transformations to make it easier to see. These include scaling it down by a factor of 1/10, and rotating it so that we can clearly see each link:<p>
<listing>
  object { Chain scale .1 rotate &lt;0, 45, -45&gt; }
</listing>
<p>
<center><img src="pov30018.gif" border=0 width=320 height=240><br><cite>The torus object can be used to create chains.</cite></center><br> <p>
We render this and we should see a very realistic gold chain stretched diagonally across the screen.<hr>

<center>
<a href="pov30009.htm">Next Section</a><br>
<a href="povray.htm#Table of Contents">Table Of Contents</a><br>
</center>
</body>
</html>