POV-Ray : Newsgroups : povray.text.tutorials : isomaze tutorial : isomaze tutorial Server Time15 Sep 2024 06:31:36 EDT (-0400)
 isomaze tutorial
 From: Date: 5 Nov 2001 09:44:13 Message:
```
{
"@context": "https://schema.org",
"@type": "DiscussionForumPosting",
"@id": "#is3dutg17gbcfmmh5ij2r05msch59oqus7%404ax.com",
"dateCreated": "2001-11-05T14:44:13+00:00",
"datePublished": "2001-11-05T14:44:13+00:00",
"author": {
"@type": "Person",
"name": ""
}
}
Here is simple isomaze tutorial for POV 3.5. It is described in 3D. Some of
functions (f_torus, f_snoize) are defined in standard include file
"functions.inc". Sorry for enigmatic sentences but it is my poor English. I
expect some isosurface experience from readers :-)

Split 3D space to similiar parts. Simplest part is a box. So, every box should
contain the same content but mirrored. And should be smoothly joined by putting
connections in the center of the boxes. So, at first lets create simplest box in
the center. Centers of the boxes will be joined internally with parts of
toruses.

<SDL>

#include "stdinc.inc"

#declare Major=.5;
#declare Minor=.03;

#declare f_torus_1=function{f_torus(x-Major,y,z-Major,Major,Minor)}
#declare f_torus_2=function{f_torus(x+Major,z,y-Major,Major,Minor)}
#declare f_torus_3=function{f_torus(y+Major,x,z+Major,Major,Minor)}

#declare f_part=function{f_torus_1(x,y,z)|f_torus_2(x,y,z)|f_torus_3(x,y,z)}

isosurface{
function{f_part(x,y,z)}
contained_by{box{-Major Major}}
}

</SDL>

Above is base shape. Now we must repeat this in all directions. We can do it by
going with all coordinates from any value to <-Major,Major> range. So we must
add function for coordinates, increase size of isosurface and change function.

<SDL>
#include "stdinc.inc"

#declare Range=3;
#declare Major=.5;
#declare Minor=.03;

#declare f_coord=function(coord){coord-(floor(coord)+.5)}

#declare f_torus_1=function{f_torus(x-Major,y,z-Major,Major,Minor)}
#declare f_torus_2=function{f_torus(x+Major,z,y-Major,Major,Minor)}
#declare f_torus_3=function{f_torus(y+Major,x,z+Major,Major,Minor)}

#declare f_part=function{f_torus_1(x,y,z)|f_torus_2(x,y,z)|f_torus_3(x,y,z)}

isosurface{
function{f_part(f_coord(x),f_coord(y),f_coord(z))}
contained_by{box{-Range Range}}
}
</SDL>

But it is too regular. So let's flip some of the boxes by mirror coordinates
around its center. But when and how should be this flipped? Let's control it by
noise value for rest of coordinates. To achive constant variation within whole
box noise need floor value for coordinates.

<SDL>
#include "stdinc.inc"

#declare Range=3;
#declare Major=.5;
#declare Minor=.03;

#declare f_coord=function(u,v,coord){
select(f_snoise3d(10*floor(u),10*floor(v),10*floor(coord)),1,-1)*
(coord-(floor(coord)+.5))
}

#declare f_x=function{f_coord(z,y,x)}
#declare f_y=function{f_coord(x,z,y)}
#declare f_z=function{f_coord(y,x,z)}

#declare f_torus_1=function{f_torus(x-Major,y,z-Major,Major,Minor)}
#declare f_torus_2=function{f_torus(x+Major,z,y-Major,Major,Minor)}
#declare f_torus_3=function{f_torus(y+Major,x,z+Major,Major,Minor)}

#declare f_part=function{f_torus_1(x,y,z)|f_torus_2(x,y,z)|f_torus_3(x,y,z)}

isosurface{
function{f_part(f_x(x,y,z),f_y(x,y,z),f_z(x,y,z))}
contained_by{box{-Range Range}}
}
</SDL>

Shape is ready. Now pattern for pigment. At first let's create base 2D pattern
within area <0,0><1,1> For smooth results it should be tileable. I choosed
checkered pattern scaled down to achive equal "squares".

<SDL>

// calc number of rects along x per visible part of torus
#declare YS=8;
#declare XS=int(.25*YS*Major/Minor); // visible part
#declare XS=4*(XS/2=int(XS/2)?XS:XS+1); // whole torus

#declare Pig=pigment{
checker
color rgb 0 color rgb 1
rotate 45*z
scale 1/sqrt(2)
translate -.5
scale <1,.5,1>
scale <1/XS,1/YS,1>
}

</SDL

Now we have to apply this texture to every part of toruses in base box.

<SDL>
#declare Pig1=pigment{
Pig
translate (x+z)*Major
}

#declare Pig2=pigment{
Pig1
matrix<-1,0,0,0,0,1,0,1,0,0,0,0>
}

#declare Pig3=pigment{
Pig1
matrix<0,-1,0,1,0,0,0,0,-1,0,0,0>
}

#declare f_Pig1=function{pigment{Pig1}} // for torus_1
#declare f_Pig2=function{pigment{Pig2}} // for torus_2
#declare f_Pig3=function{pigment{Pig3}} // for torus_3

</SDL>

And now hardest thing: We have to choose what pigment should we apply. We can
use the same functions as for isosurface. We have to choose one with smalest
value.

<SDL>

#declare f_Pig=function{

select(f_torus_1(f_x(x,y,z),f_y(x,y,z),f_z(x,y,z))-f_torus_2(f_x(x,y,z),f_y(x,y,z),f_z(x,y,z)),

select(f_torus_1(f_x(x,y,z),f_y(x,y,z),f_z(x,y,z))-f_torus_3(f_x(x,y,z),f_y(x,y,z),f_z(x,y,z)),
f_Pig1(f_x(x,y,z),f_y(x,y,z),f_z(x,y,z)).gray,
f_Pig3(f_x(x,y,z),f_y(x,y,z),f_z(x,y,z)).gray
),

select(f_torus_2(f_x(x,y,z),f_y(x,y,z),f_z(x,y,z))-f_torus_3(f_x(x,y,z),f_y(x,y,z),f_z(x,y,z)),
f_Pig2(f_x(x,y,z),f_y(x,y,z),f_z(x,y,z)).gray,
f_Pig3(f_x(x,y,z),f_y(x,y,z),f_z(x,y,z)).gray
)
)
}

</SDL>

finally we can apply pigment to the isosurface

<SDL>
isosurface{
function{f_box(f_x(x,y,z),f_y(x,y,z),f_z(x,y,z))}
contained_by{box{-Range Range}}
pigment{function{f_Pig(x,y,z)}}
}
</SDL>

at last we can add a little turbulence to pigments, add turbulenced pigment as
modifier to isosurface function and extend base pigment with gradient. Here is
whole scene with fog and other things.

<SDL>
#version 3.5;

#include "stdinc.inc"

global_settings
{
assumed_gamma 1.0
noise_generator 2
}

#declare N=20;

#local Loc=<0, 0, 0>;
#local Look=Loc+z;
#local Dir=1.5*z;
#local Right=x*image_width/image_height;
#local Angle=15;

camera {
perspective
location  Loc
up        y
right     Right
look_at   Look
angle     Angle
}

light_source {<-30, 30, -30> color rgb 1 shadowless}

#declare Major=.5;
#declare Minor=.03;
#declare YS=8;
#declare XS=int(.25*YS*Major/Minor);
#declare XS=4*(XS/2=int(XS/2)?XS:XS+1);

#declare f_torus_1=function{f_torus(x-Major,y,z-Major,Major,Minor)}
#declare f_torus_2=function{f_torus(x+Major,z,y-Major,Major,Minor)}
#declare f_torus_3=function{f_torus(y+Major,x,z+Major,Major,Minor)}

#declare PigA=function{pigment{
color_map{
[0 color rgb 0]
[.5 color rgb 1]
[1 color rgb 0]
}
}}

#declare PigB=function{pigment{
pigment_map{
[0 color rgb 0]
[.5 color rgb 1]
[1 color rgb 0]
}
}}

#declare PigC=pigment{function{min(PigA(x,y,z).gray,PigB(x,y,z).gray)}}
#declare PigD=pigment{color rgb 0}

#declare Pig1=pigment{
checker
pigment{PigC} pigment{PigD}
rotate 45*z
scale 1/sqrt(2)
translate -.5
scale <1,.5,1>
scale <1/XS,1/YS,1>
translate (x+z)*Major
}

#declare Pig2=pigment{
Pig1
matrix<-1,0,0,0,0,1,0,1,0,0,0,0>
}

#declare Pig3=pigment{
Pig1
matrix<0,-1,0,1,0,0,0,0,-1,0,0,0>
}

#declare f_Pig1=function{pigment{Pig1}}
#declare f_Pig2=function{pigment{Pig2}}
#declare f_Pig3=function{pigment{Pig3}}

#declare f_box=function{f_torus_1(x,y,z)|f_torus_2(x,y,z)|f_torus_3(x,y,z)}

#declare
f_coord=function{select(f_snoise3d(10*floor(x),10*floor(y),10*floor(z)),1,-1)*(z-(floor(z)+.5))}

#declare f_x=function{f_coord(z,y,x)}
#declare f_y=function{f_coord(x,z,y)}
#declare f_z=function{f_coord(y,x,z)}

#declare f_Pig=function{

select(f_torus_1(f_x(x,y,z),f_y(x,y,z),f_z(x,y,z))-f_torus_2(f_x(x,y,z),f_y(x,y,z),f_z(x,y,z)),

select(f_torus_1(f_x(x,y,z),f_y(x,y,z),f_z(x,y,z))-f_torus_3(f_x(x,y,z),f_y(x,y,z),f_z(x,y,z)),
f_Pig1(f_x(x,y,z),f_y(x,y,z),f_z(x,y,z)).gray,
f_Pig3(f_x(x,y,z),f_y(x,y,z),f_z(x,y,z)).gray
),

select(f_torus_2(f_x(x,y,z),f_y(x,y,z),f_z(x,y,z))-f_torus_3(f_x(x,y,z),f_y(x,y,z),f_z(x,y,z)),
f_Pig2(f_x(x,y,z),f_y(x,y,z),f_z(x,y,z)).gray,
f_Pig3(f_x(x,y,z),f_y(x,y,z),f_z(x,y,z)).gray
)
)
}

#declare f_Pig_Turb=function{pigment{function{f_Pig(x,y,z)}turbulence 2*Minor}}

isosurface{

function{f_box(f_x(x,y,z),f_y(x,y,z),f_z(x,y,z))-Minor*f_Pig_Turb(x,y,z).gray/4}
contained_by{box{-N N}}
pigment{
function{f_Pig(x,y,z)}
color_map{
[0 ForestGreen]
[1 GreenYellow]
}
}
rotate <20,30,40>
#if(clock_on)
rotate<
Interpolate(frame_number,initial_frame,final_frame,0,360,0)
,
Interpolate(frame_number,initial_frame,final_frame,0,360,1)
,
Interpolate(frame_number,initial_frame,final_frame,0,360,2)
>
#end
}

background{color GreenYellow/2}

fog {
distance N
color GreenYellow/2
}
</SDL>

I wait for large renders and amazing animations :-)

ABX
--
#declare _=function(a,b,x){((a^2)+(b^2))^.5-x}#default {pigment{color rgb 1}}
union{plane{y,-3}plane{-x,-3}finish{reflection 1 ambient 0}}isosurface{ //ABX
function{_(x-2,y,1)|_((x+y)*.7,z,.1)|_((x+y+2)*.7,z,.1)|_(x/2+y*.8+1.5,z,.1)}
contained_by{box{<0,-3,-.1>,<3,0,.1>}}translate z*15finish{ambient 1}}//POV35
```