Beispiel #1
0
def is_diagonal(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('green')
    sleep()

    # Como o dentroDoPoligono é O(1) é muito prudente fazer esse teste primeiro
    result = dentro_do_poligono(u, w, P) and (not intersecta_borda(u, w, P))
    uw.hide()
    return result
Beispiel #2
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 par_min "
    d = math.sqrt(dist(par_min))

    # desenha a faixa que eu estou procurando
    v1 = desenhos.plot_vert_line(meio.x - d, 'orange', grossura=1)
    v2 = desenhos.plot_vert_line(meio.x + d, 'orange', grossura=1)

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

    for k in range(len(cand)):
        cand[k].plot('red')
        desenhos.sleep()
        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('red')
            desenhos.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 is not None:
                    par_inter.unhilight()
                par_min.unhilight()
                par_inter = cand_inter
                par_inter.hilight('orange')
                desenhos.sleep()

        cand[k].unplot()

    desenhos.plot_delete(v1)
    desenhos.plot_delete(v2)
    desenhos.sleep()

    return par_inter
Beispiel #3
0
def dentro_do_poligono(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('red')
        sleep()
        uw.hide()

    return resposta
Beispiel #4
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 #5
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()
            if l[p_min] in par_min.endpoints():
                l[p_min].hilight('orange')
            no_p_min = Node_point(l[p_min])
            faixa.deleta(no_p_min)
            p_min += 1

        # Desenha o quadradinho de candidatos
        linha_frente = desenhos.plot_vert_line(p.x, 'orange')
        if i > 1:
            linha_tras = desenhos.plot_vert_line(p.x - d, cor='firebrick')
            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('firebrick')
            linha_baixo.plot('firebrick')
        desenhos.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:
            d2 = dist2(p, vizinho.p)
            p.hilight()
            vizinho.p.hilight('firebrick')
            if d2 < d * d:
                d = d2**0.5

                if par_min is not None:
                    par_min.unhilight()
                par_min = Segment(p, vizinho.p)
                par_min.hilight('orange')
                desenhos.sleep()

            vizinho = faixa.sucessor(vizinho)
        # Depois com os vizinhos de baixo
        vizinho = faixa.predecessor(no_p)
        while vizinho is not None and p.y - vizinho.p.y < d:
            d2 = dist2(p, vizinho.p)
            p.hilight()
            vizinho.p.hilight('firebrick')
            if d2 < d * d:
                d = d2**0.5

                if par_min is not None:
                    par_min.unhilight()
                par_min = Segment(p, vizinho.p)
                par_min.hilight('orange')
                desenhos.sleep()

            vizinho = faixa.predecessor(vizinho)

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

        p.unhilight()
        l[i].hilight('firebrick')

    "despinta quem sobrou na faixa"
    while (not faixa.vazia()):
        faixa.deleta_min().p.unhilight()
    par_min.hilight('orange')