// MC930 A, S2 2003
// Autor: Leonel Aguilar Gayard
// RA 009103
// Data 04/09/2003
// Tema: Rede de Pacotes

#include "colors.inc"
#include "metals.inc"

// ======================================================================
// CÂMERA 

// #declare distancia_entre_nos = 7;
#declare distancia_entre_nos = 7 + 2 * sin(2 * pi * clock);

camera {
    
  // location  < 2.0 * distancia_entre_nos, 2.0 * distancia_entre_nos, 5>  // Posição do observador.
  location  < -15, -15, 10>
  // location  <0 , 0, 20>
  // location  <13, 0, 10>
  right     -1.0 * x          // Largura RELATIVA da imagem.
  up        0.75 * y          // Altura RELATIVA da imagem.
  sky       z                 // Qual direção é "para cima"?
  look_at   < 100, 100, 0>    // Para onde a câmera está apontando.
} 
// Nota: os parâmetros "right" e "up" devem ter a mesma proporção
// que os parâmetros ${WIDTH} e ${HEIGHT} no Makefile.

// ======================================================================
// FONTES DE LUZ

light_source {
  0.5 * < +30.0, +10.0, +90.0 >                // Posição da lâmpada.
  color rgb 1.3 * < 1.00, 1.00, 1.00 >         // Intensidade e corda luz.
} 

light_source {
  0.5 * < +10.0, -10.0, +10.0 >                // Posição da lâmpada.
  color rgb 0.8 * < 1.00, 1.00, 1.00 >         // Intensidade e corda luz.
}

light_source {
  0.5 * < 0, -10, 10>                    // Posição da lâmpada.
  color rgb 0.8 * < 1.00, 1.00, 1.00 >   // Intensidade e corda luz.
} 

// ---------------------------------------------------------------------------------
// AQUI TERMINA O ARQUIVO DO PROFESSOR E COMECA O MEU EXERCICIO

#declare pacote_cubico = 
    box {
        <0,0,0>, <1,1,1>
        translate -0.5
        scale 1.3
    }


#declare pacote_t =
    prism {
        linear_sweep
        linear_spline
        0,
        1,
        3,
        <0,0>, <0.5, 0.5>, <1,0>
        pigment { color Red }
    }


#declare virus =
object {
    lathe {
        bezier_spline
        28,
        #declare i = 0;
        #declare OFFSET = 6;
        #while (i < 4)
            <1,0 + i * OFFSET> <0,1 + i * OFFSET> <0,2 + i * OFFSET> <1,3 + i * OFFSET>
            #if (i < 3)
                <1,3 + i * OFFSET> <2,4 + i * OFFSET> <2,5 + i * OFFSET> <1,6 + i * OFFSET>
            #end
            #declare i = i + 1;
        #end
    }
    scale <1, 0.5, 0.3>
    scale 0.3
    translate <0, -1.5, 0>
}



#declare raio_noh = 0.500;
#declare raio_cilindro = raio_noh / 4;
#declare noh = sphere { <0,0,0>, raio_noh }
#declare aresta = cylinder { <0,0,0>, <distancia_entre_nos + 0.5 * raio_noh, 0, 0>, raio_cilindro }
#declare num_nos = 5;
#declare num_pacotes = 10;

#declare semente = seed(31415926535);

object {
    union {
        // este loop coloca os nos da rede
        #declare i = 0;
        #while (i < num_nos)
            #declare j = 0;
            #while (j < num_nos)
                object { noh translate <i * distancia_entre_nos, j * distancia_entre_nos, 0> pigment { color Yellow }}
                #declare j = j + 1;
            #end
            #declare i = i + 1;
        #end
        
        // este loop coloca as arestas horizontais
        #declare i = 0;
        #declare direcao = 1;
        #while (i < num_nos)
            #declare num_cilindros = 0;
            #while (num_cilindros < num_nos - 1)
                object { aresta translate <num_cilindros * distancia_entre_nos, i * distancia_entre_nos, 0>  pigment { color Grey } }
                
                
                #declare my_x = num_cilindros * distancia_entre_nos + 0.5 * distancia_entre_nos;
                // existe uma probabilidade de r % de haver um pacote cubico no ponto medio de aresta horizontal
                #declare r = rand(semente);
                
                #if (r < 0.3)
                    object {
                        pacote_cubico
                        rotate rand(semente)*180*z
                        rotate clock * 180 * z
                        // translate <my_x, i * distancia_entre_nos + 0.5 * clock * distancia_entre_nos, 0>
                        translate <my_x + direcao * 0.5 * clock * distancia_entre_nos, i * distancia_entre_nos, 0>
                        pigment { color rgb <0, 0, 0.7 + 0.3 * clock> }
                    }
                #else #if (r < 0.45)
                    object {
                        virus
                        rotate rand(semente)*180*z
                        // translate <my_x, i * distancia_entre_nos - 0.5 * clock * distancia_entre_nos, 0>
                        translate <my_x - direcao * 0.5 * clock * distancia_entre_nos, i * distancia_entre_nos, 0>
                        pigment { color rgb <0, 0.5 + 0.5 * clock, 0> }
                    }
                #else #if (r < 0.65)
                    object {
                        pacote_t
                        rotate rand(semente)*180*z
                        // translate <my_x, i * distancia_entre_nos + 0.25 * clock * distancia_entre_nos, 0>
                        translate <my_x + direcao * 0.25 * clock * distancia_entre_nos, i * distancia_entre_nos, 0>
                        pigment { color rgb <1, 0, 0> +  0.50 * clock } // somamos branco para clarear o vermelho
                    }
                #end
                #end
                #end
                
                #declare num_cilindros = num_cilindros + 1;
            #end
            #declare i = i + 1;
            #declare direcao = -direcao;
        #end
    
        // este loop coloca as arestas verticais
        #declare i = 0;
            #while (i < num_nos - 1)
            #declare num_cilindros = 0;
                #while (num_cilindros < num_nos)
                    object { aresta rotate 90 * z translate <num_cilindros * distancia_entre_nos, i * distancia_entre_nos, 0>  pigment { color Grey } }
                    #declare num_cilindros = num_cilindros + 1;
                #end
            #declare i = i + 1;
        #end
    }
    // translate -1 * <0.5 * distancia_entre_nos * num_nos, 0.5 * distancia_entre_nos * num_nos, 0>
    // rotate -45 * x
    // rotate 45 * y
    rotate 45 * <1, -1, 0>
    
    // translate +1 * <0.5 * distancia_entre_nos * num_nos, 0.5 * distancia_entre_nos * num_nos, 0>
    
    // rotate 90 * clock * z
}