|
Quick and Dirty: Rendering Sierpinski's Pyramid
by Mike Kost
Introduction
Fractals
are just cool. To take a simple, repetitive process and derive complex
structures is amazing. I'm fond of the Sierpinski
triangle, myself. By
great coincidence, Povray is a wonderful tool for visualizing and
rendering three-dimensional geometry problems (yes, shocking). So,
this Quick and Dirty tutorial combines the recursive madness of the
Sierpinski triangle with the rendering prowess of Povray 3.6 to create
a fractal image.
Sierpinski's Triangle
To create Sierpinski's triangle, start with a triangle. Now, in every
iteration, take any existing triangle, and substitute 3 half-height
triangles in the corners and leave an inverted half-height triangle gap
in the middle. This process is shown below [1].
|
|
Base Triangle
|
1 Iteration
|
|
|
2 Iterations
|
3 Iterations
|
Moving To 3D
To
extend the Sierpinski triangle into three dimensions, the iterative
step needs to be modified. In this case, start with a pyramid. For each
iteration, replace a pyramid with 4 half-height pyramids in each of the
corners. A gap, the size of an upside-down half-height pyramid, should
now be in the middle. This is shown below. Note that, as always, the
images link to the Povray source used to create them.
|
|
1 Iteration
|
2 Iterations
|
Pyramids
Pyramids
are not fundamental shapes in Povray, so it requires that one be
constructed. There are two easy ways to generate a 5-point pyramid:
isosurfaces and Constructive Solid Geometry (CSG).
The isosurface method is shown below:
isosurface {
function {abs(x/sqrt(2))+abs(y)+abs(z/sqrt(2))-1}
contained_by {
box{ sqrt(2),
<-sqrt(2),0,-sqrt(2)> }
}
max_gradient 1.4
rotate 45*y
}
|
|
The CSG method is shown below:
difference{
box {< 1,1,1>, <-1,0,-1>}
plane { x-y, -sqrt(2)/2 }
plane { -x-y, -sqrt(2)/2 }
plane { z-y, -sqrt(2)/2 }
plane { -z-y, -sqrt(2)/2 }
}
|
|
Both of these methods produce a pyramid 1 unit tall and a
square base with corners at <1,0,1>, <1,0,-1>,
<-1,0,1>, and <-1,0,-1>. I'll use the CSG method for later
renderings. The isosurface method could be useful for applying
mathematical distortions to the shapes.
Recursive Macros
The easiest way to construct this structure is to use a recursive macro.
This refers to the macro being capable of calling itself - in this
case, to do the iterative step of the Sierpinski triangle. The
parameters for the macro are the size of the pyramid (s), the
coordinates
for the center of the base, and the recursive depth.
Defining a macro function.
#macro sierpinski(s,
base_center,
recursion_depth)
If there are still iterations to go, we need to break the current
working pyramid
into 5 smaller sections and leave out the middle. We'll do this by
calling the sierpenski macro once again (yay recursion) and
appropriately move the
base_center and size for the 5 smaller compensate. Subtract 1
from the recursion depth to note that we've descended deeper into the
fractal shape.
union {
sierpinski(s / 2, base_center +
s/2*y, recursion_depth - 1) // Top
sierpinski(s / 2, base_center - s/2*(x+z),
recursion_depth
- 1)
// Base +x +z corner
sierpinski(s / 2, base_center - s/2*(x-z),
recursion_depth
- 1)
// Base +x -z corner
sierpinski(s / 2, base_center - s/2*(-x+z),
recursion_depth - 1)
// Base -x +z corner
sierpinski(s / 2, base_center - s/2*(-x-z),
recursion_depth - 1)
// Base -x -z corner
}
However, if we are on the last iteration, we need to place a pyramid.
difference{
box { <1,1,1>, <-1,0,-1> }
plane { x-y, -sqrt(2)/2}
plane { -x-y, -sqrt(2)/2}
plane { z-y, -sqrt(2)/2}
plane { -z-y, -sqrt(2)/2}
scale s*1.0
translate base_center
}
Note that there's a 1.0 gain on the scaling factor. To give more
thickness to the structure, increase the 1.0 scaling factor. 1.2 - 1.5
works well depending on the visual effect desired.
Now, pulling this all together:
#macro sierpinski(s, base_center, recursion_depth)
#if (recursion_depth > 0)
union {
sierpinski(s
/ 2,
base_center
+
s/2*y, recursion_depth - 1)
sierpinski(s / 2,
base_center - s/2*(x+z), recursion_depth
- 1)
sierpinski(s / 2,
base_center - s/2*(x-z), recursion_depth
- 1)
sierpinski(s / 2,
base_center - s/2*(-x+z), recursion_depth - 1)
sierpinski(s / 2,
base_center - s/2*(-x-z), recursion_depth - 1)
}
#else
difference{
box {
<1,1,1>, <-1,0,-1> }
plane{ x-y,
-sqrt(2)/2}
plane{ -x-y,
-sqrt(2)/2}
plane{ z-y,
-sqrt(2)/2}
plane{ -z-y,
-sqrt(2)/2}
scale s*1.0
translate
base_center
}
#end
#end
Final Image
Now that the macro is made, it's time to use it. Grab a
sky_sphere from the realskies.inc
include library and add some water to get a simple scene. For this, the
pyramid scale factor was raised to 1.2 to give more substance to the
structure. Tweak a bit from here, and render:
Want To Know More?
Looking for a little more on Sierpinski's Triangle (also called
Sierpinski's Gasket)?
Notes And Disclaimers
[1] - These were actually made in Visio by
hand and exported for use here. I know, it's embarrassing.
Published: 10/31/2006
Last Edited: 10/31/2006
Copyright (C) 2006 Mike
Kost
|
|