background{ color rgb < 0.8, 0.8, 0.9 > }

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

#declare tx_plastico_azul = texture {
    pigment { color rgb < 0.05, 0.40, 0.50 > }
    finish { diffuse 0.8 ambient 0.1 specular 0.5 roughness 0.005 }
}

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

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

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

// ======================================================================
// DESCRIÇÃO DOS VÉRTICES

#declare ver_2 = union {
    union {
        sphere {
            < 0, 0, 0>, 2
        }
        cylinder {
            <3, 0, 0>,
            <-3, 0, 0>,
            1
        }
        texture { tx_plastico_azul }
    }
    union {
        sphere {
            <3, 0, 0>, 0.25
        }
        sphere {
            <-3, 0, 0>, 0.25
        }
        texture { tx_plastico_branco }
    }
}

#declare ver_3 = union {
    union {
        cylinder {
            <0, 0, -0.75>,
            <0, 0, 0.75>,
            2
        }
        cone {
            <0, 0, 0.75>, 2.0
            <0, 0, 1.75>, 0
        }
        texture { tx_plastico_azul }
    }
    union {
        sphere {
            <2, 0, 0>, 0.25
        }
        sphere {
            <2, 0, 0>, 0.25
            rotate <0, 0, 120>
        }
        sphere {
            <2, 0, 0>, 0.25
            rotate <0, 0, 240>
        }
        texture { tx_plastico_branco }
    }
}

#declare ver_4 = union {
    union {
        box {
            <-1, -1, -1>,
            <1, 1, 1>
        }
        box {
            <-0.5, -0.5, 1>,
            <0.5, 0.5, 2>
            rotate <0, 0, 45>
        }
        texture { tx_plastico_azul }
    }
    union {
        sphere {
            <1, 0, 0>, 0.25
        }
        sphere {
            <0, 1, 0>, 0.25
        }
        sphere {
            <-1, 0, 0>, 0.25
        }
        sphere {
            <0, -1, 0>, 0.25
        }
        texture { tx_plastico_branco }
    }
}

// ======================================================================
// AJUDA PARA ENCONTRAR AS SAIDAS DOS VERTICES
#macro s_ver_2 (N)
    #local S = <3 + (-6 * N), 0, 0>;
    S
#end

#macro s_ver_3 (N)
    #local inv_x = 0;
    #local inv_y = 0;
    #if (N > 0)
        #local inv_x = 1;
        #local inv_y = 1;
    #end
    #if (N > 1)
        #local inv_y = -1;
    #end
    #local S = <2 + (-3) * inv_x, -2 * 0.866025404 * inv_y, 0>; 
    S
#end

#macro s_ver_4 (N)
    #if (N = 0)
        #local S = <1, 0, 0>;
    #end
    #if (N = 1)
        #local S = <0, 1, 0>;
    #end
    #if (N = 2)
        #local S = <-1, 0, 0>;
    #end
    #if (N = 3)
        #local S = <0, -1, 0>;
    #end

    S
#end

// ======================================================================
// INTERPOLAÇÃO

#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, T0, T1, V0, V1, V2, V3)
    #local v01 = interpola1(T, T0, V0, T1, V1);
    #local v12 = interpola1(T, T0, V1, T1, V2);
    #local v23 = interpola1(T, T0, V2, T1, V3);

    #local v012 = interpola1(T, T0, v01, T1, v12);
    #local v123 = interpola1(T, T0, v12, T1, v23);

    #local v0123 = interpola1(T, T0, v012, T1, v123);

    v0123
#end

#macro interpola3_multi (T, Pi, N, P1s, P2s, Pf)
    #local k = int(T);

    #local Q0 = Pi;
    #local Q3 = Pf;
    #local Q1 = P1s[k];
    #local Q2 = P2s[k];

    #if (k > 0)
        #local Q0 = (P2s[k - 1] + P1s[k]) / 2;
    #end
    #if (k < (N-1))
        #local Q3 = (P1s[k + 1] + P2s[k]) / 2;
    #end

    #local Pt = interpola3(T, k, k+1, Q0, Q1, Q2, Q3);

    Pt
#end

#macro interpola1_teste (P0, P1, N, R)
    union {
        #local i = 0;
        #while (i < N)
            #local centro = interpola1 (i, 0, P0, N, P1);
            sphere {
                centro,
                R
            }
            #local i = i + 1;
        #end
    }
#end

#macro interpola3_teste (P0, P1, P2, P3, N, R)
    union {
        #local i = 0;
        #while (i < N)
            #local centro = interpola3 (i, 0, N, P0, P1, P2, P3);
            sphere {
                centro,
                R
            }
            #local i = i + 1;
        #end
    }
#end

#macro interpola3_multi_draw (Pi, Pf, N_curvas, P1s, P2s, N_pontos, P_raio)
    union {
        #local i = 0;
        #while (i < N_pontos)
            #local T = (i / N_pontos) * N_curvas;
            #local centro = interpola3_multi(T, Pi, N_curvas, P1s, P2s, Pf);
            sphere {
                centro,
                P_raio
            }
            #local i = i + 1;
        #end
    }
#end

// ======================================================================
// CONSTRUINDO

// object{ver_4}

// union {
//     object{ interpola1_teste(<2, -2, 0>, <-2, 2, 0>, 50, 0.1) texture {tx_plastico_vermelho} }

//     object{ interpola3_teste(<2, -2, 0>, <-4, 4, 5>, <4, -4, 4>, <-2, 2, 0>, 150, 0.1) texture {tx_plastico_azul} }
// }

union {
    object { ver_2 rotate <0, 0, 90> translate <5, -5, 0> }

    object { ver_4 translate <-5, 5, 0> }

    object { ver_3 }

    // Testando Pontos de saida
    // object {#local AF = s_ver_2(1); sphere {AF, 0.5} rotate <0, 0, 90> translate <5, -5, 0>}
    // object {#local AF = s_ver_3(2); sphere {AF, 0.5}}
    // object {#local AF = s_ver_4(3); sphere {AF, 0.5} translate <-5, 5, 0>}

    // INTERPOLA 3 direto
    // object { interpola3_teste(<5, -2, 0>, <5, 4, 1>, <10, 5, -1>, <-4, 5, 0>, 200, 0.1) texture {tx_plastico_vermelho} }

    // INTERPOLA 3 multi com 1 curva
    // object {
    //     #declare nn = 1;
        
    //     #declare p1 = array[nn];
    //     #declare p1[0] = <5, 4, 1>;

    //     #declare p2 = array[nn];
    //     #declare p2[0] = <10, 5, -1>;

    //     interpola3_multi_draw (
    //         <5, -2, 0>,
    //         <-4, 5, 0>,
    //         nn,
    //         p1,
    //         p2,
    //         1000,
    //         0.1
    //     )
    //     texture {tx_plastico_vermelho}
    // }

    // INTERPOLA 3 multi com 3 curvas
    object {
        #declare nn = 3;
        
        #declare p1 = array[nn];
        #declare p1[0] = <5, 4, 1>;
        #declare p1[1] = <10, 10, 3>;
        #declare p1[2] = <-5, 20, -2>;

        #declare p2 = array[nn];
        #declare p2[0] = <10, 4, 1>;
        #declare p2[1] = <5, -10, 3>;
        #declare p2[2] = <10, 5, -1>;

        interpola3_multi_draw (
            <5, -2, 0>,
            <-4, 5, 0>,
            nn,
            p1,
            p2,
            1500,
            0.1
        )
        texture {tx_plastico_vermelho}
    }
}

#include "camlight.inc"
#declare centro_cena = < 0.00, 0.00, 0.00 >;
#declare raio_cena = 15.0;
#declare dir_camera = < 1, 1, 1 >;
#declare dist_camera = 5 * raio_cena;
#declare intens_luz = 1.2;
camlight(centro_cena, raio_cena, dir_camera, dist_camera , z, intens_luz)