Ejemplo n.º 1
0
def Shamos_bis(E):
    n = len(E)
    if n < 4:
        return polar_quicksort(E, find_min(E))
    else:
        E1, E2 = Division(E)
        return Fusion(Shamos_bis(E1), Shamos_bis(E2))
Ejemplo n.º 2
0
def graham(points):

    # initialiser le pivot p
    y = [y[1] for y in points]
    x = [x[0] for x in points]
    indices = [i for i, n in enumerate(y) if n == min(y)]
    min_x = 999
    for k in indices:
        if x[k] < min_x:
            pivot = points[k]
            min_x = x[k]

    #placer le pivot en derniere position
    L = [i for i in points]
    L[len(L) - 1], L[points.index(pivot)] = L[points.index(pivot)], L[len(L) -
                                                                      1]

    #trier la liste suivant les angles faits avec le pivot
    Lnew = polar_quicksort(L, pivot)
    for i in range(0, len(Lnew) - 2):
        if i + 1 < len(Lnew):
            if polar_angle(pivot, Lnew[i]) == polar_angle(pivot, Lnew[i + 1]):
                if distance(pivot, Lnew[i]) > distance(pivot, Lnew[i + 1]):
                    del Lnew[i + 1]
                else:
                    del Lnew[i]
    #initialiser l'enveloppe
    hull = list(Lnew)
    n = len(Lnew)
    hull = []
    hull.append(Lnew[0])
    hull.append(Lnew[1])
    hull.append(Lnew[2])
    for i in range(2, n):
        while (True):
            d = determinant(Lnew[i], hull[-1], hull[-2])
            if d < 0:  # if it makes left turn
                break
            else:  # if it makes non left turn
                hull.pop()
            if len(hull) < 3:
                break
        hull.append(Lnew[i])
    return hull
Ejemplo n.º 3
0
def Fusion(E1, E2):
    n1, n2 = len(E1), len(E2)
    #on récupère les pivots des deux listes : ce sont les premiers éléments (car d'angle nul avec lui-même)
    p1, p2 = E1[0], E2[0]
    #on choisit comme pivot le point situé le plus bas (on évite ainsi d'avoir un point intérieur comme pivot)
    #pour cela on distingue le ca où le pivot est p1 et le cas où on  prend p2
    if p1[0] < p2[0]:
        #on commence par chercher l'élément de E2 de plus petit angle avec p1
        #et on cherche en même temps l'élément de plus grand angle avec p1
        m = p2
        min_a = polar_angle(m, p1)
        M = p2
        max_a = polar_angle(M, p1)
        for k in range(n2):
            if polar_angle(E2[k], p1) < min_a:
                m = E2[k]
                min_a = polar_angle(E2[k], p1)
                #on récupère les deux positions
            if polar_angle(E2[k], p1) > max_a:
                M = E2[k]
                max_a = polar_angle(E2[k], p1)
        min_i = E2.index(m)
        max_i = E2.index(M)
        #on supprime les éléments contenus dans le plus grand angle avec le pivot
        if max_i < min_i:
            del E2[max_i + 1:min_i]
        else:
            del E2[0:min_i]
            del E2[max_i + 1:len(E2)]
        #on réarrange la deuxième liste pour que ses éléments soient triés par angles croissants par rapport à p1
        #pour ce faire on met le minimum m en premier et on garde le reste de
        n1 = len(E1)
        n2 = len(E2)
        min_i = E2.index(m)
        E2 = E2[min_i:] + E2[:min_i]
        #on peut maintenant fusioner les deux listes sur le même principe que le tri fusion
        #on conserve une liste trié avec un algorithme en O(n)
        E = [E1[0]]
        k = 1
        l = 0
        E2 = polar_quicksort(E2, p1)
        while k < n1 and l < n2:
            if polar_angle(E1[k], E[0]) < polar_angle(E2[l], E[0]):
                E.append(E1[k])
                k += 1
            else:
                E.append(E2[l])
                l += 1
        #on complète avec les éléments restant de la liste E1 ou E2
        while k < n1:
            E.append(E1[k])
            k += 1
        while l < n2:
            E.append(E2[l])
            l += 1
    else:  #on traite le second cas avec le même principe que le premier
        m = p1
        min_a = polar_angle(m, p2)
        M = p1
        max_a = polar_angle(M, p2)
        for k in range(n1):
            if polar_angle(E1[k], p1) < min_a:
                m = E1[k]
                min_a = polar_angle(E1[k], p2)
                #on récupère la position dans E1 de l'élément d'angle minimal avec p1
                #et la position de celui d'angle maximal
            if polar_angle(E1[k], p2) > max_a:
                M = E1[k]
                max_a = polar_angle(E1[k], p2)
        min_i = E1.index(m)
        max_i = E1.index(M)
        if max_i < min_i:
            del E1[max_i + 1:min_i]
        else:
            del E1[0:min_i]
            del E1[max_i + 1:len(E1)]
        n1 = len(E1)
        n2 = len(E2)
        #on réarrange la deuxième liste pour que ses éléments soient triés par angles croissants par rapport à p1
        #pour ce faire on met le minimum m en premier et on garde le reste de
        min_i = E1.index(m)
        E1 = E1[min_i:] + E1[:min_i]
        #on peut maintenant fusioner les deux listes sur le même principe que le tri fusion
        #on conserve une liste trié avec un algorithme en O(n)
        E = [E2[0]]
        k = 0
        l = 1
        E1 = polar_quicksort(E1, p2)
        while k < n1 and l < n2:
            if polar_angle(E1[k], E[0]) < polar_angle(E2[l], E[0]):
                E.append(E1[k])
                k += 1
            else:
                E.append(E2[l])
                l += 1
        #on complète avec les éléments restant de la liste E1 ou E2
        while k < n1:
            E.append(E1[k])
            k += 1
        while l < n2:
            E.append(E2[l])
            l += 1
    #print("E à la fin du fusion : ")
    #print(E)
    #print("\n")
    #on a bien une liste E triée par angle polaire en fontion de E[0]
    return E
Ejemplo n.º 4
0
def EddyFloyd(E, show=True, save=False, detailed=False):
    g, d, E1, E2 = points_max(E)
    #on coupe notre liste en deux
    E1 = point_up(E1, g, d)
    E2 = point_low(E2, g, d)
    return (polar_quicksort(E1 + E2, d))
Ejemplo n.º 5
0
def Fusion(E1,E2):
    n1,n2=len(E1),len(E2)
    #on récupère les pivots des deux listes : ce sont les premiers éléments (car d'angle nul avec lui-même)
    p1,p2=E1[0],E2[0]
    if p1[0]<p2[0]:
        #on commence par chercher l'élément de E2 de plus petit angle avec p1
        m=p2
        min_a=polar_angle(m,p1)
        for k in range (n2):
            if polar_angle(E2[k],p1)<min_a:
                m=E2[k]
                min_a=polar_angle(E2[k],p1)
                #on récupère la position dans E2 de l'élément d'angle minimal avec p1
        min_i=E2.index(m)
        #on réarrange la deuxième liste pour que ses éléments soient triés par angles croissants par rapport à p1
        #pour ce faire on met le minimum m en premier et on garde le reste de
        E2=E2[min_i:]+E2[:min_i]
        #on peut maintenant fusioner les deux listes sur le même principe que le tri fusion
        #on conserve une liste trié avec un algorithme en O(n)
        E=[E1[0]]
        k=1
        l=0
        E2=polar_quicksort(E2,p1)
        while k<n1 and l<n2:
            if polar_angle(E1[k],E[0])<polar_angle(E2[l],E[0]):
                E.append(E1[k])
                k+=1
            else:
                E.append(E2[l])
                l+=1
        #on complète avec les éléments restant de la liste E1 ou E2
        while k<n1:
            E.append(E1[k])
            k+=1
        while l<n2:
            E.append(E2[l])
            l+=1
    else :
        #on commence par chercher l'élément de E1 de plus petit angle avec p2
        m=p1
        min_a=polar_angle(m,p2)
        for k in range (n1):
            if polar_angle(E1[k],p2)<min_a:
                m=E1[k]
                min_a=polar_angle(E1[k],p2)
                #on récupère la position dans E2 de l'élément d'angle minimal avec p1
        min_i=E1.index(m)
        #on réarrange la deuxième liste pour que ses éléments soient triés par angles croissants par rapport à p1
        #pour ce faire on met le minimum m en premier et on garde le reste de
        E1=E1[min_i:]+E1[:min_i]
        #on peut maintenant fusioner les deux listes sur le même principe que le tri fusion
        #on conserve une liste trié avec un algorithme en O(n)
        E=[E2[0]]
        k=0
        l=1
        E1=polar_quicksort(E1,p2)
        while k<n1 and l<n2:
            if polar_angle(E1[k],E[0])<polar_angle(E2[l],E[0]):
                E.append(E1[k])
                k+=1
            else:
                E.append(E2[l])
                l+=1
        #on complète avec les éléments restant de la liste E1 ou E2
        while k<n1:
            E.append(E1[k])
            k+=1
        while l<n2:
            E.append(E2[l])
            l+=1
    ##print(E)
    #print("\n")
    #print("azertyuio")
    #on a bien une liste E contenant tous les éléments et triée en fontion de E[0]
    return E