Documentos de Académico
Documentos de Profesional
Documentos de Cultura
2143067521
Fecha:22/03/2022
GEOMETRÍA COMPUTACIONAL
Tarea No. 1
Algoritmo de Graham
Ruiz Coronel Erick David
2143067521
Fecha:22/03/2022
i. Eliminar p(i)
def pausa(key):
if key == '':
print(" ")
def label():
plt.title('Envolvente Convexa - Erick Ruiz')
plt.xlabel('Eje - X')
plt.ylabel('Eje - Y')
def generarGraficaPasos(noConvexa0,noConvexa,step,coords,envolventeConvexa=None):
nC=0
xs,ys=zip(*coords)
plt.scatter(xs,ys,color="black")
puntosOrdenEnum=quicksort(coords)
if noConvexa0 != []:
for z in range(len(puntosOrdenEnum)):
for zz in range(len(noConvexa0)):
if puntosOrdenEnum[z]==noConvexa0[zz]:
zx=puntosOrdenEnum[z-1]
zy=puntosOrdenEnum[z+1]
zxy=noConvexa0[zz]
plt.plot((zy[0],zxy[0]),(zy[1],zxy[1]),color='black',linestyle='dashed',fillstyle='bottom')
plt.plot((zx[0],zxy[0]),(zx[1],zxy[1]),color='black',linestyle='dashed',fillstyle='bottom')
if envolventeConvexa!=None:
for i in range(1,len(envolventeConvexa)+1):
if i==len(envolventeConvexa): i=0
c0=envolventeConvexa[i-1]
c1=envolventeConvexa[i]
c00=envolventeConvexa[len(envolventeConvexa)-1]
c01=envolventeConvexa[len(envolventeConvexa)-2]
c02=envolventeConvexa[len(envolventeConvexa)-3]
plt.text(c00[0]+1.5,c00[1]-1,'f',bbox=box)
if i>0:
if i<len(envolventeConvexa)-1:
plt.plot((c0[0],c1[0]),(c0[1],c1[1]),color='green',fillstyle='top')
if i==2 and len(envolventeConvexa)<4:
if noConvexa==[]:
plt.plot((c00[0],c01[0]),(c00[1],c01[1]),color='blue',fillstyle='top')
plt.text(c01[0]+1.5,c01[1]-1,'m',bbox=box)
plt.text(c02[0]+1.5,c02[1]-1,'o',bbox=box)
if noConvexa!=[]:
cxx=noConvexa[0]
plt.plot((c02[0],c01[0]),(c02[1],c01[1]),color='green',fillstyle='top')
plt.plot((c01[0],cxx[0]),(c01[1],cxx[1]),color='blue',fillstyle='top')
plt.plot((cxx[0],c00[0]),(cxx[1],c00[1]),color='red',fillstyle='top')
nC=1
del noConvexa[0]
if i>2:
if noConvexa!=[]:
if nC != 1:
cxx=noConvexa[0]
plt.plot((c02[0],c01[0]),(c02[1],c01[1]),color='green',fillstyle='top')
plt.plot((c01[0],cxx[0]),(c01[1],cxx[1]),color='blue',fillstyle='top')
plt.plot((cxx[0],c00[0]),(cxx[1],c00[1]),color='red',fillstyle='top')
plt.text(cxx[0]+1.5,cxx[1]-1,'m',bbox=box)
plt.text(c01[0]+1.5,c01[1]-1,'o',bbox=box)
nC=1
del noConvexa[0]
if nC==0:
plt.plot((c0[0],c1[0]),(c0[1],c1[1]),color='green',fillstyle='top')
plt.plot((c00[0],c01[0]),(c00[1],c01[1]),color='red',fillstyle='top')
plt.plot((c01[0],c02[0]),(c01[1],c02[1]),color='blue',fillstyle='top')
plt.text(c01[0]+1.5,c01[1]-1,'m',bbox=box)
plt.text(c02[0]+1.5,c02[1]-1,'o',bbox=box)
label()
enumerarPts(puntosOrdenEnum)
plt.show()
enter = input("Pulsa ENTER para continuar: ")
pausa(enter)
def generarGrafica(noConvexa0,coords,envolventeConvexa=None):
xs,ys=zip(*coords)
plt.scatter(xs,ys,color="black")
puntosOrdenEnum=quicksort(coords)
if envolventeConvexa!=None:
for i in range(0,len(envolventeConvexa)):
if i==len(envolventeConvexa): i=0
c0=envolventeConvexa[i-1]
c1=envolventeConvexa[i]
c00=envolventeConvexa[0]
c01=envolventeConvexa[len(envolventeConvexa)-1]
c02=envolventeConvexa[len(envolventeConvexa)-2]
plt.text(c00[0]+1.5,c00[1]-1,'f',bbox=box)
plt.text(c01[0]+1.5,c01[1]-1,'m',bbox=box)
plt.text(c02[0]+1.5,c02[1]-1,'o',bbox=box)
plt.plot((c0[0],c1[0]),(c0[1],c1[1]),color='green',fillstyle='top')
if noConvexa0 != []:
for z in range(len(puntosOrdenEnum)):
for zz in range(len(noConvexa0)):
if puntosOrdenEnum[z]==noConvexa0[zz]:
zx=puntosOrdenEnum[z-1]
zy=puntosOrdenEnum[z+1]
zxy=noConvexa0[zz]
plt.plot((zx[0],zxy[0]),(zx[1],zxy[1]),color='black',linestyle='dashed',fillstyle='top')
plt.plot((zy[0],zxy[0]),(zy[1],zxy[1]),color='black',linestyle='dashed',fillstyle='top')
label()
enumerarPts(puntosOrdenEnum)
Ruiz Coronel Erick David
2143067521
Fecha:22/03/2022
plt.show()
print ("\nEnvolvente convexa:",envolventeConvexa)
enter = input("Pulsa ENTER para finalizar: ")
pausa(enter)
def enumerarPts(coordenadas):
for enum0 in range(0,len(pts)):
if enum0==len(pts): enum0=-1
po0=coordenadas[enum0]
plt.text(po0[0]-0.4,po0[1]+1.5,enum0+1)
def anguloPolar(p0,p1=None):
if p1==None: p1=ancla
y_span=p0[1]-p1[1]
x_span=p0[0]-p1[0]
return atan2(y_span,x_span)
def distancia(p0,p1=None):
if p1==None: p1=ancla
y_span=p0[1]-p1[1]
x_span=p0[0]-p1[0]
return y_span**2 + x_span**2
def det(p1,p2,p3):
return (p2[0]-p1[0])*(p3[1]-p1[1]) \
-(p2[1]-p1[1])*(p3[0]-p1[0])
def quicksort(a):
if len(a)<=1: return a
menor,igual,mayor=[],[],[]
piv_ang=anguloPolar(a[randint(0,len(a)-1)])
for pt in a:
pt_ang=anguloPolar(pt)
if pt_ang<piv_ang: menor.append(pt)
elif pt_ang==piv_ang: igual.append(pt)
else: mayor.append(pt)
return quicksort(menor) \
+sorted(igual,key=distancia) \
+quicksort(mayor)
def graham(puntos,show_progress=False):
global ancla
paso=1
stp=0
min_idx=None
for i,(x,y) in enumerate(puntos):
if min_idx==None or y<puntos[min_idx][1]:
min_idx=i
if y==puntos[min_idx][1] and x<puntos[min_idx][0]:
min_idx=i
ancla=puntos[min_idx]
puntosOrden=quicksort(puntos)
del puntosOrden[puntosOrden.index(ancla)]
envolvente=[ancla,puntosOrden[0]]
noEnvolvente=[]
noEnvolvente0=[]
for s in puntosOrden[1:]:
while det(envolvente[-2],envolvente[-1],s)<=0:
noEnvolvente.append(envolvente[-1])
noEnvolvente0.append(envolvente[-1])
del envolvente[-1]
stp=stp+1
envolvente.append(s)
if show_progress:
print('\nPaso #: ',paso)
generarGraficaPasos(noEnvolvente0,noEnvolvente,stp,puntos,envolvente)
paso=paso+1
print('\nPaso #: ',paso)
generarGrafica(noEnvolvente0,puntos,envolvente)
return 0
pts=[[42, 20], [28, 35], [13, 13], [21, 1], [39, 27], [12, 29], [31, 31], [39, 34], [35, 9], [15, 28]]
print ("\nSe han generado los siguientes puntos:",pts,"\n")
envolvente=graham(pts,True)
Ruiz Coronel Erick David
2143067521
Fecha:22/03/2022
Ruiz Coronel Erick David
2143067521
Fecha:22/03/2022
Ruiz Coronel Erick David
2143067521
Fecha:22/03/2022
Ruiz Coronel Erick David
2143067521
Fecha:22/03/2022
Ruiz Coronel Erick David
2143067521
Fecha:22/03/2022
Ruiz Coronel Erick David
2143067521
Fecha:22/03/2022
Ruiz Coronel Erick David
2143067521
Fecha:22/03/2022
Ruiz Coronel Erick David
2143067521
Fecha:22/03/2022
Ruiz Coronel Erick David
2143067521
Fecha:22/03/2022
Ruiz Coronel Erick David
2143067521
Fecha:22/03/2022
Conclusiones:
El algoritmo de Graham es uno de los más conocidos en lo que respecta a los algoritmos
para encontrar la cerradura convexa de una nube de puntos. Fue desarrollado a finales de la
década de los 60, cuando en los laboratorios Bell se necesitaba calcular la cerradura
convexa de una cantidad enorme de puntos (10000 a más), y con uno de los algoritmos de
por entonces, de O(N^2) resultaba demasiado lento. Entonces Graham lo solucionó con el
presente algoritmo.
Bibliografía:
Brian Faure. (2017, 29 noviembre). Graham Scan: Background & Python Code. YouTube.
https://www.youtube.com/watch?v=vPDPE66nhlo&t=1s