Difference between revisions of "HowTo:Turn a continuous function into a stepped function"

From POV-Wiki
Jump to navigation Jump to search
m (change int to floor)
Line 19: Line 19:
 
The basic idea behind creating a stepped function is to evaluate the original function in such a way that the values get rounded somehow. We determine how and how much a function gets rounded by specifying how many steps, or intervals, we want for every unit of POV space. We then multiply the function by this number, round it to the nearest integer, and divide the function by the same number you multiplied it by. Let's say we wanted three steps. Then, we would multiply the whole function by three, round it to the nearest integer, and divide by three.
 
The basic idea behind creating a stepped function is to evaluate the original function in such a way that the values get rounded somehow. We determine how and how much a function gets rounded by specifying how many steps, or intervals, we want for every unit of POV space. We then multiply the function by this number, round it to the nearest integer, and divide the function by the same number you multiplied it by. Let's say we wanted three steps. Then, we would multiply the whole function by three, round it to the nearest integer, and divide by three.
  
<source lang=pov>#declare SteppedPattern = function { int(3 * ThePattern(x, y, z)) / 3 };</source>
+
<source lang=pov>#declare SteppedPattern = function { floor(3 * ThePattern(x, y, z)) / 3 };</source>
  
 
Let's interpolate across ten steps instead of three. In this case, do as follows.
 
Let's interpolate across ten steps instead of three. In this case, do as follows.
  
<source lang=pov>#declare SteppedPattern = function { int(10 * ThePattern(x, y, z)) / 10 };</source>
+
<source lang=pov>#declare SteppedPattern = function { floor(10 * ThePattern(x, y, z)) / 10 };</source>
  
 
==Viewing the results==
 
==Viewing the results==
Line 35: Line 35:
  
 
#declare ThePattern = function { x + y };
 
#declare ThePattern = function { x + y };
#declare SteppedPattern = function { int(10 * ThePattern(x, y, z)) / 10 };
+
#declare SteppedPattern = function { floor(10 * ThePattern(x, y, z)) / 10 };
  
 
// Original pattern:
 
// Original pattern:

Revision as of 02:03, 1 July 2008

Overview

Normally, functions are evaluated so that they transition smoothly from start to finish with no apparent pixelation. However, sometimes you want functions to evaluate in such a way such that the interpolation between steps is apparent. For instance, maybe you are rendering the graph of a function and you want to make it obvious to the viewer what the function's intervals are. In this case you want to use a stepped function.

The initial function

Before you can create a stepped function, you have to define the function the stepped function is based upon. For this example we will create a function that is used as a pattern in a pigment. Let's define a simple gradient that extends along the vector, x + y.

#declare ThePattern = function(x, y, z) { x + y }

This is equivalent to a gradient pattern. We could also have used this:

#declare ThePattern = function { pattern { gradient x + y } };

Now that we've defined the initial function we can create the stepped function.

Creating the stepped function

The basic idea behind creating a stepped function is to evaluate the original function in such a way that the values get rounded somehow. We determine how and how much a function gets rounded by specifying how many steps, or intervals, we want for every unit of POV space. We then multiply the function by this number, round it to the nearest integer, and divide the function by the same number you multiplied it by. Let's say we wanted three steps. Then, we would multiply the whole function by three, round it to the nearest integer, and divide by three.

#declare SteppedPattern = function { floor(3 * ThePattern(x, y, z)) / 3 };

Let's interpolate across ten steps instead of three. In this case, do as follows.

#declare SteppedPattern = function { floor(10 * ThePattern(x, y, z)) / 10 };

Viewing the results

The next step is to render the image. For that we will use the following scene which contains our initial function and the stepped version applied to two boxes on a blue background.

#default { finish { ambient 1 } }
background { rgb z * 0.5 }
camera { location <0, 0, -10> look_at 0 angle 35 }

#declare ThePattern = function { x + y };
#declare SteppedPattern = function { floor(10 * ThePattern(x, y, z)) / 10 };

// Original pattern:
box
{
  <-1, -2, 0>, <1, 2, .1>
  pigment
  {
    function { ThePattern(x, y, z) }
    color_map { [0 rgb 0][1 rgb 1] }
    scale 2
  }
  translate -x * 1.1
}

// Stepped pattern:
box
{
  <-1, -2, 0>, <1, 2, .1>
  pigment
  {
    function { SteppedPattern(x, y, z) }
    color_map { [0 rgb 0][1 rgb 1] }
    scale 2
  }
  translate x * 1.1
}

The result should look something like this:

Stepped function pattern.png


The pattern on the left is the original, smooth pattern. The pattern on the right is the same pattern, rounded to ten intervals.