// Last edited on 2023-12-23 02:53:21 by stolfi
#include "eixos.inc"
#include "transforms.inc"
// Exemplo de arquivo de descricao de cena para POV-ray
// Last edited on 2023-12-23 02:41:11 by stolfi

// ======================================================================
// CORES E TEXTURAS

background{ color rgb < 0.8, 0.8, 0.8 > }
#declare roleta = seed(1246553);

#declare tx_vertice =
  texture{
    pigment{ color rgb < 0.585, 0.292, 0 > }
    finish{ diffuse 0.9 ambient 0.1 }
  }

#declare tx_tubo =
  texture{
    pigment{ color rgb < 0.01, 1, 0.12 > }
    finish{ diffuse 0.9 ambient 0.1 }
  }

#declare vertice_1 = union { 
    sphere {
        <0, 0, 0>, 1
    }
    cylinder {
      <0, 2, 0>, <0, -2, 0>, 0.5
    }
    texture { tx_vertice }
  }

#macro vertice_2(cx, cy, cz) 
  box {
      <cx-0.5, cy-0.5, cz-0.5>, <cx+0.5, cy+0.5, cz+0.5> 
      texture { tx_vertice }
  }
#end

#macro vertice_3(cx, cy, cz) 
  union {
    polygon { 5, <cx+0.5, cy+0.5, cz-0.5>, <cx-0.5, cy+0.5, cz-0.5>, <cx-0.5, cy-0.5, cz-0.5>, <cx+0.5, cy-0.5, cz-0.5>, <cx+0.5, cy+0.5, cz-0.5> }
    polygon { 4, <cx+0.5, cy+0.5, cz-0.5>, <cx-0.5, cy+0.5, cz-0.5>, <cx, cy, cz+0.5>, <cx+0.5, cy+0.5, cz-0.5> }
    polygon { 4, <cx-0.5, cy+0.5, cz-0.5>, <cx-0.5, cy-0.5, cz-0.5>, <cx, cy, cz+0.5>, <cx-0.5, cy+0.5, cz-0.5> }
    polygon { 4, <cx-0.5, cy-0.5, cz-0.5>, <cx+0.5, cy-0.5, cz-0.5>, <cx, cy, cz+0.5>, <cx-0.5, cy-0.5, cz-0.5> }
    polygon { 4, <cx+0.5, cy-0.5, cz-0.5>, <cx+0.5, cy+0.5, cz-0.5>, <cx, cy, cz+0.5>, <cx+0.5, cy-0.5, cz-0.5> }
    texture { tx_vertice }
  }
#end

#declare vertice_4 = cylinder {
    <0,0,-0.5>, <0, 0, 0.5>, 1 
    texture { tx_vertice }    
}

#macro interpola1(ti, t0, v0, t1, v1)
  #local ss = (ti-t0)/(t1-t0);
  #local vv = (1-ss)*v0 + ss*v1;
  vv
#end

#macro interpola3(ti, ta, tb, v0, v1, v2, v3)
  #local v01 = interpola1(ti, ta, v0, tb, v1);
  #local v12 = interpola1(ti, ta, v1, tb, v2);
  #local v23 = interpola1(ti, ta, v2, tb, v3);
  #local v012 = interpola1(ti, ta, v01, tb, v12);
  #local v123 = interpola1(ti, ta, v12, tb, v23);
  #local v0123 = interpola1(ti, ta, v012, tb, v123);
  v0123
#end

#macro interpola3_multi(ti, n, pini, p1, p2, pfin)
  #local k = int(ti);

  #if (k = 0)
    #local q0 = pini;
  #else 
    #local q0 = (p2[k-1]+p1[k])/2;
  #end

  #local q1 = p1[k];
  #local q2 = p2[k];

  #if (k != n - 1)
    #local q3 = (p2[k]+p1[k+1])/2;
  #else
    #local q3 = pfin;
  #end

  #local pt = interpola3(ti, k, k+1, q0, q1, q2, q3);
  pt
#end
#macro teste_interpola3_multi(n, p0, p1, p2, p3, qtde, raio)
  #local k = 0;
  #while(k < n)
    #local centro = interpola3_multi(k, pin, n, p1, p2, p3);
    object { sphere{ centro, raio texture { tx_tubo } } }
    #local k = k + n / qtde;
  #end
#end

#declare pin = <0, 2, 0>;
#declare pfi = <15, 15, 0>;
#declare p1 = array[3] {<3, 4, 0>, <11, 9, 0>, <13, 12, 0>};
#declare p2 = array[3] {<8, 2, 0>, <14, 10, 0>, <16, 18, 0>};
#declare n = 3;

#macro conetor(na, nb, pini, tini, pfin, tfin)
  #local p1 = array[na]
  #local p2 = array[na]
  #for(p, 0, na-1)
    #local x1 = floor(rand(roleta)*30);
    #local y1 = floor(rand(roleta)*30);
    #local z1 = floor(rand(roleta)*30);
    #local x2 = floor(rand(roleta)*30);
    #local y2 = floor(rand(roleta)*30);
    #local z2 = floor(rand(roleta)*30);

    #local p1[p] = <x1, y1, z1>;
    #local p2[p] = <x2, y2, z2>;
  #end
  #local p1[0] = tini;
  #local p2[na-1] = tfin;


  #local ti = 0;
  #while(ti < na)
    // #debug concat("!!", str(ti, 0, 0), "\n")
    #local centro = interpola3_multi(ti, na, pini, p1, p2, pfin);
    object { sphere{ centro, 0.2 texture { tx_tubo } } }
    #local ti = ti + na/nb;
  #end
#end

#macro gera_grafo(nv, ne, org, dst, D, na, nb) 
  #local vertices = array[nv];
  #local deg = array[nv];

  #for(ie, 0, ne-1)
    #ifdef(deg[org[ie]])
      #local deg[org[ie]] = deg[org[ie]] +1;
    #else
      #local deg[org[ie]] = 1;
    #end
    
    #ifdef(deg[dst[ie]])
      #local deg[dst[ie]] = deg[dst[ie]] +1;
    #else
      #local deg[dst[ie]] = 1;
    #end
  #end

  
  #for(iv, 0, nv-1)
    #debug concat("!!deg[", str(iv, 0, 0), "] = ", str(deg[iv], 0, 0), " \n")

    #local xi = floor(D*rand(roleta));
    #local yi = floor(D*rand(roleta));
    #local zi = floor(D*rand(roleta));

    // #debug concat("!!vertice[", str(iv, 0, 0), "] = <", str(xi, 0, 0), ", ", str(yi, 0, 0), ", ", str(zi, 0, 0), ">\n \n")
    #local vertices[iv] = <xi, yi, zi>;

    // #local vert = vertice_1;

    #switch(deg[iv])                      // prof
      #case (1)                           // prof
        #local vert = vertice_1           // prof
        #break                            // prof
      #case (2)                           // prof
        #local vert = vertice_2(0,0,0)    // prof
        #break                            // prof
      #case (3)                           // prof
        #local vert = vertice_3(0,0,0)    // prof
        #break                            // prof
      #case (4)                           // prof
        #local vert = vertice_4           // prof
    #end                                  // prof
    #object { vert translate vertices[iv]}
  #end
  #for (i, 0, ne-1)
    #local v1 = org[i];
    #local v2 = dst[i];

    #local v1_pos = vertices[v1];
    #local v2_pos = vertices[v2];

    conetor(2, 500, v1_pos, v1_pos, v2_pos, v2_pos)
  #end
#end

#declare nv_grafo = 5;
#declare ne_grafo = 6;

#declare origem = array[6]{0, 0, 2, 3, 4, 3};
#declare destin = array[6]{1, 2, 3, 4, 3, 0};

#declare D = 20;

gera_grafo(nv_grafo, ne_grafo, origem, destin, D, 0, 0)

// object{ eixos(D+3) }

#declare cmin = < 0, 0, 0 >;
#declare cmax = < D, D, D >;

#include "gaiola.inc"
// object{ gaiola(cmin,cmax) }

#declare centro_cena = (cmin + cmax)/2;
#declare raio_cena = 0.50*vlength(cmax-cmin);
#declare dist_camera = 7*raio_cena;

#include "camlight.inc"
#declare dir_camera = < 7, 5, 3 >;
#declare intens_luz = 1.00;
camlight(centro_cena, raio_cena, dir_camera, dist_camera , z, intens_luz)