1.3.3.5 Superquadric Ellipsoid Object
Sometimes we want to make an object that does not have perfectly sharp edges like a box does. Then, the
superquadric ellipsoid shape made by the superellipsoid is a useful object. It is described by the simple
syntax:
superellipsoid { <Value_E, Value_N >}
Where Value_E and Value_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 Value_E and Value_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 }
}
We save the file and trace it at 200x150 -A to see the shape. It will look like a box, but the edges
will be rounded off. Now let's experiment with different values of Value_E and Value_N. For the
next trace, try <1, 0.2>. The shape now looks like a cylinder, but the top edges are rounded. Now try <0.1,
1>. This shape is an odd one! We do not know exactly what to call it, but it is interesting. Finally, let's try
<1, 1>. Well, this is more familiar... a sphere!
There are a couple of facts about superellipsoids we should know. First, we should not use a value of 0 for either
Value_E nor Value_N. This will cause POV-Ray to incorrectly make a black box instead of our desired
shape. Second, very small values of Value_E and Value_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: 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 do not 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
}
We trace the scene at 320x200 -A to see the result. If we are happy with that, we do a final trace at
640x480 +A0.2 .
|