// Exemplo de arquivo de descricao de cena para POV-ray
// Last edited on 2023-10-23 21:10:12 by stolfilocal

// ======================================================================
// Declarações essenciais

background{ color rgb < 0.75, 0.75, 0.85 > }

#declare M = 3;
#declare N = 4;
#declare arraysize = M*N*2;

#declare tubos = array[arraysize]
#declare theSeed = seed(42);

// ======================================================================
// Texturas

#declare tx_tubo = 
  texture{
    pigment{ color rgb < 0.50, 0.50, 0.50 > }
    finish{ diffuse 0.8 ambient 0.1 specular 0.5 roughness 0.005 }
  }

#declare tx_fosca_vermelha = 
  texture{
    pigment{ color rgb < 0.70, 0.10, 0.10 > }
    finish{ diffuse 0.9 ambient 0.1 }
  }

#declare tx_fosca_verde = 
  texture{
    pigment{ color rgb < 0.10, 0.70, 0.10 > }
    finish{ diffuse 0.9 ambient 0.1 }
  }
#declare tx_fosca_azul = 
  texture{
    pigment{ color rgb < 0.10, 0.10, 0.70 > }
    finish{ diffuse 0.9 ambient 0.1 }
  }

#declare tx_fosca_amarela = 
  texture{
    pigment{ color rgb < 0.70, 0.70, 0.10 > }
    finish{ diffuse 0.9 ambient 0.1 }
  }

#declare tx_chao = 
  texture{
    pigment{ color rgb < 0.60, 0.40, 0.40 > }
    finish{ diffuse 0.9 ambient 0.1 }
  }

// ======================================================================
// Formas
#declare tanque1 = sphere{<0,0,1>, 1 texture{tx_fosca_amarela}}
#declare tanque2 = 
  union{
      sphere{<0,0,0.9>, 0.4 texture{tx_fosca_verde}}
      sphere{<0,0,0.4>, 0.5 texture{tx_fosca_verde}}
      cylinder{<-0.7,0,0.4>, <0.7,0,0.4>, 0.1 texture{tx_tubo}}
  }

#declare tanque3 =
  union{
    cone{<0,0,0>, 0.8, <0,0,0.3>, 0.6 texture{tx_fosca_vermelha}}
    cylinder{<0,0,0.3>, <0,0,1.5>, 0.6 texture{tx_fosca_vermelha}}
    cylinder{<-0.7,0,0.4>, <0.7,0,0.4>, 0.1 texture{tx_tubo}}
  }

#declare tanque4 = 
  union{
    cone{<0,0,0>,0.8 , <0,0,0.7>, 0.5 texture{tx_fosca_azul}}
    sphere{<0,0,0.7>, 0.5 texture{tx_fosca_azul}}
    cylinder{<-0.7,0,0.4>, <0.7,0,0.4>, 0.1 texture{tx_tubo}}
  }

// ======================================================================
// Macros

#macro interpola1(ta,t0,v0,t1,v1)
  #local fator = (ta-t0)/(t1-t0);
  #local valor = (fator * v1) + ((1-fator) * v0);
  valor
#end

#macro interpola2(p0,p1,num)
  union{
    #local currentnum = num;
    #while(currentnum > 0)
      #local centro = interpola1(currentnum, 0, p0, num, p1);
      object{sphere{centro, 0.1} texture{tx_tubo}}
      #local currentnum = currentnum - 1;
    #end
  }
#end

#macro interpola3(ta,t0,tf,v0,v1,v2,v3)
  #local v01 = interpola1(ta,t0,v0,tf,v1);
  #local v12 = interpola1(ta,t0,v1,tf,v2);
  #local v23 = interpola1(ta,t0,v2,tf,v3);

  #local v012 = interpola1(ta,t0,v01,tf,v12);
  #local v123 = interpola1(ta,t0,v12,tf,v23);

  #local v0123 = interpola1(ta,t0,v012,tf,v123);
  v0123
#end

#macro interpola4(p0,p1,p2,p3,num)
  union{
    #local currentnum = num;
    #while(currentnum > 0)
      #local centro = interpola3(currentnum, 0, num, p0, p1, p2, p3);
      object{sphere{centro, 0.1} texture{tx_tubo}}
      #local currentnum = currentnum - 1;
    #end
  }
#end

#macro interpola3_multi(ta,tsize,p0,n,ar1,ar2,pf)
  #local k = int(ta);
  #if(k = 0)
    #local q0 = p0;
  #else
    #local q0 = (ar2[k-1] + ar1[k]) /2;
  #end
  #if(k = n-1)
    #local qf = pf;
  #else
    #local qf = (ar2[k] + ar1[k+1]) /2;
  #end
  #local pt = interpola3(ta, k, k+1,q0,ar1[k],ar2[k],qf);
  pt
#end
  
#include "bezpoly.inc"

#macro interpola4_multi(p0,n,ar1,ar2,pf,num)
  #local raio = 0.1;
  union{
    object{ bezpoly_multi(n, p0, ar1, ar2, pf, 0.9*raio) }
    #local currentnum = (num*n)-1;
    #while(currentnum > 0)
      #local centro = interpola3_multi(currentnum/num, num, p0, n, ar1, ar2, pf);
      object{sphere{centro, 0.1} texture{tx_tubo}}
      #local currentnum = currentnum - 1;
    #end
  }
#end

#macro gera_tanques (m, n)
  union{
  #declare currentM = m;
  #while(currentM > 0)
    #declare currentN = n;
    #while(currentN > 0)
      #declare escolha = rand(theSeed);
      #if(escolha < 0.33)
        object{tanque1 translate <currentM*2, currentN*2, 0> }
      #end
      #if(escolha > 0.66)
        object{tanque2 translate <currentM*2, currentN*2, 0>}
      #end
      #if(escolha > 0.33 & escolha < 0.66)
        object{tanque3 translate <currentM*2, currentN*2, 0>}
      #end
      #declare tubos[((currentM-1)*n + (currentN-1))*2] = <(currentM*2)-0.7,currentN*2,0.4>;
      #declare tubos[(((currentM-1)*n + (currentN-1))*2) +1] = <(currentM*2)+0.7,currentN*2,0.4>;
      #declare currentN = currentN - 1;
    #end
    #declare currentM = currentM - 1;
  #end
  }
#end


#macro tubulacao(p,q)
  #local altura = 1 + 2*rand(theSeed);
  #local palto = <p.x,p.y, altura>;
  #local qalto = <q.x,q.y, altura>;
  union{
    object{sphere{p,0.1} texture{tx_tubo}}
    object{sphere{q,0.1} texture{tx_tubo}}
    object{sphere{qalto,0.1} texture{tx_tubo}}
    object{sphere{palto,0.1} texture{tx_tubo}}
    object{cylinder{p, palto, 0.1} texture{tx_tubo}}
    object{cylinder{q, qalto, 0.1} texture{tx_tubo}}
    object{cylinder{palto, qalto, 0.1} texture{tx_tubo}}
  }
#end

#macro gera_tubulacoes()
  union{
    #while(arraysize > 0)
      #local i = int(arraysize*rand(theSeed));
      #local j = int((arraysize-1)*rand(theSeed));
      #if(j>=i)
        #local j = j+1;
      #end
      object{tubulacao(tubos[i],tubos[j])}
      #declare tubos[i] = tubos[arraysize-1];
      #declare tubos[j] = tubos[arraysize-2];
      #declare arraysize = arraysize-2;
    #end
  }
#end

// ======================================================================
//Render

#declare array1 = array[3]
#declare array2 = array[3]

#local pini =        <  1, -1, 1>;

#declare array1[0] = <  3, -5, 1>;
#declare array2[0] = <  0, -3, 4>;

#declare array1[1] = <  5, +1, 0>;
#declare array2[1] = < -5, -1, 4>;

#declare array1[2] = <  4, +5, 2>;
#declare array2[2] = < -5, +3, 1>;

#local pfin =        <  3, +2, 0>;

object{interpola4_multi(pini,3,array1,array2,pfin,1000)}

#include "eixos.inc"
// object{ eixos(5) }

#declare cmin = < -6,-6,-0.5 >;
#declare cmax = < +6,+6,+4.5 >;

box{ cmin-0.1*z, <cmax.x,cmax.y,cmin.z>  texture{ pigment{ color rgb <0.80,0.70,0.60> } finish {diffuse 0.7 ambient 0.3 } } }

#include "camlight.inc"
#declare centro_cena = (cmin + cmax)/2;
#declare raio_cena = 0.5*vlength(cmin - cmax);
#declare dir_camera = < 10.00, 3.00, 4.00 >;
#declare dist_camera = 5*raio_cena;
#declare intens_luz = 1.20;
camlight(centro_cena, raio_cena, dir_camera, dist_camera , z, intens_luz)