// Fabio de Souza Azevedo - RA 952215 // 2021-11-17 // // TP09 - Tentaculos Tentativos Tateantes // Exemplo de arquivo de descricao de cena para POV-ray // Last edited on 2022-01-06 17:04:36 by stolfi #version 3.7; #include "rand.inc" // ====================================================================== // CORES E TEXTURAS background { color rgb < 0.75, 0.80, 0.85 > } #declare tx_plastico = 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_fosca = texture { pigment { color rgb < 1.00, 0.80, 0.10 > } finish { diffuse 0.9 ambient 0.1 } } #declare tx_espelho = texture { pigment { color rgb < 1.00, 0.85, 0.30 > } finish { diffuse 0.2 reflection 0.7*< 1.00, 0.85, 0.30 > ambient 0.1 } } #declare tx_vidro = texture { pigment { color rgb < 0.85, 0.95, 1.00 > filter 0.70 } finish { diffuse 0.03 reflection 0.25 ambient 0.02 specular 0.25 roughness 0.005 } } #declare tx_verde_escuro = texture { pigment { color rgb <0, 0.5, 0> } //finish { diffuse 0.8 ambient 0.1 specular 0.5 roughness 0.005 } } #declare tx_verde_claro = texture { pigment { color rgb <0, 1.0, 0> } //finish { diffuse 0.8 ambient 0.1 specular 0.5 roughness 0.005 } } #declare tx_azul_escuro = texture { pigment { color rgb<0, 0, 0.5> } //finish { diffuse 0.8 ambient 0.1 specular 0.5 roughness 0.005 } } #declare tx_azul_escuro_espelhado = texture { pigment { color rgb<0, 0, 0.5> } finish { diffuse 0.2 reflection 0.7*<0, 0, 0.5> ambient 0.1 } } #declare tx_verm_escuro = texture { pigment { color rgb<0.5, 0, 0> } //finish { diffuse 0.8 ambient 0.1 specular 0.5 roughness 0.005 } } #declare tx_verm_transp = texture { pigment { color rgbt <1, 0, 0, 0.5> } //finish { diffuse 0.8 ambient 0.1 specular 0.5 roughness 0.005 } } #declare tx_xadrez = texture { pigment { checker color rgb < 0.10, 0.32, 0.60 >, color rgb < 1.00, 0.97, 0.90 > } finish { diffuse 0.9 ambient 0.1 } scale 2.0 } // ====================================================================== // DESCRICAO DA CENA #macro interpola1(tt, tt0,tt1, vv0,vv1) // Interpolacao afim. // Dados dois pontos (tt0,vv0) e (tt1,vv1) do grafico de uma funcao afim (ou // seja, de um polinomio de grau 1 A*tt+B), devolve o valor da funcao para o // argumento generico {tt}. // // Alternativa: devolver diretamente esta expressao // ( (vv0)+(tt-(tt0)) * ((vv1)-(vv0))/((tt1)-(tt0)) ) // #local rr = (tt - tt0)/(tt1 - tt0); #local vv = (1-rr)*vv0 + rr*vv1; vv; #end #macro interpola3(tt, tt0,tt3, vv0,vv1,vv2,vv3) // Calcula um polinomio de grau 3 (cubico) que comeca no ponto (tt0,vv0) e // termina no ponto (tt3,vv3) para o argumento {tt}. // As derivadas no inicio e no fim do intervalo sao determinadas pelos valores // {vv1} e {vv2}, respectivamente. #local vv01 = interpola1(tt, tt0,tt3, vv0,vv1) #local vv12 = interpola1(tt, tt0,tt3, vv1,vv2) #local vv23 = interpola1(tt, tt0,tt3, vv2,vv3) #local vv012 = interpola1(tt, tt0,tt3, vv01,vv12) #local vv123 = interpola1(tt, tt0,tt3, vv12,vv23) #local vv0123 = interpola1(tt, tt0,tt3, vv012,vv123) vv0123 #end #macro segtaculo(m, p0,r0, p1,r1, p2,r2, p3,r3) // Desenha um segmento do tentaculo // {m} = numero de esferas no segmento // {p0} = ponto inicial do segmento // {r0} = raio da esfera no ponto inicial // {p3} = ponto final do segmento // {r3} = raio da esfera no ponto final // // {p1},{r1} = primeiros ponto e raio intermediarios // {p2},{r2} = segundos ponto e raio intermediarios #local i = 0; union { #while (i < m) #local centro = interpola3(i, 0,m, p0,p1,p2,p3); #local raio = interpola3(i, 0,m, r0,r1,r2,r3); sphere { centro, raio } #local i = i + 1; #end } #end #macro tentaculo(m,n,pp,rr) // {m} = numero de esferas por segmento do tentaculo // {n} = numero de segmentos do tentaculo // {pp} = matriz (n x 4) de pontos que definem a curva de Bezier do tentaculo // {rr} = matriz (n x 4) de raios, um para cada ponto da matriz {pp} #local i = 0; union { #while (i < n) segtaculo(m, pp[i][0],rr[i][0], pp[i][1],rr[i][1], pp[i][2],rr[i][2], pp[i][3],rr[i][3]) #local i = i + 1; #end } #end #macro tentaculo_teste(m) // {m} = numero de esferas por segmento do tentaculo #local N_segs = 4; #local mtz_pontos = array[N_segs][4]; #local mtz_raios = array[N_segs][4]; // Intervalos de valores que os pontos podem assumir no plano XY #local max_x = 20.0; #local max_y = 20.0; // Primeiro, cria matrizes com pontos e raios aleatorios #local sx = seed(937); #local sy = seed(2021); #local sr = seed(952215); #local vtc_a_caixa = <0.0, 0.0, 0.0>; #local vtc_b_caixa = <+max_x, +max_y, 0.5*max_x>; #local i = 0; #while (i < N_segs) #local j = 0; #while (j < 4) // rand gera um numero aleatorio entre 0 e 1 #local ale_x = rand(sx); #local ale_y = rand(sy); #local ale_r = rand(sr); #local ponto = ; //#local mtz_pontos[i][j] = ponto; #local mtz_pontos[i][j] = VRand_In_Box(vtc_a_caixa, vtc_b_caixa, sr); // VRand_In_Box deu resultados melhores. Ela devolve vetores aleatorios // dentro da caixa especificada pelos 2 vertices. #local mtz_raios[i][j] = ale_r + 0.2; #local j = j + 1; #end #local i = i + 1; #end // Depois, faz os ajustes para garantir as continuidades de Bezier #local i = 0; #while (i < N_segs) #local j = 0; #while (j < 4) #if (j=3 & i < (N_segs-1)) #local ponto_pre_emenda = mtz_pontos[i][j-1]; #local ponto_pos_emenda = mtz_pontos[i+1][1]; #local ponto = 0.5*(ponto_pre_emenda + ponto_pos_emenda); #local mtz_pontos[i][j] = ponto; #local mtz_pontos[i+1][0] = ponto; #local raio_pre_emenda = mtz_raios[i][j-1]; #local raio_pos_emenda = mtz_raios[i+1][1]; #local raio = 0.5*(raio_pre_emenda + raio_pos_emenda); #local mtz_raios[i][j] = raio; #local mtz_raios[i+1][0] = raio; #end #local j = j + 1; #end #local i = i + 1; #end object { tentaculo(m, N_segs, mtz_pontos, mtz_raios) texture { tx_fosca } } #end #macro tentaculo_animado(m,tt) // {m} = numero de esferas por segmento do tentaculo // {tt} = tempo #local N_segs = 4; #local K = 4; // Numero de quadros-chave da animacao #local T = array[K] { 0.0000, 0.3333, 0.6667, 1.000 } // Seja "qc" um quadro-chave #local QPP = array[K-1][4][N_segs][4] { { // intervalo k=0: entre qc0 e qc1 { // posicao j=0 (calculada): { // segmento n=0: <0,0,0>, <0,0,0>, <0,0,0>, <0,0,0> }, { // segmento n=1: <0,0,0>, <0,0,0>, <0,0,0>, <0,0,0> }, { // segmento n=2: <0,0,0>, <0,0,0>, <0,0,0>, <0,0,0> }, { // segmento n=3: <0,0,0>, <0,0,0>, <0,0,0>, <0,0,0> } }, { // posicao j=1 (derivada inicial, DADA): { // segmento n=0 (p0,p1,p2 dados; p3 calculado): <0,0,0>, <+1,-1.50,0>, <+2,-1.50,0>, <+3,0,0> }, { // segmento n=1 (p0 calculado; p1,p2 dados; p3 calculado): <+3,0,0>, <+4,+0.50,0>, <+5,+0.50,0>, <+6,0,0> }, { // segmento n=2 (p0 calculado; p1,p2 dados; p3 calculado): <+6,0,0>, <+7,+2.50,0>, <+8,+3.0,0>, <+8,0,0> }, { // segmento n=3 (p0 calculado; p1,p2,p3 dados): <+8,0,0>, <+8,+4.0,0>, <+7,-4.5,0>, <+6,0,0> } }, { // posicao j=2 (derivada final, DADA): { // segmento n=0 (p0,p1,p2 dados; p3 calculado): <0,0,0>, <+1,-0.50,0>, <+2,-0.50,1.0>, <+3,0,0> }, { // segmento n=1 (p0 calculado; p1,p2 dados; p3 calculado): <+3,0,0>, <+4,-2.50,0>, <+5,-0.50,2.0>, <+6,0,0> }, { // segmento n=2 (p0 calculado; p1,p2 dados; p3 calculado): <+6,0,0>, <+7,-1.50,0>, <+8,+2.5,3.0>, <+9,0,0> }, { // segmento n=3 (p0 calculado; p1,p2,p3 dados): <+9,0,0>, <+10,-1,0>, <+9.5,-2,0>, <+9,4.0,0> } }, { // posicao j=3 (calculada): { // segmento n=0: <0,0,0>, <0,0,0>, <0,0,0>, <0,0,0> }, { // segmento n=1: <0,0,0>, <0,0,0>, <0,0,0>, <0,0,0> }, { // segmento n=2: <0,0,0>, <0,0,0>, <0,0,0>, <0,0,0> }, { // segmento n=3: <0,0,0>, <0,0,0>, <0,0,0>, <0,0,0> } } }, { // intervalo k=1: entre qc1 e qc2 { // posicao j=0 (calculada): { // segmento n=0: <0,0,0>,<0,0,0>,<0,0,0>,<0,0,0> }, { // segmento n=1: <0,0,0>,<0,0,0>,<0,0,0>,<0,0,0> }, { // segmento n=2: <0,0,0>,<0,0,0>,<0,0,0>,<0,0,0> }, { // segmento n=3: <0,0,0>,<0,0,0>,<0,0,0>,<0,0,0> } }, { // posicao j=1 (dada): { // segmento n=0: <0,0,0>,<0,0,0>,<0,0,0>,<0,0,0> }, { // segmento n=1: <0,0,0>,<0,0,1.0>,<0,0,1.0>,<0,0,0> }, { // segmento n=2: <0,0,0>,<0,0,2.0>,<0,0,2.0>,<0,0,0> }, { // segmento n=3: <0,0,3.0>,<0,0,3.0>,<0,0,3.0>,<0,0,3.0> } }, { // posicao j=2 (dada): { // segmento n=0 (p0,p1,p2 dados; p3 calculado): <0,0,0>, <+1,-0.50,2.0>, <+2,-0.50,3.0>, <+3,0,3.0> }, { // segmento n=1 (p0 calculado; p1,p2 dados; p3 calculado): <+3,0,0>, <+4,+0.50,0.50>, <+5,+0.50,1.0>, <+6,0,2.0> }, { // segmento n=2 (p0 calculado; p1,p2 dados; p3 calculado): <+6,0,0>, <+7,+1.50,1.0>, <+8,+1,0.6>, <+9,0,0> }, { // segmento n=3 (p0 calculado; p1,p2,p3 dados): <+9,0,0>, <+3.0,-1,0>, <+9.5,-2,0>, <+9,0,0> } }, { // posicao j=3 (calculada): { // segmento n=0: <0,0,0>,<0,0,0>,<0,0,0>,<0,0,0> }, { // segmento n=1: <0,0,0>,<0,0,0>,<0,0,0>,<0,0,0> }, { // segmento n=2: <0,0,0>,<0,0,0>,<0,0,0>,<0,0,0> }, { // segmento n=3: <0,0,0>,<0,0,0>,<0,0,0>,<0,0,0> } } }, { // intervalo k=2: entre qc2 e qc3 { // posicao j=0 (calculada): { // segmento n=0: <0,0,0>,<0,0,0>,<0,0,0>,<0,0,0> }, { // segmento n=1: <0,0,0>,<0,0,0>,<0,0,0>,<0,0,0> }, { // segmento n=2: <0,0,0>,<0,0,0>,<0,0,0>,<0,0,0> }, { // segmento n=3: <0,0,0>,<0,0,0>,<0,0,0>,<0,0,0> } }, { // posicao j=1 (dada): { // segmento n=0: <0,0,0>,<0,0,0>,<0,0,0>,<0,0,0> }, { // segmento n=1: <0,0,0>,<0,0,0>,<0,0,0>,<0,0,0> }, { // segmento n=2: <0,0,0>,<0,0,0>,<0,0,0>,<0,0,0> }, { // segmento n=3: <0,0,0>,<0,0,0>,<0,0,0>,<0,0,0> } }, { // posicao j=2 (dada): { // segmento n=0: <0,0,0>,<0,0,0>,<0,0,0>,<0,0,0> }, { // segmento n=1: <0,0,0>,<0,0,0>,<0,0,0>,<0,0,0> }, { // segmento n=2: <0,0,0>,<0,0,0>,<0,0,0>,<0,0,0> }, { // segmento n=3: <0,0,0>,<0,0,0>,<0,0,0>,<0,0,0> } }, { // posicao j=3 (calculada): { // segmento n=0: <0,0,0>,<0,0,0>,<0,0,0>,<0,0,0> }, { // segmento n=1: <0,0,0>,<0,0,0>,<0,0,0>,<0,0,0> }, { // segmento n=2: <0,0,0>,<0,0,0>,<0,0,0>,<0,0,0> }, { // segmento n=3: <0,0,0>,<0,0,0>,<0,0,0>,<0,0,0> } } } }; #local QRR = array[K-1][4][N_segs][4] // Prof: #local sr = seed(952215); #local k = 0; #while (k < K-1) #local jk = 0; #while (jk < 4) #local i = 0; #while (i < N_segs) #local ji = 0; #while (ji < 4) #local QRR[k][jk][i][ji] = 0.05 + 0.15*rand(sr); #local ji = ji + 1; #end #local i = i + 1; #end #local jk = jk + 1; #end #local k = k + 1; #end #local k = 0; #while (k < K-1) #local jk = 0; #while (jk < 4) // Continuidade entre segmentos do quadro [k][jk]: #local i0 = 0; #while (i0 < (N_segs-1)) #local i1 = i0+1; #local QPP[k][jk][i0][3] = (QPP[k][jk][i0][2] + QPP[k][jk][i1][1])/2; #local QPP[k][jk][i1][0] = QPP[k][jk][i0][3]; #local QRR[k][jk][i0][3] = (QRR[k][jk][i0][2] + QRR[k][jk][i1][1])/2; #local QRR[k][jk][i1][0] = QRR[k][jk][i0][3]; // #local ponto_pre_emenda = mtz_pontos[i][j-1]; // #local ponto_pos_emenda = mtz_pontos[i+1][1]; // #local ponto = 0.5*(ponto_pre_emenda + ponto_pos_emenda); // #local mtz_pontos[i][j] = ponto; // #local mtz_pontos[i+1][0] = ponto; // // #local raio_pre_emenda = mtz_raios[i][j-1]; // #local raio_pos_emenda = mtz_raios[i+1][1]; // #local raio = 0.5*(raio_pre_emenda + raio_pos_emenda); // #local mtz_raios[i][j] = raio; // #local mtz_raios[i+1][0] = raio; #local i0 = i0 + 1; #end #local jk = jk + 1; #end #local k = k + 1; #end #local i = 0; #while (i < N_segs) #local ji = 0; #while (ji < 4) // Continuidade entre quadros do ponto [i][ji]: #local k0 = 0; #while (k0 < K-1) #local k1 = mod(k0+1, K-1); #local QPP[k0][3][i][ji] = (QPP[k0][2][i][ji] + QPP[k1][1][i][ji])/2; #local QPP[k1][0][i][ji] = QPP[k0][3][i][ji]; #local QRR[k0][3][i][ji] = (QRR[k0][2][i][ji] + QRR[k1][1][i][ji])/2; #local QRR[k1][0][i][ji] = QRR[k0][3][i][ji]; #local k0 = k0 + 1; #end #local ji = ji + 1; #end #local i = i + 1; #end // Interpola com tempo: #local k = 0; #while (k < K-1) #if ((T[k] <= tt) & (tt <= T[k+1])) #local kt = k; #end #local k = k + 1; #end #local mtz_pontos = array[N_segs][4] #local mtz_raios = array[N_segs][4] #local i = 0; #while (i < N_segs) #local ji = 0; #while (ji < 4) #local mtz_pontos[i][ji] = interpola3 ( tt, T[kt], T[kt+1], QPP[kt][0][i][ji], QPP[kt][1][i][ji], QPP[kt][2][i][ji], QPP[kt][3][i][ji] ); #local mtz_raios[i][ji] = interpola3 ( tt, T[kt], T[kt+1], QRR[kt][0][i][ji], QRR[kt][1][i][ji], QRR[kt][2][i][ji], QRR[kt][3][i][ji] ); #local ji = ji + 1; #end #local i = i + 1; #end // End Prof // #local i = 0; // #while (i < N_segs) // #local j = 0; // #while (j < 4) // // // rand gera um numero aleatorio entre 0 e 1 // // #local ale_x = rand(sx); // // #local ale_y = rand(sy); // // #local ale_r = rand(sr); // // #local ponto = ; // // //#local mtz_pontos[i][j] = ponto; // // // // #local mtz_pontos[i][j] = VRand_In_Box(vtc_a_caixa, vtc_b_caixa, sr); // // // VRand_In_Box deu resultados melhores. Ela devolve vetores aleatorios // // // dentro da caixa especificada pelos 2 vertices. // // // // #local mtz_raios[i][j] = ale_r + 0.2; // // #local j = j + 1; // #end // #local i = i + 1; // #end object { tentaculo(m, N_segs, mtz_pontos, mtz_raios) texture { tx_fosca } } #end #include "eixos.inc" // Aqui está a cena, finalmente: // object { eixos(5.0) } /*// Chao box { <-25, -25, +00>, <+25, +25, -0.5> translate <0,0,-2> texture { tx_xadrez } }*/ #declare M_esferas = 150; object { tentaculo_animado(M_esferas,clock) } #include "camlight.inc" #declare centro_cena = < 4.00, 0.00, 0.00 >; #declare raio_cena = 4.50; #declare dir_camera = <7.0, 7.0, 7.0 >; #declare dist_camera = 5.0*raio_cena; #declare intens_luz = 1.20; camlight(centro_cena, raio_cena, dir_camera, dist_camera , z, intens_luz)