// Exemplo de arquivo de descricao de cena para POV-ray
// Last edited on 2023-12-23 09:23:42 by stolfi
// Original version by jstolfi
// Moved Around by jevs

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

// background{ color rgb < 0.45, 0.10, 0.20 > }
background{ color rgb < 0, 0, 0 > }

#declare tx_tanque = 
  texture{
    pigment{ color rgb < 0.10, 0.80, 1.00 > }
    finish{ diffuse 0.8 ambient 0.1 specular 0.5 roughness 0.005 }
  }

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

#declare tx_xadrez =
  texture{
    pigment{ checker color rgb < 0.90, 0.95, 0.90 >, color rgb < 0.85, 0.85, 0.85 > }
    finish{ diffuse 0.9 ambient 0.1 }
    scale 5.0
  }

// ======================================================================
// DESCRI��O DA CENA 


#declare roleta = seed(2493);

#declare pipesCoords = array[1000];
#declare coordCounter = 0;

#macro umk( px, py, pz )

  object{
    union {
      sphere {
        <0, 0, 0>, 0.75 // <x, y, z>, radius
        texture {
          tx_tanque
        }
        translate<0, 0, 0.25>
      }
      cylinder {
        <0, 0, 0>, <0, 1, 0>, 0.25 // center of one end, center of other end, radius
        open // remove end caps
        texture {
          tx_cano
        }
      }

    }
    translate <px, py, pz> // <x, y, z>
  }
  #declare pipesCoords[coordCounter] = < px, py + 1 >;
  #declare coordCounter = coordCounter + 1;

#end

#macro doisk( px, py, pz )
  object{
    union {
      union {
        box {
          <-1, -1, -0>, <1, 1, 2>
          texture {
            tx_tanque
          }
        }
        

        cylinder {
          <-1.5, 0, 0.25>, <1.5, 0, 0.25>, 0.25 // center of one end, center of other end, radius
          open // remove end caps
          texture {
            tx_cano
          }
        }
      }
      prism {
          linear_spline
          conic_sweep
          0, 2, 5, // Height 1, Height 2, Number of Points
          <1,1>, <-1,1>, <-1,-1>, <1,-1> //points for outer rim
          <1,1> //points inner rim
          texture {
            tx_tanque
          }
          rotate x*-90
          translate<0, 0, 6>
          scale < 0.5, 0.5, 0.5,> // <x, y, z>
        }

    }
    translate <px, py, pz> // <x, y, z>
  }

  //only one side
  #declare pipesCoords[coordCounter] = < px + 1.5, py >;
  #declare coordCounter = coordCounter + 1;
#end

#macro quatrok( px, py, pz )
  object{
    difference {
      union {
        union {
          torus {
            0.5, .25 // major radius, minor radius
            rotate <90, 0, 0> // <x°, y°, z°>
            texture {
              tx_tanque
            }
            // translate <0, 0, 0.25> // <x, y, z>
          }

          cylinder {
            <-1.5, 0, 0>, <1.5, 0, 0>, 0.15 // center of one end, center of other end, radius
            open // remove end caps
            texture {
              tx_cano
            }
          }

        }

        cylinder {
            <-1.5, 0, 0>, <1.5, 0, 0>, 0.15 // center of one end, center of other end, radius
            open // remove end caps
            texture {
              tx_cano
            }
            rotate <0, 0, 90> // <x°, y°, z°>
        }
      }

      cylinder {
        <0, 0, -1>, <0, 0, 1>, 0.3 // center of one end, center of other end, radius
      }
    }
    translate <px, py, pz> // <x, y, z>
  }

  #declare pipesCoords[coordCounter] = < px + 1.5, py >;
  #declare coordCounter = coordCounter + 1;


#end

#macro tresk( px, py, pz )
  object{
    union {
      union {
        cylinder {
          <0, 0, 0>, <0, 0, 2>, 1 // center of one end, center of other end, radius
          texture {
            tx_tanque
          }  
        }
        cylinder {
          <-1.5, 0, 0.25>, <1.5, 0, 0.25>, 0.25 // center of one end, center of other end, radius
          open // remove end caps
          texture {
            tx_cano
          }
        }
      }
      
      cylinder {
          <0, 0, 0.25>, <1.5, 0, 0.25>, 0.25 // center of one end, center of other end, radius
          open // remove end caps
          texture {
            tx_cano
          }
          rotate <0, 0, 90> // <x°, y°, z°>
      }

    }
    translate <px, py, pz> // <x, y, z>
  }


  #declare pipesCoords[coordCounter] = < px + 1.5, py >;
  #declare coordCounter = coordCounter + 1;
#end

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

//Algoritmo de DeCasteljan
#macro interpola3(tt, ta, tb, v0, v1, v2, v3)
  #local v01 = interpola1(tt, ta, v0, tb, v1)
  #local v12 = interpola1(tt, ta, v1, tb, v2)

  #local v23 = interpola1(tt, ta, v2, tb, v3)

  #local v012 = interpola1(tt, ta, v01, tb, v12)
  #local v123 = interpola1(tt, ta, v12, tb, v23)
  #local v0123 = interpola1(tt, ta, v012, tb, v123)

  v0123
#end

#macro testa_interpola1(p0, p1, n, r)
  #local  k = 0;
  union {
    #while(k < n)
      #local centro = interpola1(k, 0, p0, n, p1);
      sphere {
        centro, r // <x, y, z>, radius
        texture {
          tx_cano
        }
      }
      #local k = k + 1;
    #end
  }

#end


#macro testa_interpola3(p0, p1, p2, p3, n, r)
    #local  k = 0;
  union {
    #while(k < n)
      #local centro = interpola3(k, 1, n, p0, p1, p2, p3);
      sphere {
        centro, r // <x, y, z>, radius
        texture {
          tx_cano
        }
      }
      #local k = k + 1;
    #end
  }
#end

#macro createPaths()
  #local i = 0;
  union {
    #while(i < coordCounter - 1)

      testa_interpola1(pipesCoords[i], pipesCoords[i+1], 100, 0.1)
      #local i = i + 1;
    #end
  }
#end


// N = inteiro
// p1 = array de ponto
// p2 = array de ponto

// pin = ponto
// pf = ponto
#macro interpola3_multi(tt, pin, n, p1, p2, pf)
  #local k = int(tt);

  // para cada k o ponto final muda -> k0 pin = pin || k=n pf =pf
  #local qini = 0;
  #local qf = 0;

  #if(n = 1)
    #local qini = pin;
    #local qf = pf;
  #elseif(k = 0)
    #local qini = pin;
    #local qf = ((p2[k] + p1[k+1]) / 2);
  #elseif(k = n-1)
    #local qini = ((p2[k-1] + p1[k]) / 2);
    #local qf = pf;
  #else
    #local qini = ((p2[k-1] + p1[k]) / 2);
    #local qf = ((p2[k] + p1[k+1]) / 2);
  #end

  //laco e muda o k 
  interpola3(tt, k, k+1, qini  ,p1[k], p2[k], qf )
#end


#macro fazFuncionar()
  #local pini = <0, 0, 0>;
  #local pf = < 2, 3, 0 >;

  #local n = 3; 
  #local p1 = array[n];

  #local p1[0] = < 0, 1, 0>;
  #local p1[1] = < 1, 2, 0>;
  #local p1[2] = < 2, 3, 0>;

  #local p2 = array[n];

  #local p2[0] = < 1, 0, 0>;
  #local p2[1] = < 2, 1, 0>;
  #local p2[2] = < 3, 2, 0>;

  #local i = 0;
  #local balls = 100; 

  union {
    #while(i < n*balls)
      
      #local pt = interpola3_multi(i/balls, pini, n, p1, p2, pf);

      sphere {
        pt, 0.10 // <x, y, z>, radius
        texture {
          tx_cano
        }
      }

      #local i = i + 1;
    #end
  }

#end


// ======================================================================
// ==============================Grafo===================================

// #declare roleta = seed(3453);

#macro geraGrafo(nv, ne, org, dst, D, na, nb)

  #declare deg = array[nv];

  #for(i, 0, nv-1)
    #declare deg[i] = 0;
  #end

  #for(i, 0, ne-1)
    #if(org[i] = dst[i])
      #declare deg[org[i]] = deg[org[i]] + 2;
    #else
      #declare deg[org[i]] = deg[org[i]] + 1;
      #declare deg[dst[i]] = deg[dst[i]] + 1;
    #end
  #end

  union {
    geraVert(nv, D, deg)
  }

#end

#macro geraVert(nv, D, deg)
  
  #local i = 0;

  union { 
    #while(i < nv)
      #local ordz = mod(int(D*rand(roleta)), D);
      #local ordy = mod(int(D*rand(roleta)), D);
      #local ordx = mod(int(D*rand(roleta)), D);
      #local k = deg[i];
      
      #switch(k-1)
        #case(0)
          umk(ordx, ordy, ordz) //trasformar para 3d
          #declare deg[i] = k;
        #break

        #case(1)
          doisk(ordx, ordy, ordz)
          #declare deg[i] = k;
        #break

        #case(2)
          tresk(ordx, ordy, ordz)
          #declare deg[i] = k;
        #break

        #case(3)
          quatrok(ordx, ordy, ordz)
          #declare deg[i] = k;
        #break
      #end

      #local i = i + 1;
    #end
  }
#end

#declare raio = 2.000;
#declare raioIni = 3;

#declare chao = 
  disc {
    <0, 0, 0>, <0, 0, 1>, 200
    texture {
      tx_xadrez
    }
  }

  
#include "eixos.inc"

#declare D = 15;
#declare nv_grafo = 4;
#declare ne_grafo = 6;

#local org = array[ne_grafo] {0, 2, 2, 3, 1, 3};
#local dst = array[ne_grafo] {2, 0, 1, 0, 3, 3};

union{
    // object{ eixos(D + 3.00)}

    // quatrok(0, 0)
    // doisk(0, 0)
    // umk(0, 0)
    // tresk(0,0)

    geraGrafo(nv_grafo, ne_grafo, org, dst, D, 4, 300)

    object{ chao  translate < 0,0,-5 > texture{ tx_xadrez } }
}

#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 = < 10.00, 15.00, 10.00 >;
#declare intens_luz = 1.20;
camlight(centro_cena, raio_cena, dir_camera, dist_camera , z, intens_luz)