def Incremental (l):
	"Algoritmo incremental para o problema do fecho convexo de uma lista de pontos"

	if len (l) == 0: return None

	# crio um fecho c/ um ponto
	fecho = Polygon ([ l[0] ])
	fecho.plot ()
	

	# Como nao posso admitir que os pontos estao em posicao geral,
	# preciso tomar cuidado ate encontrar tres pontos nao colineares
	# :-( 
	length = 1
	k = 0
	hi = l[k].hilight ()
	for k in range (1, len (l)):
		pts = fecho.pts
		l[k-1].unhilight (hi)
		hi = l[k].hilight ()
		control.thaw_update ()

		if length == 1:
			if l[k].x == pts.x and l[k].y == pts.y:
				continue
			fecho.hide ()
			pts.next = pts.prev = l[k]
			l[k].next = l[k].prev = pts
			fecho.pts = pts
			fecho.plot ()
			length = length + 1
		
		elif length == 2:
			next = pts.next
			dir = area2 (pts, next, l[k])
			if dir == 0:
				#Mais um ponto colinear -> pega o par mais distante
				fecho.hide ()
				dist_pts_next = dist2 (pts, next)
				dist_pts_lk = dist2 (pts, l[k])
				dist_next_lk = dist2 (next, l[k])
				if dist_pts_next >= dist_pts_lk and dist_pts_next >= dist_next_lk:
					a = pts
					b = next
				elif dist_pts_lk >= dist_pts_next  and  dist_pts_lk >= dist_next_lk:
					a = pts
					b = l[k]
				elif dist_next_lk >= dist_pts_lk and dist_next_lk >= dist_pts_next:
					a = next
					b = l[k]
				else:
					print 'pau!!!'

				a.next = a.prev = b
				b.next = b.prev = a
				fecho.pts = a
				fecho.plot ()

				continue
			fecho.hide ()
			# Ponto nao colinear :) - basta tomar cuidado p/ 
			#   construir o poligono c/ a direcao certa
			if dir > 0:
				pts.prev = next.next = l[k]
				l[k].next = pts
				l[k].prev = next
			else:
				pts.next = next.prev = l[k]
				l[k].prev = pts
				l[k].next = next

			length = length + 1
			fecho.pts = pts
			fecho.plot ()
			break

	# Ja tenho um fecho com 3 pontos -> basta "cresce-lo"
	for k in range (k+1, len (l)):
		pts = fecho.pts
		l[k-1].unhilight (hi)
		hi = l[k].hilight ()
		control.thaw_update ()

		tan = vertices_tangentes (fecho, l[k])
		# l[k] esta fora do fecho atual <=> len (tan) == 2
		if len (tan) == 2:
			control.freeze_update ()
			fecho.hide ()

			tan[0].next.prev = None
			tan[0].next = l[k]
			l[k].prev = tan[0]

			if tan[1].prev: tan[1].prev.next = None
			tan[1].prev = l[k]
			l[k].next = tan[1]

			fecho.pts = tan[0]
			fecho.plot ()

			control.thaw_update ()
	
	l[k].unhilight (hi)
	fecho.plot ()
	fecho.extra_info = 'vertices: %d'%len (fecho.to_list ())
	return fecho
Esempio n. 2
0
def Incremental (l):
	"Algoritmo incremental para o problema do fecho convexo de uma lista de pontos"

	if len (l) == 0: return None

	# crio um fecho c/ um ponto
	fecho = Polygon ([ l[0] ])
	fecho.plot ()
	

	# Como nao posso admitir que os pontos estao em posicao geral,
	# preciso tomar cuidado ate encontrar tres pontos nao colineares
	# :-( 
	length = 1
	k = 0
	hi = l[k].hilight ()
	for k in range (1, len (l)):
		pts = fecho.pts
		l[k-1].unhilight (hi)
		hi = l[k].hilight ()
		control.thaw_update ()

		if length == 1:
			if l[k].x == pts.x and l[k].y == pts.y:
				continue
			fecho.hide ()
			pts.next = pts.prev = l[k]
			l[k].next = l[k].prev = pts
			fecho.pts = pts
			fecho.plot ()
			length = length + 1
		
		elif length == 2:
			next = pts.next
			dir = area2 (pts, next, l[k])
			if dir == 0:
				#Mais um ponto colinear -> pega o par mais distante
				fecho.hide ()
				dist_pts_next = dist2 (pts, next)
				dist_pts_lk = dist2 (pts, l[k])
				dist_next_lk = dist2 (next, l[k])
				if dist_pts_next >= dist_pts_lk and dist_pts_next >= dist_next_lk:
					a = pts
					b = next
				elif dist_pts_lk >= dist_pts_next  and  dist_pts_lk >= dist_next_lk:
					a = pts
					b = l[k]
				elif dist_next_lk >= dist_pts_lk and dist_next_lk >= dist_pts_next:
					a = next
					b = l[k]
				else:
					print 'pau!!!'

				a.next = a.prev = b
				b.next = b.prev = a
				fecho.pts = a
				fecho.plot ()

				continue
			fecho.hide ()
			# Ponto nao colinear :) - basta tomar cuidado p/ 
			#   construir o poligono c/ a direcao certa
			if dir > 0:
				pts.prev = next.next = l[k]
				l[k].next = pts
				l[k].prev = next
			else:
				pts.next = next.prev = l[k]
				l[k].prev = pts
				l[k].next = next

			length = length + 1
			fecho.pts = pts
			fecho.plot ()
			break

	# Ja tenho um fecho com 3 pontos -> basta "cresce-lo"
	for k in range (k+1, len (l)):
		pts = fecho.pts
		l[k-1].unhilight (hi)
		hi = l[k].hilight ()
		control.thaw_update ()

		tan = vertices_tangentes (fecho, l[k])
		# l[k] esta fora do fecho atual <=> len (tan) == 2
		if len (tan) == 2:
			control.freeze_update ()
			fecho.hide ()

			tan[0].next.prev = None
			tan[0].next = l[k]
			l[k].prev = tan[0]

			if tan[1].prev: tan[1].prev.next = None
			tan[1].prev = l[k]
			l[k].next = tan[1]

			fecho.pts = tan[0]
			fecho.plot ()

			control.thaw_update ()
	
	l[k].unhilight (hi)
	fecho.plot ()
	fecho.extra_info = 'vertices: %d'%len (fecho.to_list ())
	return fecho
Esempio n. 3
0
def IncrProb (l):
	"Algoritmo incremental probabilistico para encontrar o fecho convexo"

	if len (l) == 0: return None

	# Embaralhando o vetor de entrada
	for i in range (len (l) -1, -1, -1):
		index = int (random.uniform (0, i+1))
		aux = l[i]
		l[i] = l[index]
		l[index] = aux
	
	# Inicializando alguns campos...
	for i in range (0, len(l)):
		l[i].L = []
		l[i].interior = 0
		

	# Criando um fecho convexo com 1 ponto
	fecho = Polygon ([ l[0] ])
	fecho.plot ()
	
	length = 1
	k = 0
	hi = l[k].hilight ()
	# Como nao posso admitir que os pontos estao em posicao geral,
	#  preciso tomar cuidado ate' conseguir um fecho convexo com
	#  3 pontos
	for k in range (1, len (l)):
		pts = fecho.pts
		l[k-1].unhilight (hi)
		hi = l[k].hilight ()
		control.thaw_update ()
		if length == 1:
			if l[k].x == pts.x and l[k].y == pts.y:
				continue
			fecho.hide ()
			pts.next = pts.prev = l[k]
			l[k].next = l[k].prev = pts
			fecho.pts = pts
			fecho.plot ()
			length = length + 1
		
		elif length == 2:
			next = pts.next
			dir = area2 (pts, next, l[k])
			if dir == 0:
				#Mais um ponto colinear -> pega o par mais distante
				fecho.hide ()
				dist_pts_next = dist2 (pts, next)
				dist_pts_lk = dist2 (pts, l[k])
				dist_next_lk = dist2 (next, l[k])
				if dist_pts_next >= dist_pts_lk and dist_pts_next >= dist_next_lk:
					a = pts
					b = next
				elif dist_pts_lk >= dist_pts_next  and  dist_pts_lk >= dist_next_lk:
					a = pts
					b = l[k]
				elif dist_next_lk >= dist_pts_lk and dist_next_lk >= dist_pts_next:
					a = next
					b = l[k]
				else:
					print('pau!!!')

				a.next = a.prev = b
				b.next = b.prev = a
				fecho.pts = a
				fecho.plot ()

				continue
			fecho.hide ()
			# Um ponto /nao/ colinear :) -> tomar cuidado com a 
			#  orientacao
			if dir > 0:
				pts.prev = next.next = l[k]
				l[k].next = pts
				l[k].prev = next
			else:
				pts.next = next.prev = l[k]
				l[k].prev = pts
				l[k].next = next

			length = length + 1
			fecho.pts = pts
			fecho.plot ()
			O = classify (fecho, l, k)
			break

	# Ja temos um fecho com 3 pontos -> basta cresce-lo
	for k in range (k+1, len (l)):
		pts = fecho.pts
		l[k-1].unhilight (hi)
		hi = l[k].hilight ()
		control.thaw_update ()

		if l[k].interior:
			control.sleep ()
			continue

		l[k].remove_lineto (l[k].intersect)
		control.sleep ()

		tan = vertices_tangentes (l[k].intersect, l[k])

		l[k].intersect.L.remove (l[k])

		l0 = []
		l1 = []
		# atualizando a classificacao dos pontos
		vertex = tan[0]
		while vertex != tan[1]:
			for p in vertex.L:
				id = p.hilight (config.COLOR_ALT3)
				p.remove_lineto (p.intersect)

				if p == l[k]:
					p.unhilight (id)
					continue

				if left (l[k], O, p):
					if left_on (tan[0], l[k], p):
						p.interior = 1
						p.intersect = None
					else:
						p.intersect = tan[0]
						p.lineto (p.intersect, config.COLOR_ALT1)
						l0.append (p)
				else:
					if left_on (l[k], tan[1], p):
						p.interior = 1
						p.intersect = None
					else:
						p.intersect = l[k]
						p.lineto (p.intersect, config.COLOR_ALT1)
						l1.append (p)

				p.unhilight (id)

			vertex = vertex.next

		tan[0].L = l0
		l[k].L = l1

		# atualizando o fecho
		control.freeze_update ()
		fecho.hide ()

		tan[0].next.prev = None
		tan[0].next = l[k]
		l[k].prev = tan[0]

		if tan[1].prev: tan[1].prev.next = None
		tan[1].prev = l[k]
		l[k].next = tan[1]

		fecho.pts = tan[0]
		fecho.plot ()

		control.thaw_update ()

	l[k].unhilight (hi)
	fecho.plot ()
	fecho.extra_info = 'vertices: %d'%len (fecho.to_list ())
	return fecho
Esempio n. 4
0
def IncrProb(l):
    "Algoritmo incremental probabilistico para encontrar o fecho convexo"

    if len(l) == 0: return None

    # Embaralhando o vetor de entrada
    for i in range(len(l) - 1, -1, -1):
        index = int(random.uniform(0, i + 1))
        aux = l[i]
        l[i] = l[index]
        l[index] = aux

    # Inicializando alguns campos...
    for i in range(0, len(l)):
        l[i].L = []
        l[i].interior = 0

    # Criando um fecho convexo com 1 ponto
    fecho = Polygon([l[0]])
    fecho.plot()

    length = 1
    k = 0
    hi = l[k].hilight()
    # Como nao posso admitir que os pontos estao em posicao geral,
    #  preciso tomar cuidado ate' conseguir um fecho convexo com
    #  3 pontos
    for k in range(1, len(l)):
        pts = fecho.pts
        l[k - 1].unhilight(hi)
        hi = l[k].hilight()
        control.thaw_update()
        if length == 1:
            if l[k].x == pts.x and l[k].y == pts.y:
                continue
            fecho.hide()
            pts.next = pts.prev = l[k]
            l[k].next = l[k].prev = pts
            fecho.pts = pts
            fecho.plot()
            length = length + 1

        elif length == 2:
            next = pts.next
            dir = area2(pts, next, l[k])
            if dir == 0:
                #Mais um ponto colinear -> pega o par mais distante
                fecho.hide()
                dist_pts_next = dist2(pts, next)
                dist_pts_lk = dist2(pts, l[k])
                dist_next_lk = dist2(next, l[k])
                if dist_pts_next >= dist_pts_lk and dist_pts_next >= dist_next_lk:
                    a = pts
                    b = next
                elif dist_pts_lk >= dist_pts_next and dist_pts_lk >= dist_next_lk:
                    a = pts
                    b = l[k]
                elif dist_next_lk >= dist_pts_lk and dist_next_lk >= dist_pts_next:
                    a = next
                    b = l[k]
                else:
                    print('pau!!!')

                a.next = a.prev = b
                b.next = b.prev = a
                fecho.pts = a
                fecho.plot()

                continue
            fecho.hide()
            # Um ponto /nao/ colinear :) -> tomar cuidado com a
            #  orientacao
            if dir > 0:
                pts.prev = next.next = l[k]
                l[k].next = pts
                l[k].prev = next
            else:
                pts.next = next.prev = l[k]
                l[k].prev = pts
                l[k].next = next

            length = length + 1
            fecho.pts = pts
            fecho.plot()
            O = classify(fecho, l, k)
            break

    # Ja temos um fecho com 3 pontos -> basta cresce-lo
    for k in range(k + 1, len(l)):
        pts = fecho.pts
        l[k - 1].unhilight(hi)
        hi = l[k].hilight()
        control.thaw_update()

        if l[k].interior:
            control.sleep()
            continue

        l[k].remove_lineto(l[k].intersect)
        control.sleep()

        tan = vertices_tangentes(l[k].intersect, l[k])

        l[k].intersect.L.remove(l[k])

        l0 = []
        l1 = []
        # atualizando a classificacao dos pontos
        vertex = tan[0]
        while vertex != tan[1]:
            for p in vertex.L:
                id = p.hilight(config.COLOR_ALT3)
                p.remove_lineto(p.intersect)

                if p == l[k]:
                    p.unhilight(id)
                    continue

                if left(l[k], O, p):
                    if left_on(tan[0], l[k], p):
                        p.interior = 1
                        p.intersect = None
                    else:
                        p.intersect = tan[0]
                        p.lineto(p.intersect, config.COLOR_ALT1)
                        l0.append(p)
                else:
                    if left_on(l[k], tan[1], p):
                        p.interior = 1
                        p.intersect = None
                    else:
                        p.intersect = l[k]
                        p.lineto(p.intersect, config.COLOR_ALT1)
                        l1.append(p)

                p.unhilight(id)

            vertex = vertex.next

        tan[0].L = l0
        l[k].L = l1

        # atualizando o fecho
        control.freeze_update()
        fecho.hide()

        tan[0].next.prev = None
        tan[0].next = l[k]
        l[k].prev = tan[0]

        if tan[1].prev: tan[1].prev.next = None
        tan[1].prev = l[k]
        l[k].next = tan[1]

        fecho.pts = tan[0]
        fecho.plot()

        control.thaw_update()

    l[k].unhilight(hi)
    fecho.plot()
    fecho.extra_info = 'vertices: %d' % len(fecho.to_list())
    return fecho