Previous:Are POV-Ray Macros a Function or a Macro? Main Index Next:Returning Values Via Parameters
POV-Ray macros have a variety of uses. Like most macros, they provide a parameterized way to insert arbitrary code into a scene file. However most POV-Ray macros will be used like functions or procedures in a traditional programming language. This is especially true because the POV-Ray language has no user-defined functions or procedures. Macros are designed to fill all of these roles.
When the body of a macro consists of statements that create an entire item such as an object, texture, etc. then the macro acts like a function which returns a single value. The Make_Frame
macro example in the section "Invoking Macros" above is such a macro which returns a value that is an object. Here are some examples of how you might invoke it.
union { //make a union of two objects object{ Make_Frame(8,10,7,9,1) translate 20*x} object{ Make_Frame(8,10,7,9,1) translate -20*x} } #declare BigFrame = object{ Make_Frame(8,10,7,9,1)} #declare SmallFrame = object{ Make_Frame(5,4,4,3,0.5)}
Because no type checking is performed on parameters and because the expression syntax for floats, vectors, and colors is identical, you can create clever macros which work on all three. See the sample scene MACRO3.POV
which includes this macro to interpolate values.
// Define the macro. Parameters are: // T: Middle value of time // T1: Initial time // T2: Final time // P1: Initial position (may be float, vector or color) // P2: Final position (may be float, vector or color) // Result is a value between P1 and P2 in the same proportion // as T is between T1 and T2. #macro Interpolate(T,T1,T2,P1,P2) (P1+(T1+T/(T2-T1))*(P2-P1)) #end
You might invoke it with P1
and P2
as floats, vectors, or colors as follows.
sphere{ Interpolate(I,0,15,<2,3,4>,<9,8,7>), //center location is vector Interpolate(I,0,15,3.0,5.5) //radius is float pigment{ color Interpolate(I,0,15,rgb<1,1,0>,rgb<0,1,1>) } }
As the float value I
varies from 0 to 15, the location, radius, and color of the sphere vary accordingly.
There is a danger in using macros as functions. In a traditional programming language function, the result to be returned is actually assigned to a temporary variable and the invoking code treats it as a variable of a given type. However macro substitution may result in invalid or undesired syntax. Note the definition of the macro Interpolate
above has an outermost set of parentheses. If those parentheses are omitted, it will not matter in the examples above, but what if you do this...
#declare Value = Interpolate(I,0,15,3.0,5.5)*15;
The end result is as if you had done...
#declare Value = P1+(T1+T/(T2-T1))*(P2-P1) * 15;
which is syntactically legal but not mathematically correct because the P1
term is not multiplied. The parentheses in the original example solves this problem. The end result is as if you had done...
#declare Value = (P1+(T1+T/(T2-T1))*(P2-P1)) * 15;
which is correct.
Previous:Are POV-Ray Macros a Function or a Macro? Main Index Next:Returning Values Via Parameters