#include "colors.inc"
#include "shapes.inc"
#include "camlight.inc"

#declare component_color = texture {
  pigment { color rgb <0.2, 0.2, 0.2> }
}

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

#macro interpolate3(A, B, C, D, t0, t1, tt) 
  #local AB = interpolate1(A, B, t0, t1, tt);
  #local BC = interpolate1(B, C, t0, t1, tt);
  #local CD = interpolate1(C, D, t0, t1, tt);

  #local ABC = interpolate1(AB, BC, t0, t1, tt);
  #local BCD = interpolate1(BC, CD, t0, t1, tt);

  #local ABCD = interpolate1(ABC, BCD, t0, t1, tt);
  ABCD
#end

#macro interpolate1_matrix(matrix1, matrix2, matrix_size, c0, c1, cc)
  #local mr = array[matrix_size][4];
  
  #for (i, 0, matrix_size-1, 1)
    #for (j, 0, 3, 1)
      #declare mr[i][j] = interpolate1(matrix1[i][j], matrix2[i][j], c0, c1, cc);
    #end
  #end

  mr
#end

#macro Arc(points_per_arc, A, B, C, D)

  #for (tt, 0.0, 1.0, (1 / points_per_arc) )
    sphere { 
      interpolate3(A, B, C, D, 0.0, 1.0, tt) + TRANSL, 
      0.1 
      texture { component_color }
    }
  #end

  // Prints original points for debugging
  // sphere { A, 0.20  texture { pigment { color rgbt <1, 0.2, 0.2, 0> } } }
  // sphere { B, 0.15  texture { pigment { color rgbt <1, 0.2, 0.2, 0> } } }
  // sphere { C, 0.10  texture { pigment { color rgbt <1, 0.2, 0.2, 0> } } }
  // sphere { D, 0.05  texture { pigment { color rgbt <1, 0.2, 0.2, 0> } } }

#end

#macro Noh(P_matrix, size_P_matrix, points_per_arc)

  #for (i, 0, size_P_matrix-1, 1)

    #declare end1 = (P_matrix[i][2] + P_matrix[mod(i+1, size_P_matrix)][1]) / 2;

    #if (i = 0)
        #declare begin1 = (P_matrix[i][1] + P_matrix[size_P_matrix-1][2]) / 2;
    #else
        #declare begin1 = (P_matrix[i][1] + P_matrix[i-1][2]) / 2;
    #end
    

    // Este é o arco já contendo o alinhamento das tangentes
    Arc(points_per_arc, begin1, P_matrix[i][1], P_matrix[i][2], end1)

    // Este é o arco sem alinhamento das tangentes, apenas com os pontos crus de "M"
    // Arc(100, P_matrix[i][0], P_matrix[i][1], P_matrix[i][2], P_matrix[i][3])

  #end

#end

#declare ARCS_SIZE = 7;

#declare arcs_1 = array[ARCS_SIZE][4];

#declare arcs_1[0][0] = <0, 1, 4>;
#declare arcs_1[0][1] = <0, 2, 6>;
#declare arcs_1[0][2] = <0, 3, 7>;
#declare arcs_1[0][3] = <0, 4, 8>;

#declare arcs_1[1][0] = <0, 4, 8>;
#declare arcs_1[1][1] = <0, 4.5, 6>;
#declare arcs_1[1][2] = <0, 8, 6>;
#declare arcs_1[1][3] = <0, 8, 3>;

#declare arcs_1[2][0] = <0, 6, 3>;
#declare arcs_1[2][1] = <0, 5, 4>;
#declare arcs_1[2][2] = <0, 4, 3>;
#declare arcs_1[2][3] = <0, 5, 0>;

#declare arcs_1[3][0] = <0, 5, 0>;
#declare arcs_1[3][1] = <0, 3, 0>;
#declare arcs_1[3][2] = <0, 3, 2>;
#declare arcs_1[3][3] = <0, 8, 3>;

#declare arcs_1[4][0] = <0, 5, 3>;
#declare arcs_1[4][1] = <0, 8, 4>;
#declare arcs_1[4][2] = <0, 5, 7>;
#declare arcs_1[4][3] = <0, 4, 2>;

#declare arcs_1[5][0] = <0, 5, 0>;
#declare arcs_1[5][1] = <0, 1, 2>;
#declare arcs_1[5][2] = <0, 7, 9>;
#declare arcs_1[5][3] = <0, 7, 3>;

#declare arcs_1[6][0] = <0, 2, 3>;
#declare arcs_1[6][1] = <0, 5, 5>;
#declare arcs_1[6][2] = <0, 2, 5>;
#declare arcs_1[6][3] = <0, 1, 8>;



#declare arcs_2 = array[ARCS_SIZE][4];

#declare arcs_2[0][0] = <0, 2, 2>;
#declare arcs_2[0][1] = <0, 5, 10>;
#declare arcs_2[0][2] = <0, 6, 2>;
#declare arcs_2[0][3] = <0, 1, 3>;

#declare arcs_2[1][0] = <0, 2, 8>;
#declare arcs_2[1][1] = <0, 5, 2>;
#declare arcs_2[1][2] = <0, 1, 2>;
#declare arcs_2[1][3] = <0, 1, 5>;

#declare arcs_2[2][0] = <0, 2, 2>;
#declare arcs_2[2][1] = <0, 8, 4>;
#declare arcs_2[2][2] = <0, 8, 5>;
#declare arcs_2[2][3] = <0, 7, 8>;

#declare arcs_2[3][0] = <0, 4, 7>;
#declare arcs_2[3][1] = <0, 2, 5>;
#declare arcs_2[3][2] = <0, 8, 3>;
#declare arcs_2[3][3] = <0, 9, 5>;

#declare arcs_2[4][0] = <0, 1, 8>;
#declare arcs_2[4][1] = <0, 3, 5>;
#declare arcs_2[4][2] = <0, 3, 3>;
#declare arcs_2[4][3] = <0, 4, 7>;

#declare arcs_2[5][0] = <0, 7, 8>;
#declare arcs_2[5][1] = <0, 4, 6>;
#declare arcs_2[5][2] = <0, 6, 2>;
#declare arcs_2[5][3] = <0, 2, 6>;

#declare arcs_2[6][0] = <0, 1, 5>;
#declare arcs_2[6][1] = <0, 8, 4>;
#declare arcs_2[6][2] = <0, 4, 8>;
#declare arcs_2[6][3] = <0, 5, 2>;    

#declare center = <0.00, 18.00, 5.00>;
#declare scene_radius = 20.0;
#declare camera_direction = <14.00, 5.00, 0.00>;
#declare camera_distance = 5 * scene_radius;
#declare light_intensity = 1.20;

// SCENE

camlight(
  center, 
  scene_radius, 
  camera_direction, 
  camera_distance, 
  z, 
  light_intensity
)

background { color rgb <0.7, 0.7, 0.7> }

#for (cc, 0.0, 1.0, 0.25)
  #declare TRANSL = <0, cc*25, 0>;
  Noh(interpolate1_matrix(arcs_2, arcs_1, ARCS_SIZE, 0.0, 1.0, cc), ARCS_SIZE, 1000)
#end