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))
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
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
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))
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