Exemple #1
0
def desenhaTudo(l):
    poligs = leEntrada(l)

    robo = poligs[0]
    probo = destino = None

    if (len(robo) == 1):
        print("Robo ponto na posicao ", robo[0])
        probo = robo[0]
        probo.hilight('yellow')
        destino = poligs[1][0]  #Suponho ser um ponto
    else:
        for p in robo:
            p.plot("black")
        robo = Robo(robo)
        probo = poligs[1][0]  # Suponho ser um ponto
        Polygon(robo.getPontos(probo.x, probo.y)).plot("yellow")
        poligs.pop(
            0
        )  #Removo o polígono do robo da lista, iremos tratar só com o ponto
        destino = poligs[1][0]  # Suponho ser um ponto

    for i in range(len(poligs)):
        for p in poligs[i]:
            p.plot()
        if (len(poligs[i]) > 1):
            Polygon(poligs[i]).plot("cyan")

    probo.hilight("green")
    destino.hilight("red")
Exemple #2
0
def Quickhull (l):
	"Algoritmo Quick Hull para achar o fecho convexo da lista de pontos l"

	south = north = east = west = 0
	# encontrando o ponto mais baixo
	for i in range (1, len(l)):
		if l[i].y < l[south].y:
			south = i
		elif l[i].y == l[south].y:
			if l[i].x > l[south].x:
				south = i
	
		if l[i].y > l[north].y:
			north = i
		elif l[i].y == l[north].y:
			if l[i].x > l[north].x:
				north = i
	
		if l[i].x < l[west].x:
			west = i
		elif l[i].x == l[west].x:
			if l[i].y > l[west].y:
				west = i

		if l[i].x > l[east].x:
			east = i
		elif l[i].x == l[east].x:
			if l[i].y > l[east].y:
				east = i

	fecho = []
	dirs = [ south, east, north, west ]
	for i in range (0, len (dirs)):
		j = (i+1) % 4
		if dirs[i] == dirs[j]:
			continue
		S1 = []
		a = l[dirs[i]]
		b = l[dirs[j]]
		id = a.lineto (b, config.COLOR_ALT5)
		for p in l:
			if right (a, b, p):
				S1.append (p)
		a.remove_lineto (b, id)
		id = a.lineto (b, config.COLOR_ALT4)
		aux = quickhull_rec (a, b, S1)
		a.remove_lineto (b, id)
		fecho.extend (aux)


	if len (l) == 1:
		fecho = [ l[0] ]
	hull = Polygon (fecho)
	hull.extra_info = 'vertices: %d'%len (hull.to_list ())
	return hull
Exemple #3
0
def mergehull_rec (l):
	"""Funcao recursiva que implementa o Merge Hull

	Retorna os pontos com coordenada x minima e maxima do fecho convexo
	encontrado, alem do proprio fecho.
	"""
	n = len (l)
	if n == 1:
		#l[0].prev = l[0].next = l[0]
		pol = Polygon ( [ l[0] ] )
		pol.plot ()
		#control.sleep ()
		return (l[0], l[0], pol)
	
	# Divisao
	l1 = l[:n/2]
	l2 = l[n/2:]

	id = control.plot_vert_line ((l2[0].x + l1[-1].x) / 2.)
	control.sleep ()

	# Conquista
	ch1 = mergehull_rec (l1)

	ch2 = mergehull_rec (l2)

	v = ch1[1]
	u = ch2[0]

	control.plot_delete (id)

	# Combinar
	sup = superior_tangent (v, u)
	id_sup = sup[0].lineto (sup[1], config.COLOR_ALT1)
	inf = inferior_tangent (v, u)
	id_inf = inf[0].lineto (inf[1], config.COLOR_ALT1)

	control.freeze_update ()
	control.plot_delete (id_sup)
	control.plot_delete (id_inf)
	ch1[2].hide ()
	ch2[2].hide ()

	sup[0].prev = sup[1]
	sup[1].next = sup[0]

	inf[0].next = inf[1]
	inf[1].prev = inf[0]

	ch1[2].pts = inf[0]
	ch1[2].plot ()
	control.thaw_update ()

	return (ch1[0], ch2[1], ch1[2])
Exemple #4
0
def Quickhull(l):
    "Algoritmo Quick Hull para achar o fecho convexo da lista de pontos l"

    south = north = east = west = 0
    # encontrando o ponto mais baixo
    for i in range(1, len(l)):
        if l[i].y < l[south].y:
            south = i
        elif l[i].y == l[south].y:
            if l[i].x > l[south].x:
                south = i

        if l[i].y > l[north].y:
            north = i
        elif l[i].y == l[north].y:
            if l[i].x > l[north].x:
                north = i

        if l[i].x < l[west].x:
            west = i
        elif l[i].x == l[west].x:
            if l[i].y > l[west].y:
                west = i

        if l[i].x > l[east].x:
            east = i
        elif l[i].x == l[east].x:
            if l[i].y > l[east].y:
                east = i

    fecho = []
    dirs = [south, east, north, west]
    for i in range(0, len(dirs)):
        j = (i + 1) % 4
        if dirs[i] == dirs[j]:
            continue
        S1 = []
        a = l[dirs[i]]
        b = l[dirs[j]]
        id = a.lineto(b, config.COLOR_ALT5)
        for p in l:
            if right(a, b, p):
                S1.append(p)
        a.remove_lineto(b, id)
        id = a.lineto(b, config.COLOR_ALT4)
        aux = quickhull_rec(a, b, S1)
        a.remove_lineto(b, id)
        fecho.extend(aux)

    if len(l) == 1:
        fecho = [l[0]]
    hull = Polygon(fecho)
    hull.extra_info = 'vertices: %d' % len(hull.to_list())
    return hull
Exemple #5
0
def mergehull_rec(l):
    """Funcao recursiva que implementa o Merge Hull

	Retorna os pontos com coordenada x minima e maxima do fecho convexo
	encontrado, alem do proprio fecho.
	"""
    n = len(l)
    if n == 1:
        #l[0].prev = l[0].next = l[0]
        pol = Polygon([l[0]])
        pol.plot()
        #control.sleep ()
        return (l[0], l[0], pol)

    # Divisao
    l1 = l[:n // 2]
    l2 = l[n // 2:]

    id = control.plot_vert_line((l2[0].x + l1[-1].x) / 2.)
    control.sleep()

    # Conquista
    ch1 = mergehull_rec(l1)

    ch2 = mergehull_rec(l2)

    v = ch1[1]
    u = ch2[0]

    control.plot_delete(id)

    # Combinar
    sup = superior_tangent(v, u)
    id_sup = sup[0].lineto(sup[1], config.COLOR_ALT1)
    inf = inferior_tangent(v, u)
    id_inf = inf[0].lineto(inf[1], config.COLOR_ALT1)

    control.freeze_update()
    control.plot_delete(id_sup)
    control.plot_delete(id_inf)
    ch1[2].hide()
    ch2[2].hide()

    sup[0].prev = sup[1]
    sup[1].next = sup[0]

    inf[0].next = inf[1]
    inf[1].prev = inf[0]

    ch1[2].pts = inf[0]
    ch1[2].plot()
    control.thaw_update()

    return (ch1[0], ch2[1], ch1[2])
Exemple #6
0
def visGraphAlg(l):
    poligs = leEntrada(l)

    robo = poligs[0]
    destino = None

    desenhaTudo(l)  #Muito codigo igual ao de baixo...mas deixa

    if (len(robo) == 1):
        print("Robo ponto na posicao ", robo[0])
        probo = robo[0]
        destino = poligs[1][0]  #Suponho ser um ponto
    else:
        robo = Robo(robo)
        probo = poligs[1][0]  # Suponho ser um ponto
        poligs.pop(
            0
        )  #Removo o polígono do robo da lista, iremos tratar só com o ponto
        destino = poligs[1][0]  # Suponho ser um ponto
        for i in range(len(poligs)):
            if (len(poligs[i]) > 1):
                poligs[i] = robo.deformaPolig(poligs[i])
                Polygon(poligs[i]).plot()
                control.sleep()

    pontos = []
    for i in range(len(poligs)):
        poligs[i] = Polygon(poligs[i])
        poligs[i].hilight()
        pontos.extend(poligs[i].to_list())
        control.sleep()

    probo.prev = probo.__next__ = probo

    compara = criaCompara(probo)
    pontos.sort(key=cmp_to_key(compara), reverse=True)

    #Grafo
    G = Grafo(len(pontos))

    #Numerando os pontos
    for i in range(len(pontos)):
        pontos[i].i = i

    for pi in pontos:
        W = verticesVisiveis(pi, poligs)
        for pj in W:
            G.addAresta(pi.i, pj.i, dist2(pi, pj)**0.5)

    path, dist = G.dijkstra(probo.i, destino.i)
    for i in range(len(path) - 1):
        v = path[i]
        u = path[i + 1]
        pontos[v].lineto(pontos[u], 'red')
Exemple #7
0
def read_polygons(filename):
    if filename is None:
        raise ValueError("File name is None")
    with open(filename) as file:
        polygons = []
        vertices = []
        for line in file:
            line = line.split()
            if len(line) == 0:
                polygons.append(Polygon(vertices))
                vertices = []
                continue
            if len(line) != 2:
                raise ValueError("Invalid input from file: {}: {}".format(
                    filename, line))
            vertices.append(Point(float(line[0]), float(line[1])))
        polygons.append(Polygon(vertices))
        return polygons
Exemple #8
0
def Chan (l):
	n = len (l)
	if n == 0: return None
	if n == 1 or n == 2:
		ret = Polygon (l)
		ret.plot ()
		ret.extra_info = 'vertices: %d'%n
		return ret

	i = 2
	while 1:
		H = min (1<< (1<<i), n)
		m = H
		ch = Hull2D (l, m, H)
		#print ch
		if ch != None: 
			ch.extra_info = 'vertices: %d'%len (ch.to_list ())
			return ch
		i = i + 1
Exemple #9
0
def Chan (l):
	n = len (l)
	if n == 0: return None
	if n == 1 or n == 2:
		ret = Polygon (l)
		ret.plot ()
		ret.extra_info = 'vertices: %d'%n
		return ret

	i = 2
	while 1:
		H = min (1<< (1<<i), n)
		m = H
		ch = Hull2D (l, m, H)
		#print ch
		if ch != None: 
			ch.extra_info = 'vertices: %d'%len (ch.to_list ())
			return ch
		i = i + 1
Exemple #10
0
def Incremental(list_polygon):

    # Criando e printando o retangulo externo
    oeste = list_polygon[0].pts.x
    leste = list_polygon[0].pts.x
    norte = list_polygon[0].pts.y
    sul = list_polygon[0].pts.y

    for polygon in list_polygon:
        for point in polygon.vertices():
            if point.x < oeste: oeste = point.x
            if point.x > leste: leste = point.x
            if point.y < sul: sul = point.y
            if point.y > norte: norte = point.y

    exterior = []

    exterior.append(Point(oeste - 1, sul - 1))
    exterior.append(Point(leste + 1, sul - 1))
    exterior.append(Point(leste + 1, norte + 1))
    exterior.append(Point(oeste - 1, norte + 1))

    ext = Polygon(exterior)
    Print(ext)

    # Printando os polígonos simples
    for polygon in list_polygon:
        Print(polygon)

    # Parte 1.1 - Transformando os polígonos iniciais em arestas(segmentos de retas)
    lsegments = []
    for polygon in list_polygon:
        foo = Generate(polygon.vertices())
        for x in foo:
            p1 = x.p_left
            p2 = x.p_right
            x.swap = 0

            if p1.x > p2.x or (p1.x == p2.x and p1.y > p2.y):
                x.p_left = p2
                x.p_right = p1
                x.swap = 1
            if len(polygon.vertices()) == 2:
                x.swap = 0
            lsegments.append(x)

    # Parte 1.2 - Criando o mapa de trapezoidação

    print("lsegments size is " + str(len(lsegments)))
    mapa = STrapezoidMap(lsegments)
    mapa.construct()

    return mapa
Exemple #11
0
def Lee_Preparata (p):
    
    P = p[0]
    diags = []
    d = Dcel ()
    d.initPolygon (P)
    
    # Atualiza a DCEL colocando as diagonais parar a partição em monótonos
    monotonos (d, P, diags)
    n_face_externa = len(P.vertices())
    divisoras = len(diags)
    # Para cada face, constrói um polígono e triangula ele

    if len (d.f) == 2:
        return Monotono([P])

    for e in d.f:
        vertices = [e.init]
        while e.to != vertices[0]:
            vertices.append (e.to)
            e = e.prox
        if len(vertices) != n_face_externa:
            new_p = Polygon (vertices)
            new_p.plot("orange")
            control.sleep()
            # Triangula o new_p e adiciona as novas diagonais no diags
            diags.extend (Monotono ([new_p]))
            new_p.hide()
    
    # despinta as arestas
    for i in range(divisoras):
        diags[i].hide()
        diags[i].plot("green")
Exemple #12
0
def Gift (l):
	"Algoritmo Embrulho para Presente para encontrar o fecho convexo de uma lista l de pontos"

	# achando ponto mais baixo
	i0 = 0
	for i in range (1, len(l)):
		if l[i].y < l[i0].y:
			i0 = i
		elif l[i].y == l[i0].y:
			if l[i].x > l[i0].x:
				i0 = i
	
	fecho = [ l[i0] ]
	n = len (l)
	i = i0
	while 1:
		# passo embrulho para presente
		j0 = 0
		for j in range (1,n):
			if j == i:
				continue
			direction = area2 (l[i], l[j0], l[j])
			if direction < 0:
				j0 = j
			elif direction == 0:
				if dist2 (l[i], l[j0]) < dist2 (l[i], l[j]):
					j0 = j

		i = j0
		fecho[-1].lineto (l[j0])
		if (i == i0):
			break
		fecho.append (l[j0])
	
	ch = Polygon (fecho)
	ch.extra_info = 'vertices: %d'%len (fecho)
	return ch
Exemple #13
0
def Graham(l):
    "Algoritmo de Graham para achar o fecho convexo de uma lista l de pontos"

    if len(l) == 0: return None

    # So um ponto foi passado. Retorna um fecho c/ apenas um ponto
    if len(l) == 1:
        ret = Polygon(l)
        ret.plot()
        ret.extra_info = 'vertices: 1'
        return ret

    p0 = l[0]

    # acha o ponto mais baixo
    for i in range(1, len(l)):
        if l[i].y < p0.y:
            p0 = l[i]
        elif l[i].y == p0.y:
            if l[i].x > p0.x:
                p0 = l[i]

    l.remove(p0)

    def cmp(x, y, z=p0):
        """Funcao para ordenar os pontos ao redor de z

		Usada com a funcao sort, ordena os pontos de uma lista
		de acordo com o angulo que cada ponto forma com o ponto 
		z e a reta horizontal. Em caso de empate, o ponto mais
		distante aparece primeiro."""
        area = area2(z, x, y)
        if area > 0:
            return -1
        elif area < 0:
            return 1
        else:
            dist_z_x = dist2(z, x)
            dist_z_y = dist2(z, y)
            if dist_z_y < dist_z_x:
                return -1
            return dist_z_y > dist_z_x

    # Ordena os pontos pelo seus angulos
    l.sort(cmp)

    # eliminando pontos colineares
    l2 = [l[0]]
    for i in range(1, len(l)):
        if collinear(p0, l[i - 1], l[i]):
            continue
        l2.append(l[i])

    l = l2

    # So sobraram dois pontos -> retorna fecho c/ os dois
    if len(l) < 2:
        ret = Polygon([p0, l[0]])
        ret.plot()
        ret.extra_info = 'vertices: 2'
        return ret

    pilha = [p0, l[0], l[1]]

    p0.lineto(l[0])
    l[0].lineto(l[1])
    control.sleep()

    for i in range(2, len(l)):
        l[i].hilight()
        pilha[-1].lineto(l[i])
        control.sleep()

        while not left(pilha[-2], pilha[-1], l[i]):
            pilha[-2].remove_lineto(pilha[-1])
            pilha[-1].remove_lineto(l[i])

            pilha.pop()

            pilha[-1].lineto(l[i])
            control.sleep()

        pilha.append(l[i])

        l[i].unhilight()

    pilha[-1].lineto(pilha[0])

    for i in range(0, len(pilha) - 1):
        pilha[i].remove_lineto(pilha[i + 1])

    pilha[-1].remove_lineto(pilha[0])
    poligono = Polygon(pilha)
    poligono.plot()
    control.thaw_update()

    poligono.extra_info = 'vertices: %d' % len(poligono.to_list())
    return poligono
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
Exemple #15
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
Exemple #16
0
def read(filename):
    """Reads any type of geometric primitive data structures (Point,
    Polygon, Segment) from a file and returns it as a list.

    This method reads geometric data from a file. Any empty line or
    any line started by '#' (considered  a commentary) is ignored.
    The input can be mixed, it can contains a set of Polygons, Points
    and Segments and not necessarily only one type of data.

    The following patterns are required during the input operation:

    Point: defined by two floating point coordinates, on a line,
           separated by whitespaces. For example:

               0 0
               0.5 1.5
               1.5 3

    Polygon: defined by a list of adjacent points, enclosed by '['
             at the beginning and ']' at the end, in the order that
             they appear in the polygon boundary, i.e., any pair of
             consecutive points defines an edge on the polygon
             boundary. For example, the following input defines a
             square:

             [
             0 0
             1 0
             1 1
             0 1
             ]

    Segment: defined by four floating point coordinates, on a line,
             separated by whitespaces. Each pair of consecutive
             coordinates defines a segment endpoint. For example,
             the following input defines a segment from (0, 0) to
             (0.5, 1.5):

             0 0 0.5 1.5

     Disc: Atualmente, ele espera que o arquivo contenha uma lista de
           discos, um disco por linha, as 3 coordenadas em cada linha
           (x, y, r). Exemplo:
    
            0 0 0
            0 1 2
            10 100 50

    :param filename: (str) The name of the file that will be read

    :return: (list) A list of geometric primitive data structures
             read from the file

    Raises:
        FileNotFoundError: if file could not be found

        TypeError: if 'filename' is None

        ValueError: if some input from the file does not follow the
                    required patterns

    """
    with open(filename) as file:
        i = 0
        vertices = []
        data = []
        expecting_polygon = False
        for line in file:
            i += 1
            line = line.split()
            if len(line) == 0 or line[0] == "#":
                continue
            if line[0] == "[":
                expecting_polygon = True
            elif line[0] == "]":
                expecting_polygon = False
                data.append(Polygon(vertices))
                vertices = []
            elif len(line) == 3:
                data.append(Disc(float(line[0]), float(line[1]), float(line[2])))
            elif len(line) == 4:
                data.append(
                    Segment(
                        Point(float(line[0]), float(line[1])),
                        Point(float(line[2]), float(line[3]))
                    )
                )
            elif len(line) == 2:
                if expecting_polygon:
                    vertices.append(Point(float(line[0]), float(line[1])))
                else:
                    data.append(Point(float(line[0]), float(line[1])))
            else:
                raise ValueError(
                    "Invalid input from file: {}: line: {}: {}".format(filename, i, line))
        return data
Exemple #17
0
def Bhatta_Sen (l):
	"""Algoritmo otimo proposto por Bhattacharya e Sen para encontrar o fecho convexo de l"""
	south = north = east = west = 0
	# encontrando o ponto mais baixo
	for i in range (1, len(l)):
		if l[i].y < l[south].y:
			south = i
		elif l[i].y == l[south].y:
			if l[i].x > l[south].x:
				south = i
	
		if l[i].y > l[north].y:
			north = i
		elif l[i].y == l[north].y:
			if l[i].x > l[north].x:
				north = i
	
		if l[i].x < l[west].x:
			west = i
		elif l[i].x == l[west].x:
			if l[i].y > l[west].y:
				west = i

		if l[i].x > l[east].x:
			east = i
		elif l[i].x == l[east].x:
			if l[i].y > l[east].y:
				east = i

	fecho = []
	dirs = [ south, east, north, west ]
	for i in range (0, len (dirs)):
		j = (i+1) % 4
		if dirs[i] == dirs[j]:
			continue
		fecho.append (l[dirs[i]])
		S1 = []
		a = l[dirs[i]]
		b = l[dirs[j]]
		for p in l:
			if right (a, b, p):
				S1.append (p)
		id = a.lineto (b, config.COLOR_ALT4)
		aux = []
		if len (S1) > 0:
			if dirs[i] == south  or  dirs[i] == west:
				aux = bhatta_sen_lower_rec (a, b, S1)
			else:
				aux = bhatta_sen_upper_rec (a, b, S1)
		a.remove_lineto (b, id)
		if len (aux) > 0:
			a.lineto (aux[0])
			aux[-1].lineto (b)
		else:
			a.lineto (b)
		fecho.extend (aux)

	if len (l) == 1:
		fecho = [ l[0] ]
	pol = Polygon (fecho)
	pol.plot ()
	pol.extra_info = "vertices: %d" %len (fecho)

	return pol
def Bhatta_Sen(l):
    """Algoritmo otimo proposto por Bhattacharya e Sen para encontrar o fecho convexo de l"""
    south = north = east = west = 0
    # encontrando o ponto mais baixo
    for i in range(1, len(l)):
        if l[i].y < l[south].y:
            south = i
        elif l[i].y == l[south].y:
            if l[i].x > l[south].x:
                south = i

        if l[i].y > l[north].y:
            north = i
        elif l[i].y == l[north].y:
            if l[i].x > l[north].x:
                north = i

        if l[i].x < l[west].x:
            west = i
        elif l[i].x == l[west].x:
            if l[i].y > l[west].y:
                west = i

        if l[i].x > l[east].x:
            east = i
        elif l[i].x == l[east].x:
            if l[i].y > l[east].y:
                east = i

    fecho = []
    dirs = [south, east, north, west]
    for i in range(0, len(dirs)):
        j = (i + 1) % 4
        if dirs[i] == dirs[j]:
            continue
        fecho.append(l[dirs[i]])
        S1 = []
        a = l[dirs[i]]
        b = l[dirs[j]]
        for p in l:
            if right(a, b, p):
                S1.append(p)
        id = a.lineto(b, config.COLOR_ALT4)
        aux = []
        if len(S1) > 0:
            if dirs[i] == south or dirs[i] == west:
                aux = bhatta_sen_lower_rec(a, b, S1)
            else:
                aux = bhatta_sen_upper_rec(a, b, S1)
        a.remove_lineto(b, id)
        if len(aux) > 0:
            a.lineto(aux[0])
            aux[-1].lineto(b)
        else:
            a.lineto(b)
        fecho.extend(aux)

    if len(l) == 1:
        fecho = [l[0]]
    pol = Polygon(fecho)
    pol.plot()
    pol.extra_info = "vertices: %d" % len(fecho)

    return pol
Exemple #19
0
def Hull2D (P, m, H):

	#print m, H
	lines = []
	n = len (P)
	CHs = []
	num = n/m

	a = 0
	while a < n:
		b = min (a+m, n)
		l = P[a:b]
		ids = []
		for p in l: ids.append (p.hilight ())
		ch = Graham (l)
		#ch.hide ()
		for p in P[a:b]: p.unhilight (ids.pop ())
		CHs.append (ch)
		a = b

	i0 = 0
	# encontrando o ponto mais a direita
	p0 = CHs[0].pts
	for ch in CHs:
		for p in ch.to_list ():
			if p.x > p0.x: p0 = p
			elif p.x == p0.x: 
				if p.x > p0.x: p0 = p
	
	fecho = [ p0 ]
	for ch in CHs: ch.hide ()
	#control.sleep (2)
	for k in range (0, H):
		Q = []
		for ch in CHs:
			ch.plot ()
			p = ch.pts
			initial = 1
			while 1:
				direction = area2 (fecho[-1], p, p.next)
				if direction < 0:
					p = p.next
					initial = 0
				elif direction == 0 \
					and dist2 (fecho[-1], p) \
					    < dist2 (fecho[-1], p.next):
					p = p.next
					initial = 0
				elif initial:
					p = p.next
				else:
					Q.append (p)
					p.hilight ()
					control.sleep ()
					ch.pts = p.prev
					ch.hide ()
					break
			

		control.sleep ()
		p = Q[0]
		for q in Q[1:]:
			direction = area2 (fecho[-1], p, q)
			if direction < 0:
				p = q
			elif direction == 0:
				if (dist2 (fecho[-1], p) < dist2 (fecho[-1], q)):
					p = q

		for q in Q: q.unhilight ()
		lines.append (fecho[-1].lineto (p, 'green'))
		fecho.append (p)
		if p == p0: 
			#for ch in CHs: ch.hide ()
			#print 'fecho =',`fecho`
			fecho.pop ()
			for i in lines:
				control.plot_delete (i)
			poly = Polygon (fecho)
			poly.plot ()
			return poly
	
	#for ch in CHs: ch.hide ()
	for i in lines:
		control.plot_delete (i)
	return None
Exemple #20
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
def Graham (l):
	"Algoritmo de Graham para achar o fecho convexo de uma lista l de pontos"

	if len (l) == 0: return None

	# So um ponto foi passado. Retorna um fecho c/ apenas um ponto
	if len (l) == 1:
		ret = Polygon (l)
		ret.plot ()
		ret.extra_info = 'vertices: 1'
		return ret

	p0 = l[0]

	# acha o ponto mais baixo
	for i in range (1, len(l)):
		if l[i].y < p0.y:
			p0 = l[i]
		elif l[i].y == p0.y:
			if l[i].x > p0.x:
				p0 = l[i]

	l.remove (p0)

	def cmp (x, y, z = p0):
		"""Funcao para ordenar os pontos ao redor de z

		Usada com a funcao sort, ordena os pontos de uma lista
		de acordo com o angulo que cada ponto forma com o ponto 
		z e a reta horizontal. Em caso de empate, o ponto mais
		distante aparece primeiro."""
		area = area2 (z, x, y)
		if area > 0:
			return -1
		elif area < 0:
			return 1
		else:
			dist_z_x = dist2 (z, x)
			dist_z_y = dist2 (z, y)
			if dist_z_y < dist_z_x:
				return -1
			return dist_z_y > dist_z_x

	# Ordena os pontos pelo seus angulos
	l.sort (cmp)

	# eliminando pontos colineares
	l2 = [ l[0] ]
	for i in range (1, len (l)):
		if collinear (p0, l[i-1], l[i]):
			continue
		l2.append (l[i])

	l = l2

	# So sobraram dois pontos -> retorna fecho c/ os dois
	if len (l) < 2:
		ret = Polygon ( [ p0, l[0] ] )
		ret.plot ()
		ret.extra_info = 'vertices: 2'
		return ret

	pilha = [ p0, l[0], l[1] ]

	p0.lineto (l[0])
	l[0].lineto (l[1])
	control.sleep ()

	for i in range (2, len(l)):
		l[i].hilight ()
		pilha[-1].lineto (l[i])
		control.sleep ()

		while not left (pilha[-2], pilha[-1], l[i]):
			pilha[-2].remove_lineto (pilha[-1])
			pilha[-1].remove_lineto (l[i])

			pilha.pop ()

			pilha[-1].lineto (l[i])
			control.sleep ()


		pilha.append (l[i])

		l[i].unhilight ()
		
	pilha[-1].lineto (pilha[0])
	

	for i in range (0, len(pilha)-1):
		pilha[i].remove_lineto (pilha[i+1])

	pilha[-1].remove_lineto (pilha[0])
	poligono = Polygon (pilha)
	poligono.plot ()
	control.thaw_update ()

	poligono.extra_info = 'vertices: %d'%len (poligono.to_list ())
	return poligono
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
Exemple #23
0
def Hull2D (P, m, H):

	#print m, H
	lines = []
	n = len (P)
	CHs = []
	num = n/m

	a = 0
	while a < n:
		b = min (a+m, n)
		l = P[a:b]
		ids = []
		for p in l: ids.append (p.hilight ())
		ch = Graham (l)
		#ch.hide ()
		for p in P[a:b]: p.unhilight (ids.pop ())
		CHs.append (ch)
		a = b

	i0 = 0
	# encontrando o ponto mais a direita
	p0 = CHs[0].pts
	for ch in CHs:
		for p in ch.to_list ():
			if p.x > p0.x: p0 = p
			elif p.x == p0.x: 
				if p.x > p0.x: p0 = p
	
	fecho = [ p0 ]
	for ch in CHs: ch.hide ()
	#control.sleep (2)
	for k in range (0, H):
		Q = []
		for ch in CHs:
			ch.plot ()
			p = ch.pts
			initial = 1
			while 1:
				direction = area2 (fecho[-1], p, p.next)
				if direction < 0:
					p = p.next
					initial = 0
				elif direction == 0 \
					and dist2 (fecho[-1], p) \
					    < dist2 (fecho[-1], p.next):
					p = p.next
					initial = 0
				elif initial:
					p = p.next
				else:
					Q.append (p)
					p.hilight ()
					control.sleep ()
					ch.pts = p.prev
					ch.hide ()
					break
			

		control.sleep ()
		p = Q[0]
		for q in Q[1:]:
			direction = area2 (fecho[-1], p, q)
			if direction < 0:
				p = q
			elif direction == 0:
				if (dist2 (fecho[-1], p) < dist2 (fecho[-1], q)):
					p = q

		for q in Q: q.unhilight ()
		lines.append (fecho[-1].lineto (p, 'green'))
		fecho.append (p)
		if p == p0: 
			#for ch in CHs: ch.hide ()
			#print 'fecho =',`fecho`
			fecho.pop ()
			for i in lines:
				control.plot_delete (i)
			poly = Polygon (fecho)
			poly.plot ()
			return poly
	
	#for ch in CHs: ch.hide ()
	for i in lines:
		control.plot_delete (i)
	return None