// Question 3

// Au choix on peut soit tout faire dans une seule fonction ou soit, de façon modulaire, découper notre code en plusieurs fonctions
// Je choisis ici la seconde méthode en faisant d'abord une fonction pour calculer les delta^k(Pi)
// La fonction delta prend en paramètre une liste de points P et un entier k et elle renvoit la liste des delta^k(Pi)

// On peut coder cette fonction de manière itérative ou récursive. Je propose ici les deux versions : delta pour l'iterative et deltar pour la récursive.

// Version itérative (avec une boucle)
function L=delta(P,k)
    
    // on détermine le nombre de points de la liste P
    s=size(P)
    n=s(2)
    
    // On initialise L à P qui correspond à delta^0(P)
    L=P
    
    // A la fin de chaque tour de boucle il y aura les delta^l(P) dans L
    for l=1:k
        T=[]
        for j=1:n-l
            T=[T,L(:,j+1)-L(:,j)]
        end
        L=T
    end
    
endfunction

// Version récursive
function L=deltar(P,k)
    
    if k == 0
        L=P
    else
        T=[]
        L=deltar(P,k-1)
        s=size(L)
        n=s(2)
        for j=1:n-1
            T=[T,L(:,j+1)-L(:,j)]
        end
        L=T
    end
    
endfunction


// On réutilise la fonction binome de la dernière fois
function r=binom(k,n)

    if k > n/2
        k=n-k
    end
    p1=1
    for i=2:k
        p1=p1*i
    end
    p2=1
    for i=n-k+1:n
        p2=p2*i
    end
    r=p2/p1
endfunction

// On peut alors facilement faire la fonction demandée
function M = deriveBezier(P,k,m)
    M=[]
    
    D=delta(P,k)
    s=size(D)
    n=s(2)-1
        
    for i=1:m+1
        s=[0;0]
        for j=0:n
            s=s+binom(j,n)*((i-1)/m)^j*(1-(i-1)/m)^(n-j)*D(:,j+1)
        end
        s=factorial(n)/factorial(n-k)*s
        M=[M,s]
    end
endfunction


// Question 5

function Casteljau(P,d)
    
    s=size(P)
    n=s(2)
    
    stop=1
    
    for i=1:n-1
        if (P(1,i)-P(1,i+1))^2 + (P(2,i)-P(2,i+1))^2 > d^2
            stop=0
        end
    end
    
    if stop == 1
        xpoly(P(1,:),P(2,:),"lines");
    else
        ListP=P
        L1=P
        for j=1:n
            L2=zeros(2,n)
            for i=1:n-j
                L2(:,i)=(L1(:,i)+L1(:,i+1))/2
            end
            ListP=[ListP;L2]
            L1=L2
        end
        
        P1=[]
        P2=[]
        
        for i=1:n
            s1=[ListP(2*i-1,1);ListP(2*i,1)]
            P1=[P1,s1]
            s2=[ListP(2*i-1,n+1-i);ListP(2*i,n+1-i)]
            P2=[P2,s2]
        end
        
        Casteljau(P1,d)
        Casteljau(P2,d)
    end
    
endfunction

