// Exemplo de arquivo de descricao de cena para POV-ray
// Last edited on 2020-09-30 19:57:13 by jstolfi

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

background{ color rgb < 0.90, 0.80, 0.85 > }
#declare tx_fosca_cinza = 
texture{
pigment{ color rgb < 0.3, 0.3, 0.3 > }
finish{ diffuse 0.9 ambient 0.1 }
}

#declare roleta = seed(1);
#declare NMAX = 50;

// ======================================================================
// FORMAS

#declare raio = 2.000;  // A principio pode-se usar declare ou local
#declare pontoFinalCilindroVertice = <0, 2, 4>;
#declare pontoInicialCilindroVertice = < 0, 0, 3>;

#declare bolaVertice1 =
  sphere{
    < 0, 0, 0 >, 1.2 
    texture{ tx_fosca_cinza }
  }

#declare cilindroVertice1 = 
    cylinder {
        < 0, 0, 0>, <0, 1, 2>, 0.25 // center of one end, center of other end, radius
    }


#declare tanque = 
    cylinder {
        < 0, 0, 0>, <0, 0, 3>, 1 // center of one end, center of other end, radius
    }

#declare coneTanque1 =
    cone {
        <0, 0, 3>, 1 // <x, y, z>, center & radius of one end
        <0, 0, 4.5>, 0 // <x, y, z>, center & radius of the other end
    }

#declare cilindroCortaTanque1 = 
    cylinder {
        < 0, -2, 2.5>, <0, 2, 2.5>, 0.25 // center of one end, center of other end, radius
    }

#declare bolaTanque2 =
  sphere{
    < 0, 0, 3 >, 1.2 
    texture{ tx_fosca_cinza }
  }

#declare cilindroCortaTanque2 = 
    cylinder {
        < 0, 0, 3>, <0, 2, 4>, 0.25 // center of one end, center of other end, radius
    }

#declare quadradoTanque3 =
    box {
        <-0.5, -0.5, 3>, <0.5, 0.5, 4> // <x, y, z> near lower left corner, <x, y, z> far upper right corner
    }

#declare cilindroCortaTanque3 = 
    cylinder {
        < 0, -2, 3.5>, <0, 2, 3.5>, 0.25 // center of one end, center of other end, radius
    }
// ======================================================================
// Objetos

#declare tanque1 = 
  union {
    object{tanque texture{tx_fosca_cinza}}
    object{coneTanque1 texture{tx_fosca_cinza}}
    object{ cilindroCortaTanque1 texture{ tx_fosca_cinza } }
  }

#declare tanque2 = 
  union {
    object{tanque texture{tx_fosca_cinza}}
    object{bolaTanque2 texture{tx_fosca_cinza}}
    object{ cilindroCortaTanque2 texture{ tx_fosca_cinza } }
    object{ cilindroCortaTanque2 rotate <0, 0, 120> texture{tx_fosca_cinza}} 
    object{ cilindroCortaTanque2 rotate <0, 0, 240> texture{tx_fosca_cinza}} 
  }

#declare tanque3 = 
  union {
    object{tanque texture{tx_fosca_cinza}}
    object{quadradoTanque3 texture{tx_fosca_cinza}}
    object{ cilindroCortaTanque3 texture{ tx_fosca_cinza } }
    object{ cilindroCortaTanque3 rotate <0, 0, 90> texture{tx_fosca_cinza}} 
  }

#declare bola1 = 
  union{
    object{bolaVertice1}
    object{cilindroVertice1}
  }



#declare vertice1 = union {
    object{bolaTanque2 texture{tx_fosca_cinza}}
    object{ cilindroCortaTanque2 texture{ tx_fosca_cinza } }
}

#declare vertice2 = union {
    object{bolaTanque2 texture{tx_fosca_cinza}}
    object{ cilindroCortaTanque2 texture{ tx_fosca_cinza } }
    object{ cilindroCortaTanque2 rotate <0, 0, 180> texture{tx_fosca_cinza}} 
}

#declare vertice3 = union {
    object{bolaTanque2 texture{tx_fosca_cinza}}
    object{ cilindroCortaTanque2 texture{ tx_fosca_cinza } }
    object{ cilindroCortaTanque2 rotate <0, 0, 120> texture{tx_fosca_cinza}} 
    object{ cilindroCortaTanque2 rotate <0, 0, 240> texture{tx_fosca_cinza}} 
}

#declare vertice4 = union {
    object{bolaTanque2 texture{tx_fosca_cinza}}
    object{ cilindroCortaTanque2 texture{ tx_fosca_cinza } }
    object{ cilindroCortaTanque2 rotate <0, 0, 90> texture{tx_fosca_cinza}} 
    object{ cilindroCortaTanque2 rotate <0, 0, 180> texture{tx_fosca_cinza}} 
    object{ cilindroCortaTanque2 rotate <0, 0, 270> texture{tx_fosca_cinza}} 
}
// ======================================================================
// Lógica
#macro interpola1(t_, t0, v0, t1, v1)
  #local ss = (t_-t0)/(t1-t0);
  #local vv = (1-ss)*v0+ss*v1;
  vv
#end

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

    #local v012 = interpola1(t_, ta, v01, tb, v12);
    #local v123 = interpola1(t_, ta, v12, tb, v23);

    #local v0123 = interpola1(t_, ta, v012, tb, v123);
    v0123
#end



#macro testa_interpola_1(p0, p1, n, raio)
  union{
    #local i = 0;
    #while(i < n)
      #local j=0;
      #local centro = interpola1(i,j,p0,n,p1);
      object{ sphere {
        centro, raio
        texture{tx_fosca_cinza}
      }}
      #local i = i + 1;
    #end
  }
#end

#macro testa_interpola_3(p0, p1, p2, p3, n, raio)
  union{
    #local i = 0;
    #while(i < n)
      #local j=0;
      #local centro = interpola3(i,j,n, p0,p1,p2,p3);
      object{ sphere {
        centro, raio
        texture{tx_fosca_cinza}
      }}
      #local i = i + 1;
    #end
  }
#end

#macro 
  interpola3_multi(t_, p_in, n, p1, p2, p_fim)
  union {
    #local k = int(t_);

    #while(k<n)
      #if(k = 0)
        #local q0 = p_in;
        #local q3 = (p2[0]+p1[1])/2;
        object{testa_interpola_3(q0, p1[k], p2[k], q3, 100, 0.1)}
      // #end
      #elseif(k = n-1)
        #local q0 = (p2[k-1]+p1[k])/2;
        #local q3 = p_fim;
        object{testa_interpola_3(q0, p1[k], p2[k], q3, 100, 0.1)}
      // #end
      #elseif(k>0 & k<n-1)
        #local q0 = (p2[k-1]+p1[k])/2;
        #local q3 = (p2[k]+p1[k+1])/2;
        object{testa_interpola_3(q0, p1[k], p2[k], q3, 100, 0.1)}
      #end
      #local k = k+1;
    #end
  }
#end

#macro 
  vert_grau_1(point)
    #local vv = union {object{vertice1 translate point}}
    vv
#end

#macro 
  vert_grau_2(point)
    #local vv = union {object{vertice2 translate point}}
    vv
#end

#macro 
  vert_grau_3(point)
    #local vv = union {object{vertice3 translate point}}
    vv
#end

#macro 
  vert_grau_4(point)
    #local vv = union {object{vertice3 translate point}}
    vv
#end

#macro
  gera_grafo(nv, ne, org, dst, D, na, nb)
    #local translate_ponto = array[NMAX]; 
    #local idx_nv = 0;
    #local deg = array[nv];
    #local idx_ne = 0;
    #while(idx_nv<nv)
      #local deg[idx_nv] = 0;
      #local idx_nv = idx_nv+1;
    #end
    #while(idx_ne<=ne)
      #local idx_org = org[idx_ne];
      #local idx_des = dst[idx_ne];
      #local deg[idx_org] = deg[idx_org] + 1;
      #local deg[idx_des] = deg[idx_des] + 1;
      #local idx_ne = idx_ne+1;
    #end


    #local vertice_atual = 0;
    #while(vertice_atual<nv+1)
      #local xx = int(D*rand(roleta)+1);
      #local yy = int(D*rand(roleta)+1);
      #local zz = int(D*rand(roleta)+1);
      #local point = <xx, yy, zz>;
      #local translate_ponto[vertice_atual] = point;
      #if(deg[vertice_atual] = 1)
        union {
          object{vert_grau_1(point)}
        }
      #elseif(deg[vertice_atual] = 2)
        union {
          object{vert_grau_2(point)}
        }
      #elseif(deg[vertice_atual] = 3)
          union {
            object{vert_grau_3(point)}
          }
      #elseif(deg[vertice_atual] = 4)
        union {
          object{vert_grau_4(point)}
        }
      #end
    #end
#end



#macro
  conetor(na, nb, pini, tini, pfin, tfin)
#end


#include "eixos.inc"

union {

  #local nv = 4;
  #local ne = 5; 
  #local org = array[6];
  #local dst = array[6];
  #local org[0] = 0;
  #local org[1] = 2;
  #local org[2] = 2;
  #local org[3] = 3;
  #local org[4] = 1;
  #local org[5] = 3;
  #local dst[0] = 2;
  #local dst[1] = 0;
  #local dst[2] = 1;
  #local dst[3] = 0;
  #local dst[4] = 3;
  #local dst[5] = 3;
  #local D = 10;
  #local na = 3;
  #local nb = 100;
  gera_grafo(nv, ne, org, dst, D, na, nb)
}


#include "camlight.inc"
#declare centro_cena = < 0.00, 0.00, 2.00 >;
#declare raio_cena = 15.0;
#declare dir_camera = < 14.00, 7.00, 4.00 >;
// #declare dir_camera = < 14.00, -4.00, -8.00 >;
#declare dist_camera = 5*raio_cena;
#declare intens_luz = 1.20;
camlight(centro_cena, raio_cena, dir_camera, dist_camera , z, intens_luz)