The program uses IFS scripting language to define attractors (fractals)
and 3-dimenstional scene parameters.
General structure of an IFS script file
camera <camera attributes>;
light <light source2 attributes>;
light <light source2 attributes>;
...
background(r,g,b,l); // background color/brightness
<formulas, maps, substitutions>
set s1 = <structure of the set1>;
set s2 = <structure of the set2>;
...
build <structure of the set3> <material1>;
build <structure of the set4> <material2>;
First we will give a working script example, and then explain script notations.
Example. The Koch Snowflake
camera position (0,0,-80) vertical(0,1,0) fov(50);
light color (0,1,0) position (1, 1,-3) shadows(0);
light color (1, 1, 0) position (3,-1,-1) shadows(0);
ambient(1,1,1,.05);
background(0,1,1,0.5); // set background color
s = sqrt(3);
f1 := translate(1/2, 1/2/s,0) * scale(1/s) * rotate(0,0,-1,150);
f2 := translate(1,0,0) * scale(1/s) * rotate(0,0,-1,-150);
f3 := translate(-1/2,s/2,0) * scale(s) * rotate(0,0,-1,30);
f4 := translate(-1/2,-s/2,0) * scale(s) * rotate(0,0,-1,-90);
f5 := translate(1,0,0) * scale(s) * rotate(0,0,-1,150);
set KochCurve = (f1 + f2) KochCurve; // define the Koch curve
set Snowflake = (f3 + f4 + f5) KochCurve;
build Snowflake;
The script defines the Koch Curve consisting of two own scaled down copies
KochCurve = f1(KochCurve) ∪ f2(KochCurve).
Then the Koch Snowflake is defined as the set consisting of three images of the Koch Curve:
Snowflake = f3(KochCurve) ∪ f4(KochCurve) ∪ f5(KochCurve).
Note for explanation about difference between the equals '=' sign and ':=' see substitutions section.
Sets and Maps
A Set here is just a set a points in 3d.
Under a Map we will understand any transformation of sets in the 3d space into other sets.
E.g. map scale(k) contracts all points (x,y,z) into (k*x,k*y,k*z).
Sets in the program are specified by equations like: set S = f1(S) + f2(S) + ... + fn(S);
Here S means a set in 3-dimensional space, the plus sign '+' denotes union of sets,
and f1,...,fn are affine or Mebius maps in 3D space,
each of these is defined as composition of basic maps.
Note that mathematicians use ∪ sign to denote a union of sets,
so the correct mathematical notation for the equation above is:
S = f1(S) ∪ f2(S) ∪ ... ∪ fn(S).
The program uses the plus sign, due to keyboard and character table (ASCII) limititations.
Composion of maps is written with the superposition sign '*'.
For example translate(tx,ty,tz) * scale(k) * M
means contract the set M by factor k and than translate all its points by vector (tx,ty,tz).
Sign of maps superposition can be omitted.
Moreover, associativity rule of '+' and '*' operations can be applied, e.g.: f1*(f2+f3)=f1*f2+f1*f3.
Associativity also works with sets, e.g. S=(f1+f2)S is the same as S=f1(S)+f2(S) .
Example of a Map:
f1 := translate(-1,0,0) * scale(1/2);
Example of a set definition:
Segment = scale(0.5) * (translate(1,0,0) + translate(-1,0,0)) Segment;
Basic Maps of Sets.
Map name | Type* | Description |
id() | S |
Identical motion. |
scale(k) | S |
Contraction to the point of origin with coefficient k. |
scale(kx,ky,kz) | A |
Contraction to the point of origin with coefficients kx,ky,kz along according axes. |
rotate(x,y,z,angle) | S |
Rotation by the angle around an axis passing through the point of origin and point (x,y,z). |
rotate(x,y,z,angle,along,across) | A |
The same rotation as the previous, but additionally with contraction
along the axis by coefficient along and in the plane orthogonal to the axis by coefficient across. |
rotate(angle) | S |
Rotation by the angle around an axis (0,0,1). |
translate(x,y,z) | S |
Translation by vector (x,y,z). |
translate(x,y) | S |
Translation by vector (x,y,0). |
reflect(x,y,z) | S |
Plane reflection with the plane passing through the point of origin an with normal vector (x,y,z). |
matrix(ax,ay,az,bx,by,bz,cx,cy,cz) | A |
Linear transformation by 3x3 matrix:
|
affine2d(ax,ay,bx,by,tx,ty) | A |
Composition of maps translate(tx,ty,0) * matrix(ax,ay,0,bx,by,0,0,0,0).
It's useful to determinate 2-dimensional self-affine fractals. |
stretch(x,y,z,k) | M |
Mebius map transforming a ball with unit radius and with the center at the point of origin into the same ball
and also transferring the point of origin along vector (x,y,z) by the distance k. |
inverse(x,y,z,r) | M |
Inversion with respect to sphere with radius r and center (x,y,z).
This Mebius map changes orientation. |
bound(x,y,z,r) | M |
It's not actually a map, but operator to label the Set, tha it's bound by a ball with radius r
and center (x,y,z). All compositions of Mebius maps which act from this Set to itself must be
contractive on the specified ball. |
empty() | |
Map transforming every set into empty set. It's useful to determine random-generated fractals. |
section(nx,ny,nz,d) | |
Intersects a set with the plane given by equation x*nx+y*ny+z*nz=d. |
*Note: A - affine map, S - similarity map, M - Mebius map.
The program forbids mixing affine maps with Mebius in a same Set definition.
Camera.
The scene appearance essentially depends on location of the camera (observer).
Camera parameters are defined by camera keyword,
with following after it camera attributes.
Attribute | Default value | Description |
position(x,y,z) | required |
The point (x,y,z) defines camera (observer) location. |
direction(x,y,z) | can be calculated automatically |
Vector (x,y,z) defines direction of the view. |
vertical(x,y,z) | required |
Vector (x,y,z) defines vertical direction. |
fov(angle) | 50 degree |
Number angle defines angle of the field of view in vertical plane. |
stereo(eyeDist, scrDist) | 'mono mode' |
This attribute turn on 'stereo mode' (two pictures for two eyes) with parameters:
eyeDist - distance between eyes,
scrDist - distance between viewer and the screen. |
Lighting.
The lighting of the scene is calculated by well known ray-tracing algorithm,
which requires light sorces and specular properties of surfaces (color, reflectivity, e.t.c.) to be defined.
Note: Color/Brightness in the scripting file can be defined in the form of
(r,g,b,lum), where r,g,b is color, and lum is luminescence.
Parameter lum can be omitted, in this case lum=1 will be assumed.
1. Parameters of the scene.
Parameter | Default value | Description |
ambient(r,g,b,lum) | (0,0,0,0) |
Color and brightness of the ambient light. |
background(r,g,b,lum) | Background color and brightness. |
tracing_depth(n) | 0 |
Number of consecutive rays reflections. Can be n=0 (no reflections),1,2,3 ... |
antialiasing(n) | 0 |
Smoothing the pixelization effect. Can be n=0 (turned off),1,2,3 ... |
screen_size(width, heght) | from UI |
Set resulting image dimenstion, ignoring the UI settings. |
reflect_background | off |
Turn on reflection of the background in th fractal. The parameter works only while using rays reflections (tracing_depth>1) |
2. Light sources.
- There are 3 types of light sources supported: "Lamp", "Floodlight", "Sun"
(point source, directional source and parallel source).
- Light source can ba added to the scene by specifying light keyword with following attributes.
- Type of light source is automatically determined by specified attributes.
- Number of light sources in the scene cab be arbitrary, and they can be of any different types.
The following table explains the mining of attributes.
Attribute | Lamp | Floodlight | Sun | Description |
position (x,y,z) | R | R | N/A |
Point (x,y,z) defines light source location. |
direction (dx,dy,dz) | N/A | R | R |
Vector (x,y,z) defines direction, in which the light source shines. |
spot_angles (a1,a2) | N/A | R | N/A |
angles to define spot size for directional light source. |
attenuation (qa,la,ca) |
by default (1,0,0) | N/A |
Coefficient fo quadratic, linear and constant of source light brightness with re respect to destination. |
shadows (1 | 0) |
by default (1) |
1 - source light can be blocked up by objects, 0 - can't be blocked up. |
attachment (1 | 0) |
1 - source light is attached to object coordinate system, or 0 - to the camera coordinate system. |
diffuse (r,g,b,lum) |
One or more attribute of these shall be defined.
Default value is (0,0,0,0) |
Defines color/brightness of scattered light component of the light source. |
specular (r,g,b,lum) |
Defines color/brightness of reflecting component of the light source. |
color (r,g,b,lum) |
Defines color/brightness of the both scattered light and reflecting component of the light source. |
Note: N/A - attribute can't be specified, R - attribute is required.
3. Specular properties of surfaces.
Properties of a surface can be specified just after the build command.
Since the build keyword can be specified more then once,
it is possible to create objects with different colors and properties of surfaces in one scene.
Property | Note | Description |
ambient(r,g,b,lum) |
Arguments can be given in the form of (r,g,b) or (lum) |
Defines color/brightness of the ambient color component. |
diffuse(r,g,b,lum) |
Defines color/brightness of the diffuse color component. |
specular(r,g,b,lum) |
Defines color/brightness of the specular color component. |
color(r,g,b) |
for convinience |
Defines color of the ambient and diffuse components and assigns specular component to (1,1,1). |
metall(r,g,b) | |
Defines metallic surface: sets color of the diffuse and specular component. |
Substitutions
Substitutions are used to simplify Sets and Maps definition. The general notations is
<name> := <value>;
It means that all occurences of the <name> in the script below this line
will be replaced with the <value>.
For example
sum := a + b;
result = sum * 3;
is equivalent to
result = a + b * 3;
Arithmetical expressions
Arithmetical formulas utilize the same syntax as used in C++/Java/Perl/PHP languages.
- Names of variables can consist of characters a-z,A-Z and the underscore character "_"
- Supported real-valued functions:
ln(x), exp(x), sqrt(x), abs(x), sign(x), sin(x), cos(x), atan(x)
atan2(y,x), arg(x,y) - these two functions returns arctg(y/x)
rnd(x) - random number in the [0,x] segment
- Real, logical and bit operations:
= += -= *= /= + - * / , () ?: ++ -- == != < <= > >=
- Predefined constants: PI and E.
Random-generated fractals
When defining IFS (or Digraph-IFS), it's possible to set which maps shoul be selected randomly
from given finite set of maps. Here are the rules to define such random-generated IFS:
- The attractor and each its copy
(a set obtained by IFS maps from the attractor and from other copies),
has a corresponding pseudo-random number.
This number for attractor can be set by calling randState(arg) function
before a build operator, where real-valued arg belongs to the [0,1] segment.
For example: randState(rnd(1));
- The operator (...)%n (where n is an integer)
selects n maps from parenthesis, using pseudo-random number assigned
to the current copy of attractor.
- Operator (...)%n allows to assign to each map a weight (a real positive number),
by placing it into braces after the map.
Weights are used to calculate probabilities for the map selecting operator.
For each map its probability is calculated by dividing its weight
by the total maps weight in the current (...)%n operator.
If a weight was not specified for some map, then it's supposed to be a unity by default.
Example: (f1{2}+f2{3})%1
- If a copy of the atractor of IFS consist of some subcopies, then subcopies
inherit by default the pseuodo-random number from the copy.
But if f|m construction has ben found, then the random number of
the subcopy, obtained from current copy by the f map,
is changed by m-th way, i.e. it's changed by applying pseudo-random
generator which depends on the parameter m.
So, if two map have the same parameter m,
e.g. in (f1|1+f2|1) construction, then copies obtained by applying
f1,f2 maps, will obtain the same pseudo-random number,
and so will be divided by (...)%n operator in the same way.
Control statements
- { operator1; operator2; ... }
Block statement. It executes the sequence of operators, located in braces.
- if(expresion) operator1; [ else оператор2;]
Conditional statement. Executes operator1 if expresion is not
equal to zero, otherwise executes оператор2.
- for(initialization; expresion; iteration) operator;
First executes initialization. Then in a loop
calculates the expresion, and while it is not zero executes operator and iteration.
- while(condition) body;
While condition is not zero executes the body.
- do { body; } while(condition);
Executes the body, then checks the condition,
and while it is not zero repeats executing the body.
- echo <variables and strings>;
Print to the output log the variables and the text located in double quotes,
all arguments should be delimited by comma or spaces.
Angles measurement units
angles ( degree | radian ) - sets the angles measurement units,
this parameter affects fov, rotate, spot_angles and trigonometrical functions.
Default value: degree.
Animation
To save an animation frame, save_frame() function is used.
To save a sequence of frames, use a repetitive operator.