# 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.).

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.

### 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:

## 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:

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>}
```

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:

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