# Operators

## Affine Operators

ifs.affine3d.matrix {a11,a12,a13,a21,a22,a23,a31,a32,a33}

```x'=a11*x+a12*y+a13*z;
y'=a21*x+a22*y+a23*z;
z'=a31*x+a32*y+a33*z;
```

ifs.affine3d.affine {a11,a12,a13,a21,a22,a23,a31,a32,a33,b1,b2,b3}

```x'=a11*x+a12*y+a13*z+b1;
y'=a21*x+a22*y+a23*z+b2;
z'=a31*x+a32*y+a33*z+b3;
```

ifs.affine3d.affine {a11,a12,a21,a22,b1,b2}

```x'=a11*x+a12*y+b1;
y'=a21*x+a22*y+b2;
```

ifs.affine3d.rotate {ang,vx,vy,vz}

Rotation around vector (vx,vy,vz) by angle "ang" (in radians)

ifs.affine3d.rotate {ang,vx,vy,vz,k1,k2}

Rotation around vector (vx,vy,vz) by angle "ang" (in radians), scale by "k1" along vector, scale by "k2" across vector

ifs.affine3d.rotated

Same as ifs.affine3d.rotate, but angle in degrees

ifs.affine3d.scale{k1,k2,k3}

```x'=k1*x;
y'=k2*y;
z'=k3*z;
```

ifs.affine3d.scale {k}

```x'=k*x;
y'=k*y;
z'=k*z;
```

ifs.affine3d.translate {tx,ty,tz}

```x'=x+tx;
y'=y+ty;
z'=z+tz;
```

## Mobius Operator

ifs.mobius3d.inverse {x,y,z,r}

Inverse relative sphere with radius r and center (x,y,z)

## Compiled Formula Operators

ifs.formula(string)

Formula compiler operator

Example:

```frm=ifs.formula
[[
f(x,y,z) = x/(x+1),y/(y+1),1/(z+1);

g(x,y,z,a,b)=t, x-y,z+b
t=sin(x*a);
]]```

Now, we have two 3D non-linear operators: frm.f() and frm.g(a,b).

Usage:

```OP1=frm.f()
OP2=frm.g(0.4,-0.2)
OP3=frm.g(-1,2.3)
```

Following functions are available:

exp,ln,sin,cos,tan,asin,acos,atan

rnd() - random number from 0 to 1

arg(x,y) - argument of (x+i*y)

x%y - modulus

x?y:z - conditional

x^y - power

logical (value = 0 or 1):

"%%" "||" ">" "<" "==" "!=" ">=" "<=" "!"

## Lua operator

It is possible to use any Lua function as operator.

ifs.luafunc(f:function, nIn: number, nOut: number)

Parameters:

• f: Lua function
• nIn: number of arguments of the Lua function
• nOut: number of values returned by the Lua function

Example:

```function lfunc(x,y,z)
tx,ty,tz=(x+0.5),(y+0.5),(math.sin(x*128)+1)/2;
return tx,ty,tz;
end;

OP=ifs.luafunc(lfunc,3,3);```

Now, operator 'OP' represents transformation from 3D to 3D

## Color Operator

ifs.color {R:number,G:number,B:number}

Set color of the object

0<=R,G,B<=1

Example:

```t=ifs.color {0.5,0.1,0};
```

## Image Operator

ifs.image(img:imImage, interpolation: number)

Transformation from R^2 (plane) to R^4 (RGBA 4D space)

X,Y - > R,G,B,A,

[0,1]x[0,1] - >[0,1]x[0,1]x[0,1]x[0,1]

Can be used as texture, displacement map, height-field and so on.

Parameters:

• img: image (see IM library)
• interpolation: 0 - nearest neighborhood, 1 - bilinear (by default).

Example:

```img=im.FileImageLoad("files\\my_file.jpg",0)
t=ifs.image(img)```

Operator for advanced colorizing (procedure texturing)

Prameters:

• op - arbitrary operator (procedure)

Operator uses first coordinates of the object as input parameters for the texturing procedure.

Example:

```F=ifs.formula
[[
clr(x,y,z)=x+0.5,y+0.5,(sin(x*128)+1)/2 --function that maps x,y,z to R,G,B
]]

Material procedure can return:

• 3 values - R,G,B: diffuse=specular=ambient=(R,G,B)
• 4 values - same as 3 values+shininess
• 6 values - Rd,Gd,Bd, Rs,Gs,Bs : diffuse=(Rd,Gd,Bd) specular= (Rs,Gs,Bs), ambient=diffuse
• 7 values - same as 6 values+shininess
• 9 values - Rd,Gd,Bd, Rs,Gs,Bs, Ra,Ga,Ba: diffuse=(Rd,Gd,Bd) specular= (Rs,Gs,Bs), ambient=(Ra,Ga,Ba)
• 10 values - same as 9 values+shininess

## Mesh Operator

ifs.mesh(filename:string, level:integer)

Returns table of all objects from mesh file.

Parameters:

• filename - name of the obj-file or model itself (as string)
• level - tesselation level

Example:

```t=ifs.mesh("mymesh.obj");
ts1=t.Shape1;-- represents 'Shape1' object in the file```

or

`ts1=t;-- represents 2nd object in the file`

Union of all objects in the mesh file (see 'union' operator description):

```l=ifs.mesh("myfile.obj");
l[#l+1]="+"
allobj=ifs(l)```

Note:

If mesh-file contains texture coordinates, then imported model is a 5-dimensional object (x,y,z,u,v). We can use "ifs.shader" and "ifs.image" operators for texturing these models.

## Intersection Operator

ifs.cutoff()

Intersect object with half space x<=0 (where x - first coordinate in space)

Example:

```F=ifs.formula
[[
ball(x,y,z,r)=x^2+y^2+z^2-r^2
]]
mycut={ifs.resize{-1},ifs.cutoff(),F.ball(0.3),ifs.resize{3}}```

Now 'mycut' operator represents intersection with ball of radius 0.3 and center (0,0,0).

## Identity Operator

ifs{}

Identity operator (empty composition)

## Empty Set

ifs{"+"}

Empty set (empty union)

## Composition Operator

We can create new operator, that represents composition of the several other operators

Example:

```T=ifs{T1,T2,T3,....Tn}
where T1,T2,..Tn - another operators or objects
```

Now T is equal T1(T2(T3(...Tn)..)

Note:

{T1,T2,T3,....Tn} is a standard Lua table (array). We can rewrite previous example as:

```tbl={T1,T2,T3,....Tn}
T=ifs(tbl);```

More over, we can create table in the loop:

```tbl={};
for i=1,20 do --Notice that the indexing into the array starts at 1, not at zero
tbl[i]=ifs.affine3d.scale(i);
end;
T=ifs(tbl);```

For more information see Lua tables tutorial

## Union Operator

We can create new operator, that represents union of the several other operators.

Example:

```T=ifs{T1,T2,T3,....Tn,'+'}
where T1,T2,..Tn - another operators or objects
```

Now T is equal T1 union T2 union .... Tn. See note for 'composition' operator

## Nested operators and equations

Unions and compositions can be combined as nested tables (with arbitrary level of depth).

Example (Hutchinson operator):

Let we have IFS equation S=f1(S) U f2(S) U ... fn(S) where f1,f2..,fn - some previously defined operators. We can write:

```S=ifs{}
S:eq{{f1,S},{f2,S}, ...{fn,S}, "+"} -- union of compositions, nested operator```

Now S represents solution of IFS equation.

We can rewrite this example as:

```HutOp=ifs{f1,f2, ...fn, "+"} --Hutchinson operator
S=ifs{}
S:eq{HutOp,S}-- S is equal to the composition of the HutOp and S```