You are here

More on objects


  • Some other useful objects

    • The cylinder
    • The cone
    • The torus

  • Manipulating Objects: moving, shaping, and rotating

    • Moving: The translate command
    • Shaping: The scale command

      • The pitfalls of scaling

    • Rotating: The rotate command

      • The hazards of rotation


  • The #declare statement

    • The dangers of #declare

Some other useful objects

Before we continue, let's add a few more useful objects to our stock "kit." Sample renditions of these objects show a checkered background, much like the previous scene, to provide some scale and orientation.

The cylinder

Specify a cylinder by giving the centers of the two ends, and the radius, like this:

cylinder { <0,0,0>, <0,0,5> 0.5 }


which makes a cylinder with length 5 along the z axis and a radius of 0.5. Like any other object, cylinders can take a texture (pigment, finish, etc.).

cyl1.jpg

The additional keyword open specifies a cylinder without end caps -- i.e., a thin-walled tube. For example:

cylinder { <0,0,0>, <0,0,5> 0.5 open
           pigment {color {Gray50} finish {Dull} }


makes a cylinder that looks like a gray plastic hose.

The Cone

Specify cones much like cylinders, except that you must give two radii, one for each end of the cone:

 cone { <0,0,0>,1 <5,0,0>0.5 pigment {color Green}} 


This is a cone along the x-axis, with radius 1 at z=0, tapering down to 0.5 at x=+5. If one of the radii is zero the cone comes to a sharp point. A negative radius makes a pair of cones, joined at their tips.

cone1.jpg

The torus

The torus is a doughnut-shaped object. The specifications for the torus are simple: two floating-point numbers that indicate the larger and smaller radii respectively (the larger radius is that of the torus as a whole, while the smaller is the "thickness" of the torus):

torus {5,1 pigment {color Red}}


By default, torus puts the torus in the x-z plane, so you don't need to specify any coordinates. You may need to move it around to put it where you want; you'll see how to to that in the next section.

For the torus an image is worth a thousand words:

tor1.jpg

Manipulating Objects: Moving, Shaping, and Rotating

Now that we've got a bunch of objects to play with, what can we do?

Moving: the translate command

Use the translate command to move an object around, without changing its shape or orientation. The translate command takes a vector, which POV-Ray simply adds to the object's current position to give its new position. For example, let's make a box:

box {<1,0,0>, <1.5, 0.5, 0.5> pigment {color Yellow}}


then make an exact duplicate and translate this two units in x:

box {<1,0,0>, <1.5, 0.5, 0.5> pigment {color Yellow}
     translate <2,0,0> }


and put these in our coordinate system:

translate.jpg



Translating a box along +x.

Shaping: the scale command

Use the scale command to scale -- i.e., resize -- an object along each of the 3 axes. scale normally takes a vector, e.g.,

scale <1,2,1>


in which each component specifies a multiplier for that dimension. Values larger than 1 stretch an object; values smaller than 1 squish it. In this case, the object would be stretched in its y dimension by a factor of 2.

A handy shortcut: if you want to scale all dimensions equally, i.e., expand or shrink an object while retaining its shape, the scale command can take a single floating-point number, rather than a vector. scale is smart enough to turn scale 2.5 into scale <2.5,2.5,2.5>.

The Pitfalls of Scaling

The scale command doesn't just scale the object, it also scales the object's distance from the origin. This can lead to confusion, quickly. For example, you might try to scale a cube in the following manner:


box {<2,2,2>, <3,3,3>
    pigment {color Red}
    scale 2}


This makes the cube twice as large, as expected, but also twice as far from the origin. If all you wanted was a larger cube in the same place, scale won't work by itself -- unless you start at the origin. As a general rule, create objects centered as nearly as possible on the origin, scale them, then translate them to the place you want them to be.

Rotating: the rotate command

Use the rotate command to rotate an object around any (or all) of the x,y,and z axes. rotate takes a three-element vector, representing the number of degrees to rotate about each axis (a zero value for any element means no rotation about that axis). For example:

rotate <45,30,-45>


first rotates the object 45 degrees around the x-axis, then 30 degrees around y, and finally -45 degrees around z. Since the coordinate system is left-handed, be careful with the signs!

Like scale, rotate can take a single number and apply it equally to all elements of a vector. You do this by multiplying (using "*") the vector by a single number. Thus

rotate <10.5,10.5,10.5>


can also be written as

rotate <1,1,1>*10.5


Most frequently, you will want to rotate around one of the three principal axes, x, y, or z. POV-Ray lets us use the axis names as a shorthand, i.e., "x" stands for <1,0,0> and similarly for the others. Thus, rotate <0,90,0> and rotate y*90 both represent a rotation of 90 degrees about +y.

The Hazards of Rotation

rotate x (or y, or z) rotates an object around that axis, not the center of the object. POV-Ray doesn't even bother trying to figure out where the center of an object is; for complicated objects, the center may not even be well-defined. As a result, if your object is not centered on the origin, it will "orbit" the origin, as well as being rotated itself.

Behavior like this may seem like a nuisance, but it's actually very useful. If you want to create, for example, a bunch of objects arranged in a circle around the origin, all you need to do is create one object, displaced from the origin, and then rotate copies of it by varying
amounts.

Still, much of the time you want to scale and rotate an object or group of objects without having them move all over the place. The solution? Create all your objects, particularly simpler ones with well-defined centers (like spheres and cones), around the origin. Then you can scale and rotate to your heart's content while the object stays put. Finally, you translate it to wherever you want it.

In general, a good rule for "order of operations" on object motions is:


  1. scale
  2. rotate
  3. translate

The #declare statement

Often, you'll want to have a single object used many times, or colored differently each time, and so on. The #declare statement lets you give any POV-Ray function -- be it a color, a texture, or even a whole object -- a simple name. You then use the name instead of retyping all the POV-Ray code for the "original" over and over again.

For example, suppose you were building a simple picture of standing stones, sort of like those in Stonehenge (to keep things simple, though, we'll just make a simple rectangular "stone", rather than making pi-shaped objects). You could use a scene file starting like this:

#include "colors.inc"
#include "textures.inc"
#include "finish.inc"

camera {location <-12,3,-12> look_at <0,2,0> angle 45}

light_source {<0,0,-10> color White}
light_source {<-10,10,10> color White}

plane {y, 0 pigment {color Green}}

cylinder {<0,0,0>, <0,5,0>, 0.02 pigment {color Red}}

box {<0,0,0>, <0.5,2,1> 
     pigment {color Gray80}
     translate <5,0,0>}


minihenge.jpg

Here there's a nice green field, a small red cylinder marking the y-axis (which we'll rotate the blocks around), and a gray block 5 units from the origin.

Now, you could make this "miniature Stonehenge" by typing in this box declaration 8 or 10 times and rotating the boxes various amounts. However, it's a real chore to type in the same box object over and over again. Use #declare instead:

#declare Block = 
     box {<0,0,0>, <0.5,2,1> 
     pigment {color Gray80}
     translate <5,0,0>}


Now, in this scene file, anytime you want to use that gray box, write

object {Block}


and add whatever commands or attributes you want to give Block. For example, you could do:

object {Block rotate y*0}
object {Block rotate y*45}
object {Block rotate y*90}
object {Block rotate y*135}
object {Block rotate y*180}
object {Block rotate y*225}
object {Block rotate y*270}
object {Block rotate y*315}


And here's our mini-Stonehenge:

minihenge.jpg

Nice!

You can #declare anything you want, for example a color:

#declare MyBlue = color rgb <0.1,0.2,0.9>


which you can use later on as:

pigment {color MyBlue}


Most of the "include" files are actually just big compilations of useful colors, textures, and objects given special names with #declare.

The dangers of #declare

First, an advance warning for C programmers: remember that it's "#declare", not "#define". Yes, you'll probably type "#define" more times than you care to remember, at least for the first few days of using POV-Ray.

Also, despite the superficial resemblance, the POV-Ray #declare doesn't behave exactly like a C preprocessor directive. Specifically, it does not include the #declare material verbatim. Thus, you might think you could declare a block like this:

#declare Block = 
     box {<0,0,0>, <0.5,2,1>
     pigment {color Gray80}
     translate <5,0,0>}


and use it later by writing Block rather than object {Block}, since Block looks like a "synonym" for box {<0,0,0>... Unfortunately, this doesn't work well all the time. If you #declare an object, you should refer to it later with object {...}. Similarly, refer to a declared pigment with pigment {....}, and so on.

This can be frustrating, but it also makes it easier to add additional commands or attributes to a declared object. We took advantage of this in the "mini-Stonehenge" -- by using object {Block} we made sure that we could add the rotation easily. We could even go in and change the color or texture of any (or all) of the blocks.

Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer