Sometimes we want to make an object that does not have perfectly sharp edges like a box does. Then, the superquadric ellipsoid is a useful object. It is described by the simple syntax:

superellipsoid { <r, n> }

Where r and n are float values greater than zero and less than or equal to one. Let's make a superellipsoid and experiment with the values of r and n to see what kind of shapes we can make.

We create a file called supellps.pov and edit it as follows:

#include "colors.inc" camera { location <10, 5, -20> look_at 0 angle 15 } background { color rgb <.5, .5, .5> } light_source { <10, 50, -100> White }

The addition of a gray background makes it a little easier to see our object. We now type:

superellipsoid { <.25, .25> pigment { Red } }

There are a couple of facts about superellipsoids we should know. First, we should not use a value of 0 for either r nor n. This will cause POV-Ray to incorrectly make a black box instead of our desired shape. Second, very small values of r and n may yield strange results so they should be avoided. Finally, the Sturmian root solver will not work with superellipsoids.

Superellipsoids are finite objects so they respond to auto-bounding and can be used in CSG.

Now let's use the superellipsoid to make something that would be useful in a scene. We will make a tiled floor and place a couple of superellipsoid objects hovering over it. We can start with the file we have already made.

We rename it to tiles.pov and edit it so that it reads as follows:

#include "colors.inc" #include "textures.inc" camera { location <10, 5, -20> look_at 0 angle 15 } background { color rgb <.5, .5, .5> } light_source{ <10, 50, -100> White }

Note that we have added #include "textures.inc" so we can use pre-defined textures. Now we want to define the superellipsoid which will be our tile.

#declare Tile = superellipsoid { <0.5, 0.1> scale <1, .05, 1> }

Superellipsoids are roughly 2*2*2 units unless we scale them otherwise. If we wish to lay a bunch of our tiles side by side, they will have to be offset from each other so they don't overlap. We should select an offset value that is slightly more than 2 so that we have some space between the tiles to fill with grout. So we now add this:

#declare Offset = 2.1

We now want to lay down a row of tiles. Each tile will be offset from the original by an ever-increasing amount in both the +z and -z directions. We refer to our offset and multiply by the tile's rank to determine the position of each tile in the row. We also union these tiles into a single object called Row like this:

#declare Row = union { object { Tile } object { Tile translate z*Offset } object { Tile translate z*Offset*2 } object { Tile translate z*Offset*3 } object { Tile translate z*Offset*4 } object { Tile translate z*Offset*5 } object { Tile translate z*Offset*6 } object { Tile translate z*Offset*7 } object { Tile translate z*Offset*8 } object { Tile translate z*Offset*9 } object { Tile translate z*Offset*10 } object { Tile translate -z*Offset } object { Tile translate -z*Offset*2 } object { Tile translate -z*Offset*3 } object { Tile translate -z*Offset*4 } object { Tile translate -z*Offset*5 } object { Tile translate -z*Offset*6 } }

This gives us a single row of 17 tiles, more than enough to fill the screen. Now we must make copies of the Row and translate them, again by the offset value, in both the +x and -x directions in ever increasing amounts in the same manner.

object { Row } object { Row translate x*Offset } object { Row translate x*Offset*2 } object { Row translate x*Offset*3 } object { Row translate x*Offset*4 } object { Row translate x*Offset*5 } object { Row translate x*Offset*6 } object { Row translate x*Offset*7 } object { Row translate -x*Offset } object { Row translate -x*Offset*2 } object { Row translate -x*Offset*3 } object { Row translate -x*Offset*4 } object { Row translate -x*Offset*5 } object { Row translate -x*Offset*6 } object { Row translate -x*Offset*7 }

Finally, our tiles are complete. But we need a texture for them. To do this we union all of the Rows together and apply a White Marble pigment and a somewhat shiny reflective surface to it:

union{ object { Row } object { Row translate x*Offset } object { Row translate x*Offset*2 } object { Row translate x*Offset*3 } object { Row translate x*Offset*4 } object { Row translate x*Offset*5 } object { Row translate x*Offset*6 } object { Row translate x*Offset*7 } object { Row translate -x*Offset } object { Row translate -x*Offset*2 } object { Row translate -x*Offset*3 } object { Row translate -x*Offset*4 } object { Row translate -x*Offset*5 } object { Row translate -x*Offset*6 } object { Row translate -x*Offset*7 } pigment { White_Marble } finish { phong 1 phong_size 50 reflection .35 } }

We now need to add the grout. This can simply be a white plane. We have stepped up the ambient here a little so it looks whiter.

plane { y, 0 //this is the grout pigment { color White } finish { ambient .4 diffuse .7 } }

To complete our scene, let's add five different superellipsoids, each a different color, so that they hover over our tiles and are reflected in them.

superellipsoid { <0.1, 1> pigment { Red } translate <5, 3, 0> scale .45 } superellipsoid { <1, 0.25> pigment { Blue } translate <-5, 3, 0> scale .45 } superellipsoid { <0.2, 0.6> pigment { Green } translate <0, 3, 5> scale .45 } superellipsoid { <0.25, 0.25> pigment { Yellow } translate <0, 3, -5> scale .45 } superellipsoid { <1, 1> pigment { Pink } translate y*3 scale .45 }

Some superellipsoids hovering above a tiled floor.

### Section 4.4.9Surface of Revolution Object

Bottles, vases and glasses make nice objects in ray-traced scenes. We want to create a golden cup using the surface of revolution object (SOR object).

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.

The point configuration of our cup object.

Now it is time to come up with a scene that uses the above SOR object. We edit a file called sordemo.pov and enter the following text.

#include "colors.inc" #include "golds.inc" global_settings { assumed_gamma 2.2 } camera { location <10, 15, -20> look_at <0, 5, 0> angle 45 } background { color rgb<0.2, 0.4, 0.8> } light_source { <100, 100, -100> color rgb 1 } plane { y, 0 pigment { checker color Red, color Green scale 10 } } sor { 8, <0.0, -0.5>, <3.0, 0.0>, <1.0, 0.2>, <0.5, 0.4>, <0.5, 4.0>, <1.0, 5.0>, <3.0, 10.0>, <4.0, 11.0> texture { T_Gold_1B } }

The scene contains our cup object resting on a checkered plane. Tracing this scene at a resolution of 320x200 results in the image below.

A surface of revolution object.

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.

Next Section