2.2. Expressions
Prev | Chapter 2. MegaPOV References | Next

## 2.2. Expressions

### 2.2.1. Language directives

#### 2.2.1.1. Set directive

### Chris Huff

The `#set` keyword modifies the most recently created version of a variable. So, if a variable has been created previously with either `#declare` or `#local`, its value can be changed with the `#set` directive.

Example 2.2. Using the #set directive

    #declare MyCounter = 0:
    #set MyCounter = MyCounter + 1;

One advantage is that it makes it more visually clear where variables are 'created', and where they are only 'changed'.

Another advantage is that if you try to change a variable that doesn't yet exist, it produces an error. This could happen if you make a typing mistake, like this:

    #declare MyCounter = 0;
    #while (MyCounter < 10)
      #declare MyCountr = MyCounter+1;
    #end

This would normally cause an infinite loop, and may take a while to track down, especially in complex scenes and with typos that "look right" at a glance. If `#set` was used, it would cause an error ("#set cannot assign to uninitialized identifier MyCountr.") at that line, pointing you directly at the problem.

### 2.2.2. Built-in tokens

#### 2.2.2.1. Additional tokens in function syntax

### Włodzimierz ABX Skiba

POV-Ray™ 3.5 in its official release does not accept all built-in constants and variables to be used in functions. Following tokens are recognized additionally in VM since MegaPOV 1.0: `clock_delta`, `clock_on`, `false`, `final_clock`, `final_frame`, `frame_number`, `initial_clock`, `initial_frame`, `image_height`, `image_width`, `no`, `off`, `on`, `true`, `version`, `yes` . All mentioned tokens return the same values as in the whole SDL parser.

#### 2.2.2.2. `frame_step` key-word

### Włodzimierz ABX Skiba

As other animation options, also `Frame_Step` has its own equivalent in SDL. You can use the `frame_step` key-word to get the value which was passed to `Frame_Step` (see Section 2.1.1). Default value is 1.

### 2.2.3. Functions

#### 2.2.3.1. Time and date functions

### Yvo Smellenbergh

With the keyword `date`, time and/or a date can be used in your images. This might be useful in a macro to place a time stamp in your images, along with your name. The keyword `date` works like other string functions, except that you have to supply a format string.

Example 2.3. `date` function usage

Suppose it's Saturday 1 January. The following script:

    #declare TheString=date("%a %B")

will return the string: Sat January

The most flexible implementation was chosen (which is probably not the easiest ...) because not all countries write dates in the same way. Just think of the difference between the USA and most parts of Europe. These are the possible specifiers for the format string: Please note that these should be equal for all platforms but if you don't get the expected result, contact the person who compiled your version to find out if there are differences.

Table 2.1. The following time formatting strings are available:

a | Abbreviated weekday name.
A | Full weekday name.
b | Abbreviated month name.
B | Full month name.
c | The strftime() format equaling the format string of "%x %X".
d | Day of the month as a decimal number.
H | The hour (24-hour clock) as a decimal number from 00 to 23.
I | The hour (12-hour clock) as a decimal number from 01 to 12
j | The day of the year as a decimal number from 001 to 366
m | The month as a decimal number from 01 to 12.
M | The minute as a decimal number from 00 to 59.
p | "AM" or "PM".
S | The seconds as a decimal number from 00 to 59.
U | The week number of the year as a decimal number from 00 to 52. Sunday is considered the first day of the week.
w | The weekday as a decimal number from 0 to 6. Sunday is (0) zero.
W | The week of the year as a decimal number from 00 to 51. Monday is the first day of the week.
x | The date representation of the current locale.
X | The time representation of the current locale.
y | The last two digits of the year as a decimal number.
Y | The century as a decimal number.
z | The time zone name or nothing if it is unknown.
% | The percent sign is displayed.

| Note:
To use the '%' character in the result, use it twice: `date`("%%")

Refer to `date.pov` for an example scene. Please note that you might have to write the result in a file if you want to abort the rendering and continue later on. Otherwise you could get a different result because time goes on :-)

#### 2.2.3.2. Timer function

### Yvo Smellenbergh

The keyword `start_chrono` sets an internal variable and returns the current internal clock counter of your computer. The return value is not important. However, you must assign this return value from `start_chrono` otherwise you get an error. Use it like this:

    #declare Stopwatch = start_chrono;

or use it like this:

    #if (start_chrono)

but not:

    start_chrono //parsing stops with a fatal error

The keyword `current_chrono` returns the time in full seconds (no fractions of seconds) between `start_chrono` and `current_chrono`. The start value is not changed. A second `current_chrono` will still return the seconds between `start_chrono` and the second `current_chrono`.

If you don't call `start_chrono` somewhere before you call `current_chrono`, you will get the seconds elapsed since the beginning of the current render (parsing).

Example 2.4. Using the timer function

    //reset the chrono and return the internal clock counter
    #declare ParseStart = start_chrono;

    ... syntax to be parsed

    //read the seconds elapsed since chrono_start
    #declare ParseEnd = current_chrono;
    #debug concat("\nParsing took ",str((ParseEnd, 1, 0)," seconds\n")

Refer to `chrono.pov` for a demo scene.

### 2.2.4. Internal functions

MegaPOV delivers new pre-defined functions. These new internal functions can be accessed through the `mp_functions.inc` include file, so it should be included in your scene.

#### 2.2.4.1. `f_triangle`

### Włodzimierz ABX Skiba

`f_triangle` function has 10 parameters:

`FLOAT f_triangle(`FLOAT V1x, FLOAT V1y, FLOAT V1z, FLOAT V2x, FLOAT V2y, FLOAT V2z, FLOAT V3x, FLOAT V3y, FLOAT V3z, FLOAT Thickness`)`;

The parameters `V1x`, `V1y`, `V1z` describe the coordinates of the first vertex in the triangle.

The parameters `V2x`, `V2y`, `V2z` describe the coordinates of the second vertex in the triangle.

The parameters `V3x`, `V3y`, `V3z` describe the coordinates of the third vertex in the triangle.

The parameter `Thickness` describes how thick the triangle is.

| Note
In order to achieve the fastest calculation, try to pass the parameters so that the side `V1`-`V2` represents the longest side and `V1`-`V3` represents the shortest side.

### 2.2.5. Polynomial solver in parser

### Włodzimierz ABX Skiba

The polynomial solver is accessible from scripts via the float functions `n_roots` and `nth_root` with the following syntax:

`INT n_roots(`FLOAT an, ..., FLOAT a0, BOOL sturm_flag, FLOAT epsilon`)`;

`FLOAT nth_root(`FLOAT nth, FLOAT an, ..., FLOAT a0, BOOL sturm_flag, FLOAT epsilon`)`;

`n_roots` returns the number of roots derived from the polynomial given by the parameters `an`, `...`, `a0` and calculated under the conditions specified by the parameters `sturm_flag` and `epsilon`.

`nth_root` returns the value of the `nth` root of a given polynomial.

The sturm flag turns on a different algorithm of calculation. Its usage influences the number of returned roots. Epsilon (positive) value means that the roots below Epsilon value are ignored. Epsilon=0 means that none of the roots are ignored.

| Important
You don't have to call `n_roots` before `nth_root`, but if you do call `nth_root` with the wrong root number then it causes an error and breaks parsing. It is better to call `n_roots` first to verify the number of available roots.

Example 2.5. Polynomial solver usage

Imagine that we have x3+6*x2-x-6 and that we are interested in its roots for further calculations. So if we declare:

    #declare N=n_roots(1, 6, -1, -6, off, 0);

then N has value 3 because the mentioned equation has 3 roots. If we are interested in what roots it has, we can use the following calls:

    #declare R0=nth_root(0, 1, 6, -1, -6, off, 0);
    #declare R1=nth_root(1, 1, 6, -1, -6, off, 0);
    #declare R2=nth_root(2, 1, 6, -1, -6, off, 0);

And it returns R0=-6, R1=1 and R2=-1. So finally we know that x3+6*x2-x-6=(x+6)*(x-1)*(x+1) .

### 2.2.6. Splines

#### 2.2.6.1. `spline` follows `sor`

### Włodzimierz ABX Skiba

Splines in POV-Ray™ can be used to create objects by its rotation, translation or being a border of surface. Usually it is hard to follow those surfaces with calculations developed in SDL because they are mostly hard coded within the source core code of POV-Ray™. The `spline` feature introduced in POV-Ray™ 3.5 makes such operations much easier but some spline types are still missing. `sor_spline` is introduced to access the surface of the `sor` object in SDL.

To use the data from the `sor` object in `sor_spline`, the order of coordinates has to be changed. The old `y` coordinate is now the clock value in the spline. The advantage is that one `sor_spline` can hold data from five old `sor`-s. That's because every `spline` can operate up to five dimensions along the clock value.

Example 2.6. Conversion from `sor` object definition to `sor_spline` type in `spline`

    spline{
       sor_spline
      -1.000000,0.000000*x
       0.000000,0.118143*x
       0.540084,0.620253*x
       0.827004,0.210970*x
       0.962025,0.194093*x
       1.000000,0.286920*x
       1.033755,0.468354*x
    }

    sor{
      7
      <0.000000, -1.000000>
      <0.118143,  0.000000>
      <0.620253,  0.540084>
      <0.210970,  0.827004>
      <0.194093,  0.962025>
      <0.286920,  1.000000>
      <0.468354,  1.033755>
    }

#### 2.2.6.2. Spline accessed like array

### Włodzimierz ABX Skiba

Since MegaPOV 1.0 it is possible to read values stored in `spline` with a notation similar to the `array`. Previously once `spline` was declared, it was only possible to evaluate it for a specified argument. Now two new usages are possible: you can get the number of entries and read the exact values placed in splines.

    SPLINE_USAGE:
      SPLINE_EVALUATION | SPLINE_MEASUREMENT | SPLINE_ENTRY

    SPLINE_EVALUATION:
      #declare Spline_Value = MySpline(Val);
      #declare Spline_Value = MySpline(Val, SPLINE_TYPE);

    SPLINE_MEASUREMENT:
      #declare Number_Of_Entries = dimension_size( MySpline );

    SPLINE_ENTRY:
      #declare Float_Time_Parameter = MySpline[ Counter ][ 0 ];
      #declare Vector_Value_Of_Entry = MySpline[ Counter ][ 1 ];

#### 2.2.6.3. Fix for splines in function usage

The spline function evaluator in POV-Ray™ 3.5 for functions assumes that only 3D vectors are used there. This is fixed in MegaPOV 1.0.

Prev | Up | Next
Chapter 2. MegaPOV References | Home | 2.3. Objects