Beispiel #1
0
def Brute (l):
	"Algoritmo forca bruta para encontrar o par de pontos mais distante"

	if len (l) < 2: return None
	
	farthest = 0
	a = b = None
	id = None

	for i in range (len(l)):
		for j in range (i + 1, len (l)):
			dist = dist2 (l[i], l[j])
			if dist > farthest:
				control.freeze_update ()
				if a != None: a.unhilight (hia)
				if b != None: b.unhilight (hib)
				if id != None: control.plot_delete (id)

				farthest = dist
				a = l[i]
				b = l[j]

				hia = a.hilight ()
				hib = b.hilight ()
				id = a.lineto (b)
				control.thaw_update ()
				control.update ()
	
	ret = Segment (a, b)
	ret.extra_info = 'distancia: %.2f'%math.sqrt (dist2 (a, b))
	return ret
Beispiel #2
0
def Brute (l):
	"Algoritmo forca bruta para encontrar o par de pontos mais proximo"

	if len (l) < 2: return None
	
	closest = float("inf")
	a = b = None
	id = None

	for i in range (len(l)):
		for j in range (i + 1, len (l)):
			dist = dist2 (l[i], l[j])
			if dist < closest:
				control.freeze_update ()
				if a != None: a.unhilight (hia)
				if b != None: b.unhilight (hib)
				if id != None: control.plot_delete (id)

				closest = dist
				a = l[i]
				b = l[j]

				hia = a.hilight ()
				hib = b.hilight ()
				id = a.lineto (b)
				control.thaw_update() 
				control.update ()

	a.hilight('green')
	b.hilight('green')
	ret = Segment (a, b)
	ret.extra_info = 'distancia: %.2f'%math.sqrt (dist2 (a, b))
	print(math.sqrt (dist2 (a, b)))
	return ret
Beispiel #3
0
 def edges(self):
     edges = []
     p = self.pts
     while p.next != self.pts:
         edges.append(Segment(p, p.next))
         p = p.next
     edges.append(Segment(p, p.next))
     return edges
Beispiel #4
0
def trata_ponta_pra_baixo (p, L, dcel, diags):
    t = Trapezio (p)
    removido1 = (L.busca (t)).elemento
    removido1.apaga()
    L.deleta (t)
    
    if ponta_pra_baixo (removido1.sup):
        d = Segment (removido1.sup, p)
        d.plot('blue')
        control.sleep()
        dcel.add_edge (d.init, d.to)
        diags.append(d)
    
    # Se tem outro polígono
    removido2 = (L.busca (t)).elemento
    if removido2 != None:
        L.deleta (t)
        removido2.apaga()
        
        if ponta_pra_baixo (removido2.sup):
            d = Segment (removido2.sup, p)
            d.plot('blue')
            control.sleep()
            dcel.add_edge (d.init, d.to)
            diags.append(d)
            
        if removido2.a_esq.to == p:
            t = Trapezio (p, removido1.a_esq, removido2.a_dir)
        else:
            t = Trapezio (p, removido2.a_esq, removido1.a_dir)
        L.insere (t)
        t.desenha()
        control.sleep()
Beispiel #5
0
def trata_ponta_pra_cima (p, L, dcel, diags):
    viz_esq = p.next
    viz_dir = p.prev
    if left (p, viz_dir, viz_esq):
        viz_esq, viz_dir = viz_dir, viz_esq
    
    t = Trapezio (p)
    removido = (L.busca (t)).elemento
    
    if removido == None:
        t.a_esq = Segment (p, viz_esq)
        t.a_dir = Segment (p, viz_dir)
        t.desenha()
        L.insere (t)
    
    else:
        L.deleta (t)
        removido.apaga()
        d = Segment (p, removido.sup)
        d.plot('blue')
        dcel.add_edge (d.init, d.to)
        diags.append(d)
        control.sleep()
        
        
        t1 = Trapezio (p, removido.a_esq, Segment (p, viz_esq))
        t2 = Trapezio (p, Segment (p, viz_dir), removido.a_dir)
        t1.desenha()
        t2.desenha()
        L.insere (t1)
        L.insere (t2)
        
    control.sleep()
Beispiel #6
0
def ShamosRec(l, i, j):
    " Função que faz o serviço recursivo "
    " recebe uma lista de pontos l[i:j] ordenados pela coordenada x "
    # Base da recursão, 2 ou 1 ponto
    if j - i < 3:
        # registra o par mais proximo
        par_min = Segment(l[i], l[j - 1])
        # Ordena pelo eixo y
        if (l[i].y > l[j - 1].y):
            l[i], l[j - 1] = l[j - 1], l[i]
    else:
        q = (i + j) // 2
        meio = l[q]

        vert_id = control.plot_vert_line(meio.x)
        verde = meio.hilight()
        control.sleep()

        # Calcula o menor das duas metades
        par_esq = ShamosRec(l, i, q)
        par_dir = ShamosRec(l, q, j)

        par_min = minPar(par_esq, par_dir)

        # Intercala do mergeSort escondido
        intercalaY(l, i, j)

        control.plot_delete(vert_id)
        meio.unhilight(id=verde)

        # Calcula o menor entre as duas metade
        par_inter = menorInter(l, i, j, meio, par_min)
        if par_inter != None:
            par_min = minPar(par_inter, par_min)
            par_inter.hide()

        par_esq.unhilight()
        par_dir.unhilight()

    global d
    dnovo = math.sqrt(dist(par_min))
    d = min(d, dnovo)

    par_min.hilight("red")
    control.sleep()
    return par_min
Beispiel #7
0
def visivel(T, S, p, i):

    a = S[i]
    a.visivel = False  #Até que se prove o contrário

    if (a is p):
        a.visivel = True
        return a.visivel

    #Testa se a reta p->s[i] passa por dentro do polígono
    # de p.
    if (p.prev != p):  #p está em algum polígono
        if (noCone(p.prev, p, p.next, a)):
            a.visivel = False
            #Falhou no cone
            return a.visivel

    if (i == 0 or not collinear(p, S[i - 1], a)):
        segMin = T.getMin()
        if (segMin is None):
            a.visivel = True
            #seg min é null
            return a.visivel
        #Testando intersec com min
        a.visivel = not intersectaProp(segMin, Segment(p, a))
    elif (not S[i - 1].visivel):
        # Anterior não é visível
        a.visivel = False
    else:
        if (S[i - 1].prev != S[i - 1]):  #S[i-1] esta em um polígono
            if (noCone(S[i - 1].prev, S[i - 1], S[i - 1].next, a)):
                a.visivel = False
                print("Falhou no cone 2")
                return a.visivel

        segTemp = Segment(S[i - 1], a)
        seg2 = T.getProx(S[i - 1])
        # Testando o segmento do meio #

        if (seg2 is None):
            a.visivel = True
        else:
            a.visivel = not intersectaProp(seg2, segTemp)

    return a.visivel
Beispiel #8
0
    def __init__(self, u, v):
        self.origin = u
        self.dest = v
        self.twin = None
        self.face = None
        self.next_hedge = None
        self.segment = Segment(u.p, v.p)
        self.segment.lid = None

        u.hedge = self
	def newEdge(self, x1, y1, x2, y2):
		vertex1 = self.findVertex(x1, y1)
		vertex2 = self.findVertex(x2, y2)
		if (vertex1 != None) and (vertex2 != None):
			self.allEdge.append(Edge(vertex1, vertex2))
			point1 = Point(vertex1.getX(), vertex1.getY())
			point2 = Point(vertex2.getX(), vertex2.getY())
			Printo(Segment(point1, point2))
		else:
			print("Falhou em newEdge -- vertices errados!")
Beispiel #10
0
    def desenha (self):
        cima = self.sup.y
        baixo = max (self.a_esq.to.y, self.a_dir.to.y)
        
        # Acha os dois pontos da esquerda
        x1, y1 = self.a_esq.init.x, self.a_esq.init.y
        x2, y2 = self.a_esq.to.x, self.a_esq.to.y
        cima_esq = Point ((x2*y1 - x1*y2 + cima*(x1 - x2))/(y1 - y2), cima)
        baixo_esq = Point ((x2*y1 - x1*y2 + baixo*(x1 - x2))/(y1 - y2), baixo)

        # Acha os dois pontos da direita
        x1, y1 = self.a_dir.init.x, self.a_dir.init.y
        x2, y2 = self.a_dir.to.x, self.a_dir.to.y
        cima_dir = Point ((x2*y1 - x1*y2 + cima*(x1 - x2))/(y1 - y2), cima)
        baixo_dir = Point ((x2*y1 - x1*y2 + baixo*(x1 - x2))/(y1 - y2), baixo)
        
        self.aresta_cima = (Segment (cima_esq, cima_dir)).plot('green')
        self.aresta_baixo = (Segment (baixo_esq, baixo_dir)).plot('green')
        self.aresta_esq = (Segment (baixo_esq, cima_esq)).plot('green')
        self.aresta_dir = (Segment (baixo_dir, cima_dir)).plot('green')
Beispiel #11
0
def intersectaBorda(u, w, P):
    """ Função que recebe dois vértices u e w do polígono P e retorna se o 
        segmento uw intersecta alguma aresta de P
        (equivalente a função QuaseDiagonal dos slides)
    """
    borda = P.edges()
    uw = Segment(u, w)
    for aresta in borda:
        aresta.plot('cyan')
        sleep()
        if (u not in aresta.endpoints()) and (w not in aresta.endpoints()):
            if (uw.intersects(aresta)):
                aresta.hide()
                aresta.plot('yellow')
                sleep()
                aresta.hide()
                return True
        aresta.hide()

    return False
Beispiel #12
0
def trata_caso_meio (p, viz_baixo, L, dcel, diags):
    # Remove da linha o trapésio que tem o p
    t = Trapezio (p)
    removido = (L.busca (t)).elemento
    removido.apaga()
    L.deleta (t)
    
    if ponta_pra_baixo (removido.sup):
        d = Segment (removido.sup, p)
        d.plot('blue')
        dcel.add_edge (d.init, d.to)
        diags.append(d)
        control.sleep()
        
    # Insere um novo trapésio com o p
    # Se o removido estava a direita
    if (p == removido.a_dir.to):
        t.a_dir = Segment (p, viz_baixo)
        t.a_esq = removido.a_esq        
    # Se estava a esquerda
    else:
        t.a_esq = Segment (p, viz_baixo)
        t.a_dir = removido.a_dir
    t.desenha()
    L.insere (t)
    control.sleep()
	def visit(self, u, target):
		u.setVisited(True)
		v = self.findNeighbor(u)
		while v is not None:

			# Printando o segmento atual do grafo
			seg = Segment(Point(u.x, u.y), Point(v.x, v.y))
			seg.plot('cyan')
			control.sleep()

			# Continuar o DFS
			if (v == target):
				self.solved = True
				return 1
			self.visit(v, target)

			# Condicao de parada do DFS
			if(self.solved):
				return 1

			# Retirando o print do segmento
			seg.hide()
			control.sleep()

			# Pegar o próximo vizinho
			v = self.findNeighbor(u)
Beispiel #14
0
def read_segments(filename):
    if filename is None:
        raise ValueError("File name is None")
    with open(filename) as file:
        segments = set()
        for line in file:
            line = line.split()
            if len(line) != 4:
                raise ValueError("Invalid input from file: {}: {}".format(
                    filename, line))
            segments.add(
                Segment(Point(float(line[0]), float(line[1])),
                        Point(float(line[2]), float(line[3]))))
        return segments
Beispiel #15
0
def read_intersections(filename):
    if filename is None:
        raise ValueError("File name is None")
    with open(filename) as file:
        intersections = {}
        point = None
        for line in file:
            line = line.split()
            if len(line) == 2:
                point = Point(float(line[0]), float(line[1]))
                intersections[point] = set()
            if len(line) == 4:
                intersections[point].add(
                    Segment(Point(float(line[0]), float(line[1])),
                            Point(float(line[2]), float(line[3]))))
        return intersections
Beispiel #16
0
def Generate(l):
    # Dado a lista de pontos do poligono e gera todos os segmentos de retas
    lsegments = []
    n = len(l)
    if (n == 2):
        lsegments.append(
            SSegment(SPoint(l[0].x, l[0].y), SPoint(l[1].x, l[1].y)))
        seg = Segment(Point(l[0].x, l[0].y), Point(l[1].x, l[1].y))
        seg.plot('green')
        control.sleep()
    else:
        for i in range(n):
            lsegments.append(
                SSegment(SPoint(l[i % n].x, l[i % n].y),
                         SPoint(l[(i + 1) % n].x, l[(i + 1) % n].y)))
            seg = Segment(Point(l[i % n].x, l[i % n].y),
                          Point(l[(i + 1) % n].x, l[(i + 1) % n].y))
            seg.plot('green')
            control.sleep()
    return lsegments
Beispiel #17
0
def isDiagonal(u, w, P):
    """ Função que recebe dois vértices u e w do polígono P e retorna se uw é 
        uma diagonal de P
    """
    # colore a candidata a diagonal
    uw = Segment(u, w)
    uw.plot('blue')
    sleep()

    # Como o dentroDoPoligono é O(1) é muito prudente fazer esse teste primeiro
    result = dentroDoPoligono(u, w, P) and (not intersectaBorda(u, w, P))
    uw.hide()
    return result
Beispiel #18
0
 def __init__(self, p1, p2, p3, a):
     if left(p1, p2, p3):
         self.p1 = p1
         self.p2 = p2
     else:
         self.p1 = p2
         self.p2 = p1
     self.p3 = p3
     self.a = a  # Alguma aresta da DCEL que faz parte desse triangulo
     self.filhos = []  # Node_Triangs que são filhos do self no DAG
     # arestas
     self.a1 = Segment(self.p1, self.p2)
     self.a2 = Segment(self.p2, self.p3)
     self.a3 = Segment(self.p3, self.p1)
Beispiel #19
0
def menorInter(l, i, j, meio, par_min):
    " Retorna o par de pontos mais proximo dentro da faixa dada pelo ponto meio da lista "
    " e a distancia do min_par "
    global d

    blue = meio.hilight("blue")

    # desenha a faixa que eu estou procurando
    v1 = control.plot_vert_line(meio.x - d, "blue")
    v2 = control.plot_vert_line(meio.x + d, "blue")
    control.sleep()

    par_inter = None
    cand = candidatos(l, i, j, meio)

    for k in range(len(cand)):
        cyan = cand[k].hilight("cyan")
        for l in range(k + 1, len(cand)):

            # Se os pontos já estão distantes, posso parar de olhar
            if (cand[l].y - cand[k].y > d):
                break

            cand_inter = Segment(cand[k], cand[l])
            cand_inter.plot("cyan")
            control.sleep()
            cand_inter.hide()

            dcand = math.sqrt(dist2(cand[k], cand[l]))
            # Se achei um novo par, apaga o outro e pinta esse
            if (dcand < d):
                d = dcand
                if par_inter != None:
                    par_inter.hide()
                par_inter = cand_inter
                par_inter.plot("blue")
                control.sleep()

        cand[k].unhilight(id=cyan)

    control.plot_delete(v1)
    control.plot_delete(v2)
    meio.unhilight(id=blue)
    control.sleep()

    return par_inter
Beispiel #20
0
def dentroDoPoligono(u, w, P):
    """ Função que recebe dois vértices u e w do polígono P e retorna se a 
        candidata a diagonal uw está pra dentro do polígono
        (equivalente a função NoCone dos slides)
    """
    prevU = u.prev
    nextU = u.next
    if (left_on(prevU, u, nextU)):
        resposta = (left(u, w, prevU) and left(w, u, nextU))
    else:
        resposta = not (left_on(u, w, nextU) and left_on(w, u, prevU))

    if not resposta:
        uw = Segment(u, w)
        uw.plot("yellow")
        sleep()
        uw.hide()

    return resposta
def Diameter (l):
	"""Algoritmo Diametro para encontrar o par de pontos mais distantes

	Ele consiste de:
	- determinar o fecho convexo dos pontos passados
	- determinar o conjunto de pares antipodas do fecho convexo
	- determinar o par antipoda cujos pontos estao a uma distancia maxima
	"""

	if len (l) < 2: return None
	if len (l) == 2:
		ret = Segment (l[0], l[1])
		ret.extra_info = 'distancia: %.2f'%math.sqrt (dist2 (l[0], l[1]))
		return ret
	
	ch = Graham (l)
	ch.hide ()
	ch.plot (config.COLOR_ALT4)

	control.sleep ()

	pairs = antipodes (ch)
	cores = (config.COLOR_ALT1,)

	#print `pairs`

	i=0
	for p,q in pairs:
		p.hilight (cores[i])
		q.hilight (cores[i])
		p.lineto (q, cores[i])
		i = (i+1) % len (cores)

	control.sleep ()

	farthest = dist2 (pairs[0][0], pairs[0][1])
	a = pairs[0][0]
	b = pairs[0][1]
	hia = a.hilight ()
	hib = b.hilight ()
	id = a.lineto (b)

	for i in range (1, len (pairs)):
		dist = dist2 (pairs[i][0], pairs[i][1])
		if dist > farthest:
			control.freeze_update ()
			a.unhilight (hia)
			b.unhilight (hib)
			control.plot_delete (id)

			farthest = dist
			a = pairs[i][0]
			b = pairs[i][1]

			hia = a.hilight ()
			hib = b.hilight ()
			id = a.lineto (b)
			control.thaw_update ()
	
	ret = Segment (a, b)
	ret.extra_info = 'distancia: %.2f'%math.sqrt (farthest)
	return ret
def intersects(seg1: Segment, seg2: Segment) -> bool:
    ''' Returns whether two segments intersect or not. '''
    return seg1.intersects(seg2)
Beispiel #23
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
def shamos_hoey(segmentos, estrutura):
    global cores

    if len(segmentos) == 0: return None

    # Abaixo, redefinimos as funcoes de comparacao de segmentos para nosso proposito
    Segment.__lt__ = lambda s1, s2: prim.compara_segmentos(x_linha_varredura, s1, s2) == -1
    Segment.__ge__ = lambda s1, s2: prim.compara_segmentos(x_linha_varredura, s1, s2) >= 0

    E = [] # inicializa fila de eventos

    for i, segmento in enumerate(segmentos):
        # se e_x > d_x, entao inverte os pontos que determinam o segmento 
        # (pontos da esquerda nao podem ter x-coordenada maior que pontos da direita)
        if (segmento.init.x > segmento.to.x): 
            segmento.reverse()

        # tambem inverte se for segmento vertical com inicio (init) com menor y-coordenada do que fim (to)
        elif (segmento.init.x == segmento.to.x and segmento.init.y < segmento.to.y):
            segmento.reverse()

        segmento.id = i
        segmento.intersected = False
        # coloca na fila de eventos E
        E.append(PontoEvento(segmento.init, 'esquerdo', i))
        E.append(PontoEvento(segmento.to, 'direito', i))

    E.sort() # ordena pontos eventos por x-coordenada

    global x_linha_varredura

    pred,suc = None, None

    for ponto_evento in E:
        x_linha_varredura = ponto_evento.ponto.x

        #Remove o destaque da iteracao passada
        destaca_segs( [pred, suc], 'presente')

        seg = segmentos[ponto_evento.id_segmento]
        pred = estrutura.predecessor(seg)
        suc = estrutura.sucessor(seg)

        #Destaca os segmentos que serao analisados
        destaca_segs( [pred, suc], 'vizinho')

        if ponto_evento.tipo == 'esquerdo':
            destaca_segs([seg], 'presente')
            estrutura.insere(seg)
            if pred != None:
                if prim.inter(seg,pred) == True: # Detectou interseccao do seg com o pred
                    destaca_segs([seg,pred], 'intersectado')
                    seg.intersected, pred.intersected = True, True
                    break

            if suc != None:
                if prim.inter(seg,suc) == True: # Detectou interseccao do seg com o suc
                    destaca_segs([seg,suc], 'intersectado')
                    seg.intersected, suc.intersected = True, True
                    break

        elif ponto_evento.tipo == 'direito':
            destaca_segs([seg], 'passado')
            estrutura.remove(seg)
            if (pred != None and suc != None):
                if prim.inter(pred,suc) == True: # Detectou interseccao do pred com o suc
                    destaca_segs([pred,suc], 'intersectado')
                    pred.intersected, suc.intersected = True, True
                    break

        linha_varredura_plotada_id = control.gui.plot_vert_line (x_linha_varredura, config.COLOR_LINE_SPECIAL, 1) # plota a linha de varredura
        control.sleep() # dorme
        control.gui.plot_delete(linha_varredura_plotada_id) # desplota a linha de varredura

    if estrutura.__class__.__name__ == 'Skiplist':
        ret = Segment() # pequeno hack, porque resolvemos um problema de decisão, e não temos nada (nenhum polígono, por exemplo) para retornar
                        # e para o algoritmo de Skip List queremos devolver essa informacao extra abaixo
        ret.extra_info = 'SL: p = ' + str(estrutura.p) + ' nivelmax = '  + str(estrutura.maxnivel) + ' (media de niveis = ' + str( (estrutura.somaniveis / (2*len(segmentos)))) + ')'
        return ret
Beispiel #25
0
def Diameter(l):
    """Algoritmo Diametro para encontrar o par de pontos mais distantes

	Ele consiste de:
	- determinar o fecho convexo dos pontos passados
	- determinar o conjunto de pares antipodas do fecho convexo
	- determinar o par antipoda cujos pontos estao a uma distancia maxima
	"""

    if len(l) < 2: return None
    if len(l) == 2:
        ret = Segment(l[0], l[1])
        ret.extra_info = 'distancia: %.2f' % math.sqrt(dist2(l[0], l[1]))
        return ret

    ch = Graham(l)
    ch.hide()
    ch.plot(config.COLOR_ALT4)

    control.sleep()

    pairs = antipodes(ch)
    cores = (config.COLOR_ALT1, )

    #print `pairs`

    i = 0
    for p, q in pairs:
        p.hilight(cores[i])
        q.hilight(cores[i])
        p.lineto(q, cores[i])
        i = (i + 1) % len(cores)

    control.sleep()

    farthest = dist2(pairs[0][0], pairs[0][1])
    a = pairs[0][0]
    b = pairs[0][1]
    hia = a.hilight()
    hib = b.hilight()
    id = a.lineto(b)

    for i in range(1, len(pairs)):
        dist = dist2(pairs[i][0], pairs[i][1])
        if dist > farthest:
            control.freeze_update()
            a.unhilight(hia)
            b.unhilight(hib)
            control.plot_delete(id)

            farthest = dist
            a = pairs[i][0]
            b = pairs[i][1]

            hia = a.hilight()
            hib = b.hilight()
            id = a.lineto(b)
            control.thaw_update()

    ret = Segment(a, b)
    ret.extra_info = 'distancia: %.2f' % math.sqrt(farthest)
    return ret
Beispiel #26
0
 def __init__ (self, x, y, r):
     "Para criar um disco, passe suas coordenadas."
     self.center = Point(x, y)
     self.r = r
     self.seg = Segment(Point(x-r, y), Point(x+r,y))
     self.lineto_id = {}
Beispiel #27
0
def Varre(l):
    "Algoritmo de divisão e conquista para encontrar o par de pontos mais proximo"
    "Recebe uma lista de pontos l"

    if len(l) < 2: return None

    d = float("inf")

    l = sorted(l, key=lambda x: x.x)

    par_min = None
    faixa = Abbb()

    p_min = 0

    for i in range(len(l)):
        p = l[i]
        no_p = Node_point(p)

        # Caso degenerado -> pontos coincidentes
        # (não conseguimos adicionar na abbb, pois ja tem um clone dele)
        repetido = faixa.busca(no_p).elemento
        if repetido != None:
            if par_min != None:
                par_min.hide()
            par_min = Segment(p, repetido.p)
            break

        faixa.insere(no_p)
        p.hilight()

        # Remove os pontos fora da faixa
        while p.x - l[p_min].x > d:

            l[p_min].unhilight()
            no_p_min = Node_point(l[p_min])
            faixa.deleta(no_p_min)
            p_min += 1

        # Desenha o quadradinho de candidatos
        linha_frente = control.plot_vert_line(p.x)
        if i > 1:
            linha_tras = control.plot_vert_line(p.x - d, color="blue")
            linha_cima = Segment(Point(p.x, p.y + d), Point(p.x - d, p.y + d))
            linha_baixo = Segment(Point(p.x, p.y - d), Point(p.x - d, p.y - d))
            linha_cima.plot("blue")
            linha_baixo.plot("blue")
        control.sleep()

        # Extrai os pontos da abbb até a distancia vertical ficar maior que d
        # Primeiro com os vizinhos de cima
        vizinho = faixa.sucessor(no_p)
        while vizinho != None and vizinho.p.y - p.y < d:
            # Despinta das cores atuais, dai o dist2 pinta de amarelo, depois repinta de novo
            p.unhilight()
            vizinho.p.unhilight()
            d2 = dist2(p, vizinho.p)
            p.hilight()
            vizinho.p.hilight("blue")
            if d2 < d * d:
                d = d2**0.5

                if par_min != None:
                    par_min.hide()
                par_min = Segment(p, vizinho.p)
                par_min.plot("red")
                control.sleep()

            vizinho = faixa.sucessor(vizinho)
        # Depois com os vizinhos de baixo
        vizinho = faixa.predecessor(no_p)
        while vizinho != None and p.y - vizinho.p.y < d:
            # Despinta das cores atuais, dai o dist2 pinta de amarelo, depois repinta de novo
            p.unhilight()
            vizinho.p.unhilight()
            d2 = dist2(p, vizinho.p)
            p.hilight()
            vizinho.p.hilight("blue")
            if d2 < d * d:
                d = d2**0.5

                if par_min != None:
                    par_min.hide()
                par_min = Segment(p, vizinho.p)
                par_min.plot("red")
                control.sleep()

            vizinho = faixa.predecessor(vizinho)

        # Apaga o quadradinho
        control.plot_delete(linha_frente)
        if (i > 1):
            control.plot_delete(linha_tras)
            linha_cima.hide()
            linha_baixo.hide()

        p.unhilight()
        l[i].hilight("blue")

    "despinta quem sobrou na faixa"
    while (not faixa.vazia()):
        faixa.deleta_min().p.unhilight()
    par_min.hilight("red", "red")
Beispiel #28
0
def Monotono(p):

    # Essa é a forma que eu recebo o polígono do front-end :/
    P = p[0]
    # lista com as diagonais, nosso return
    resp = []

    v = ordenaY(P)
    n = len(v)

    s = [v[0], v[1]]  # pilha
    v[0].hilight('blue')
    v[1].hilight('blue')
    t = 1  # index do fim da pilha

    for i in range(2, n):
        v[i].hilight('green')
        sleep()
        vizinho_ultimo = adj(v[i], s[t])
        vizinho_primeiro = adj(v[i], s[0])

        if vizinho_ultimo and not vizinho_primeiro:
            while t > 0:
                a = s[t - 1]
                b = s[t]
                if a.x > b.x:
                    a, b = b, a
                if right(a, b, v[i]):
                    s[t].unhilight()
                    s.pop()
                    t -= 1
                    # acrescenta a nova diagonal
                    d = Segment(s[t], v[i])
                    d.plot('green')
                    sleep()
                    resp.append(d)
                else:
                    break
            t += 1
            s.append(v[i])
            v[i].unhilight()
            v[i].hilight('blue')

        elif vizinho_primeiro and not vizinho_ultimo:
            aux = s[t]
            while t > 0:
                # acrescenta a nova diagonal
                d = Segment(s[t], v[i])
                d.plot('green')
                sleep()
                resp.append(d)

                s.pop()
                t -= 1
                s[t].unhilight()
            s = []
            s.append(aux)
            s.append(v[i])
            v[i].unhilight()
            v[i].hilight('blue')
            t = 1

        else:
            while t > 1:
                s[t].unhilight()
                t -= 1
                # acrescenta a nova diagonal
                d = Segment(s[t], v[i])
                d.plot('green')
                sleep()
                resp.append(d)
            s[0].unhilight()
            s[1].unhilight()
            v[i].unhilight()
    return resp
Beispiel #29
0
def triangulaMonotono2(l,diagonais):#Os pontos devem vir em ordem anti-horária
    pontos = [] #lista com os pontos,juntamente com seus indices
    verts = [] #lista com os pontos ordenados
    pilha = [] #pilha usada no algoritmo
    lado = []

    for x in range(len(l)):#desenha poligono
        if(x != len(l)-1): l[x].lineto(l[(x+1)],'red')
        else: l[x].lineto(l[0],'red')
                                        
    N = len(l)

    for i in range(N): 
        pontos.append((l[i],i)) #transforma cada ponto numa dupla (ponto,indice)
        lado.append(True)
    
    ########################################### 
    #Esse pedaço acha o vertice mais alto e o mais baixo e realiza o merge
    yMax = -20000000
    yMin = 2000000
    vMax = pontos[0]
    vMin = pontos[N-1]

    for i in range(N):
        if(pontos[i][0].y == yMax and pontos[i][0].x < vMax[0].x): vMax = pontos[i]
        if(pontos[i][0].y == yMin and pontos[i][0].x > vMin[0].x): vMin = pontos[i]
        if(pontos[i][0].y > yMax):
            vMax = pontos[i]
            yMax = vMax[0].y
        if(pontos[i][0].y < yMin):
            vMin = pontos[i]
            yMin = vMin[0].y
            
    if(vMax[1] != N-1):v = pontos[vMax[1]+1]
    else: v = pontos[0]
            
    if(vMax[1]!= 0): i = vMax[1]-1
    else: i = N-1

    if(vMax[1]!= N-1):j = vMax[1]+1
    else: j = 0

    lado[vMin[1]] = False

    if(vMax[1]!= 0): i = vMax[1]-1
    else: i = N-1

    if(vMax[1]!= N-1):j = vMax[1]+1
    else: j = 0            

    verts.append(vMax);
    while(len(verts) < N): #Merge
        if(pontos[j] == vMin):
            while(pontos[i] != vMin):
                verts.append(pontos[i])
                if(i!=0):i -= 1
                else: i = N-1
        elif(pontos[i] == vMin):
            while(pontos[j] != vMin):
                lado[pontos[j][1]] = False
                verts.append(pontos[j])
                if(j != N-1):j += 1
                else: j = 0

        if((pontos[j][0].y >= pontos[i][0].y)):
            lado[pontos[j][1]] = False
            verts.append(pontos[j])
            if(j != N-1): j+= 1
            else: j = 0
        else:
            verts.append(pontos[i])
            if(i!=0):i -= 1
            else: i = N-1

    ########################################

    #verts = sorted(pontos,key=lambda x: (x[0].y,-x[0].x), reverse=True)	 

    print verts

    pilha.append(verts[0])
    pilha.append(verts[1])

    for i in range(2,N):
        t = len(pilha)
        print "____________________"
        print pilha
        verts[i][0].hilight("yellow")
        control.sleep()
        if(verts[i][1] == 0): ant = len(l)-1
        else: ant = verts[i][1]-1

        if(verts[i][1] == len(l)-1): prox = 0
        else: prox = verts[i][1]+1

        #aqui pilha[t-1][1] é o St e pilha[0][1] o S1, de acordo com os slides

   #Caso A ########################
        if((ant == pilha[t-1][1] and prox != pilha[0][1]) or (ant != pilha[0][1] and prox == pilha[t-1][1])): #adjacente a St mas nao a S1   
            print "Entrei no caso A" , "no vertice ",verts[i][0]
            if(lado[pilha[t-1][1]] == True):   
                while(t>1 and left_on(pilha[t-1][0],pilha[t-2][0],verts[i][0]) ):                
                    pilha.pop()
                    t -= 1
                    diagonais.append(Segment(verts[i][0],pilha[t-1][0]))
                    d = Segment(verts[i][0],pilha[t-1][0])
                    d.hilight("blue")
                    control.sleep()
                    print "Adicionei a diagonal ", d
            elif(t>1):
                while(t>1 and right_on(pilha[t-1][0],pilha[t-2][0],verts[i][0])):
                    
                    pilha.pop()
                    t -= 1
                    diagonais.append(Segment(verts[i][0],pilha[t-1][0]))
                    d = Segment(verts[i][0],pilha[t-1][0])
                    d.hilight("blue")
                    control.sleep()
                    print "Adicionei a diagonal ", d
                    
            pilha.append(verts[i])

   #Caso B ########################
        if((ant != pilha[t-1][1] and prox == pilha[0][1]) or (ant == pilha[0][1] and prox != pilha[t-1][1])): #adjacente a S1 mas nao a St
            print "Entrei no caso B"  , "no vertice ",verts[i][0]
            aux = pilha[t-1]
            while(t>1):
                diagonais.append(Segment(verts[i][0],pilha[t-1][0]))
                d = Segment(verts[i][0],pilha[t-1][0])
                d.hilight("blue")
                control.sleep()
                print "Adicionei a diagonal ", d
                pilha.pop()
                t -= 1
            pilha.pop()
            pilha.append(aux)
            pilha.append(verts[i])
   #Caso C ########################
        if((ant == pilha[t-1][1] and prox == pilha[0][1]) or (ant == pilha[0][1] and prox == pilha[t-1][1])): #adjacente a St e S1
            print "Entrei no caso C", "no vertice ",verts[i][0]
            pilha.pop()
            while(t>2):
                t -= 1
                diagonais.append(Segment(verts[i][0],pilha[t-1][0]))
                d = Segment(verts[i][0],pilha[t-1][0])
                d.hilight("blue")
                control.sleep()
                print "Adicionei a diagonal ", d
                pilha.pop()
        verts[i][0].hilight("red")
        print "--------------------"

    return diagonais
Beispiel #30
0
def verticesVisiveis(p, poligs):
    pontos = []
    for i in range(len(poligs)):
        pontos.extend(poligs[i].to_list())
    compara = criaCompara(p)

    #Intersecta p.x -> inf+
    T = Tree()

    pontos.sort(key=cmp_to_key(compara), reverse=True)
    for i in range(len(poligs)):
        listaPs = poligs[i].to_list()
        n = len(listaPs)
        for j in range(n):
            a = listaPs[j]
            b = listaPs[(j + 1) % n]
            if (passaEixoX(a, b, p)):
                if (left_on(p, b, a)): T.insert(Segment(a, b))
                else: T.insert(Segment(b, a))

    W = []
    for i in range(len(pontos)):
        a = pontos[i]

        idBranco = p.lineto(a, 'white')
        a.hilight('yellow')
        control.sleep()
        a.hilight('red')
        a.unhilight()

        if (visivel(T, pontos, p, i)):
            if (a is not p):
                W.append(a)
                p.remove_lineto(a, idBranco)
                p.lineto(a, 'blue')
            else:
                continue
        else:
            p.remove_lineto(a, idBranco)

        b = a.prev
        c = a.next

        if (a.x == b.x and a.y == b.y): continue  #a não está em um
        #polígono
        if (left_on(p, a, b)):
            T.delete(Segment(b, a))

        if (left_on(p, a, c)):
            T.delete(Segment(c, a))

        else:
            T.insert(Segment(a, c))

        #else do primeiro if
        #Tentando evitar q na hora da inserção tenha segmentos terminando
        #na linha de varredura.
        if (right(p, a, b)):
            T.insert(Segment(a, b))

    return W
Beispiel #31
0
def triangulaMonotono(l):#Os pontos devem vir em ordem anti-horária
    pontos = [] #lista com os pontos,juntamente com seus indices
    verticesOrdenados = [] #lista com os pontos ordenados
    pilha = [] #pilha usada no algoritmo
    diagonais = [] #lista de diagonais da triangulação
    lado = []

    for x in range(len(l)):#desenha poligono
        if(x != len(l)-1): l[x].lineto(l[(x+1)],'red')
        else: l[x].lineto(l[0],'red')
                                        
    N = len(l)

    for i in range(N): 
        pontos.append((l[i],i)) #transforma cada ponto numa dupla (ponto,indice)
        lado.append(True)

#####################################

    verticesDCEL = []
    arestas = []
    arestas2 = []

    for a in range(N):
        if(a != N-1):
            ar = Aresta()
            ar.setAresta(Segment(pontos[a],pontos[a+1]))

            ar2 = Aresta()
            ar2.setAresta(Segment(pontos[a+1],pontos[a]))

            ar.setGemeo(ar2)
            ar2.setGemeo(ar)

            arestas.append(ar)
            arestas2.append(ar2)
            
        else:
            ar = Aresta()
            ar.setAresta(Segment(pontos[a],pontos[0]))

            ar2 = Aresta()
            ar2.setAresta(Segment(pontos[0],pontos[a]))

            ar.setGemeo(ar2)
            ar2.setGemeo(ar)

            arestas.append(ar)
            arestas2.append(ar2)

    for k in range(len(arestas)):
        if(k!= 0 and k!= len(arestas)-1):
            arestas[k].setProx(arestas[k+1])
            arestas[k].setAnt(arestas[k-1])

            arestas2[k].setProx(arestas2[k-1])
            arestas2[k].setAnt(arestas2[k+1])
        elif(k == 0):
            arestas[k].setProx(arestas[k+1])
            arestas[k].setAnt(arestas[len(arestas)-1])

            arestas2[k].setProx(arestas2[len(arestas)-1])
            arestas2[k].setAnt(arestas2[k+1])
        else:
            arestas[k].setProx(arestas[0])
            arestas[k].setAnt(arestas[k-1])

            arestas2[k].setProx(arestas2[k-1])
            arestas2[k].setAnt(arestas2[0])

    for a in range(N):
        bla = Vertice(aresta=arestas2[a])
        verticesDCEL.append(bla)          


    face = Face(arestas2[0])
    faces = []

    faces.append(face)



######################################
    verticesOrdenados = merge(pontos,lado)
######################################
    
    pilha.append(verticesOrdenados[0])
    pilha.append(verticesOrdenados[1])

    for i in range(2,N):
        t = len(pilha)
        verticesOrdenados[i][0].hilight("yellow")
        control.sleep()
        if(verticesOrdenados[i][1] == 0): ant = len(l)-1
        else: ant = verticesOrdenados[i][1]-1

        if(verticesOrdenados[i][1] == len(l)-1): prox = 0
        else: prox = verticesOrdenados[i][1]+1

        #aqui pilha[t-1][1] é o St e pilha[0][1] o S1, de acordo com os slides

   #Caso A ########################
        if((ant == pilha[t-1][1] and prox != pilha[0][1]) or (ant != pilha[0][1] and prox == pilha[t-1][1])): #adjacente a St mas nao a S1   
            if(lado[pilha[t-1][1]] == True):   
                while(t>1 and left_on(pilha[t-1][0],pilha[t-2][0],verticesOrdenados[i][0]) and not (pilha[t-1][0].y == pilha[t-2][0].y and verticesOrdenados[i][0].y == pilha[t-1][0].y )):                    
                    pilha.pop()
                    t -= 1
                    d = Segment(verticesOrdenados[i][0],pilha[t-1][0])
                    d.hilight("green")
                    control.sleep()
                    diagonalASerInserida = criaAresta(verticesOrdenados[i],pilha[t-1])
                    diagonais.append(diagonalASerInserida)
                    insere(verticesDCEL[verticesOrdenados[i][1]-1],verticesDCEL[pilha[t-1][1]-1],diagonalASerInserida,faces)
            elif(t>1):
                while(t>1 and right_on(pilha[t-1][0],pilha[t-2][0],verticesOrdenados[i][0])  and not (pilha[t-1][0].y == pilha[t-2][0].y and verticesOrdenados[i][0].y == pilha[t-1][0].y )):
                    pilha.pop()
                    t -= 1
                    d = Segment(verticesOrdenados[i][0],pilha[t-1][0])
                    d.hilight("green")
                    control.sleep()
                    diagonalASerInserida = criaAresta(verticesOrdenados[i],pilha[t-1])
                    diagonais.append(diagonalASerInserida)
                    insere(verticesDCEL[verticesOrdenados[i][1]-1],verticesDCEL[pilha[t-1][1]-1],diagonalASerInserida,faces)

                    
            pilha.append(verticesOrdenados[i])

   #Caso B ########################
        if((ant != pilha[t-1][1] and prox == pilha[0][1]) or (ant == pilha[0][1] and prox != pilha[t-1][1])): #adjacente a S1 mas nao a St
            aux = pilha[t-1]
            while(t>1):
                d = Segment(verticesOrdenados[i][0],pilha[t-1][0])
                d.hilight("green")
                control.sleep()
                diagonalASerInserida = criaAresta(verticesOrdenados[i],pilha[t-1])
                diagonais.append(diagonalASerInserida)
                insere(verticesDCEL[verticesOrdenados[i][1]-1],verticesDCEL[pilha[t-1][1]-1],diagonalASerInserida,faces)
                pilha.pop()
                t -= 1
            pilha.pop()
            pilha.append(aux)
            pilha.append(verticesOrdenados[i])
   #Caso C ########################
        if((ant == pilha[t-1][1] and prox == pilha[0][1]) or (ant == pilha[0][1] and prox == pilha[t-1][1])): #adjacente a St e S1
            pilha.pop()
            while(t>2):
                t -= 1
                d = Segment(verticesOrdenados[i][0],pilha[t-1][0])
                d.hilight("green")
                control.sleep()
                diagonalASerInserida = criaAresta(verticesOrdenados[i],pilha[t-1])
                diagonais.append(diagonalASerInserida)
                insere(verticesDCEL[verticesOrdenados[i][1]-1],verticesDCEL[pilha[t-1][1]-1],diagonalASerInserida,faces)
                pilha.pop()
        verticesOrdenados[i][0].hilight("red")
        
    for d in diagonais:
        checaDiagonal(verticesDCEL[d.getAresta().init[1] -1 ],verticesDCEL[d.getAresta().to[1] -1 ],d)
Beispiel #32
0
class Node_Triang:
    " Classe que será o nó do DAG, guarda os triângulos que fazem parte da triangulação "

    def __init__(self, p1, p2, p3, a):
        if left(p1, p2, p3):
            self.p1 = p1
            self.p2 = p2
        else:
            self.p1 = p2
            self.p2 = p1
        self.p3 = p3
        self.a = a  # Alguma aresta da DCEL que faz parte desse triangulo
        self.filhos = []  # Node_Triangs que são filhos do self no DAG
        # arestas
        self.a1 = Segment(self.p1, self.p2)
        self.a2 = Segment(self.p2, self.p3)
        self.a3 = Segment(self.p3, self.p1)

    def draw(self):
        self.a1.plot("gray")
        self.a2.plot("gray")
        self.a3.plot("gray")
        sleep()

    def hide(self):
        self.a1.hide()
        self.a2.hide()
        self.a3.hide()

    def busca(self, ponto):
        " Retorna o nó folha em que o ponto está "
        if desenha_busca: self.draw()
        for f in self.filhos:
            if (left_on(f.p1, f.p2, ponto) and left_on(f.p2, f.p3, ponto)
                    and left_on(f.p3, f.p1, ponto)):
                if desenha_busca: self.hide()
                return f.busca(ponto)
        if desenha_busca: self.hide()
        return self
Beispiel #33
0
def triangulaMonotono(l):#Os pontos devem vir em ordem anti-horária
    pontos = [] #lista com os pontos,juntamente com seus indices
    verticesOrdenados = [] #lista com os pontos ordenados
    pilha = [] #pilha usada no algoritmo
    #diagonais = [] #lista de diagonais da triangulação
    lado = []

    for x in range(len(l)):#desenha poligono
        if(x != len(l)-1): l[x].lineto(l[(x+1)],'red')
        else: l[x].lineto(l[0],'red')
                                        
    N = len(l)

    for i in range(N): 
        pontos.append((l[i],i)) #transforma cada ponto numa dupla (ponto,indice)
        lado.append(True)
    
    ########################################### 
    verticesOrdenados = merge(pontos,lado)
    ########################################

    pilha.append(verticesOrdenados[0])
    pilha.append(verticesOrdenados[1])

    for i in range(2,N):
        t = len(pilha)
        verticesOrdenados[i][0].hilight("yellow")
        control.sleep()
        if(verticesOrdenados[i][1] == 0): ant = len(l)-1
        else: ant = verticesOrdenados[i][1]-1

        if(verticesOrdenados[i][1] == len(l)-1): prox = 0
        else: prox = verticesOrdenados[i][1]+1

        #aqui pilha[t-1][1] é o St e pilha[0][1] o S1, de acordo com os slides

   #Caso A ########################
        if((ant == pilha[t-1][1] and prox != pilha[0][1]) or (ant != pilha[0][1] and prox == pilha[t-1][1])): #adjacente a St mas nao a S1   
            if(lado[pilha[t-1][1]] == True):   
                while(t>1 and left_on(pilha[t-1][0],pilha[t-2][0],verticesOrdenados[i][0]) and not (pilha[t-1][0].y == pilha[t-2][0].y and verticesOrdenados[i][0].y == pilha[t-1][0].y )):                    
                    pilha.pop()
                    t -= 1
                    d = Segment(verticesOrdenados[i][0],pilha[t-1][0])
                    d.hilight("blue")
                    control.sleep()
            elif(t>1):
                while(t>1 and right_on(pilha[t-1][0],pilha[t-2][0],verticesOrdenados[i][0])  and not (pilha[t-1][0].y == pilha[t-2][0].y and verticesOrdenados[i][0].y == pilha[t-1][0].y )):
                    pilha.pop()
                    t -= 1
                    d = Segment(verticesOrdenados[i][0],pilha[t-1][0])
                    d.hilight("blue")
                    control.sleep()

                    
            pilha.append(verticesOrdenados[i])

   #Caso B ########################
        if((ant != pilha[t-1][1] and prox == pilha[0][1]) or (ant == pilha[0][1] and prox != pilha[t-1][1])): #adjacente a S1 mas nao a St
            aux = pilha[t-1]
            while(t>1):
                d = Segment(verticesOrdenados[i][0],pilha[t-1][0])
                d.hilight("blue")
                control.sleep()
                pilha.pop()
                t -= 1
            pilha.pop()
            pilha.append(aux)
            pilha.append(verticesOrdenados[i])
   #Caso C ########################
        if((ant == pilha[t-1][1] and prox == pilha[0][1]) or (ant == pilha[0][1] and prox == pilha[t-1][1])): #adjacente a St e S1
            pilha.pop()
            while(t>2):
                t -= 1
                d = Segment(verticesOrdenados[i][0],pilha[t-1][0])
                d.hilight("blue")
                control.sleep()
                pilha.pop()
        verticesOrdenados[i][0].hilight("red")