Ejemplo n.º 1
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
Ejemplo n.º 2
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)
Ejemplo n.º 3
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
Ejemplo n.º 4
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")
Ejemplo n.º 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()
            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")