def distancia_rec_sh(pts, l, r, best):
    '''
    pts: array de pontos
    l: limite esquerdo da recursão
    r: limite direito da recursão
    best: melhores pontos encontrados
    '''

    # força bruta / base da recursão
    if r-l <= 3:
        for i in range(l, r):
            for j in range(i+1, r):
                update(pts[i], pts[j], best)
        pts[l:r] = sorted(pts[l:r], key=cmp_to_key(compare_y))
        return
    
    m = int((l+r)/2)
    m_point = pts[m]
    m_line = control.plot_vert_line(m_point[0], color='red')
    
    # divisão
    distancia_rec_sh(pts, l, m, best)
    distancia_rec_sh(pts, m, r, best)
    intercala(pts, l, m, r)
    
    # conquista
    control.plot_delete(m_line)
    m_line = control.plot_vert_line(m_point[0], color='yellow')
    combine(pts, l, r, m_point, best)
    control.plot_delete(m_line)
Exemple #2
0
def Bent_ott(segments):
    '''
    Rotina principal de execução do algoritmo de Bentley and Ottmman.
    '''
    # Ordenando os pontos do segmento
    for s in segments:
        if s[0] > s[1]:
            s.to, s.init = s.init, s.to
        s.plot()

    bag = EventBag(segments)
    sweep_line = SweepLine(bag)
    line = None
    while not bag.event_bag.is_empty():
        p, e_tuple = bag.next_events()
        # Andando com a linha de varredura
        if line: control.plot_delete(line)
        sweep_line.current_x = p[0]
        line = control.plot_vert_line(p[0], color='yellow')
        control.sleep()
        # Processando cada tupla de eventos do mesmo tipo
        for t in [END, INTERSECTION, START, VERTICAL]:
            for e in e_tuple[t]:
                sweep_line.process_event(e)

    intersections = sweep_line.get_intersections()
    print("Numero de interseções: " + str(len(intersections)))
Exemple #3
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
Exemple #4
0
 def draw_interval(should_plot=True):
     control.thaw_update()
     for i in range(2):
         if not ids[i] == None:
             control.plot_delete(ids[i])
         if T[i] != -inf and T[i] != +inf and should_plot:
             ids[i] = control.plot_vert_line(T[i], 'yellow')
     control.sleep()
     control.freeze_update()
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 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 #7
0
def Bentley_Ottmann (l):
    
    L = Abbb () # Linha de varredura
    resp = [] # Os nós com os pontos de interseção que retornaremos
    
    # Pré-processamento - Transforma cada circulo em pontos-eventos
    # pontos é a ABBB de pontos eventos
    pontos = eventos (l)
    control.sleep()
    
    while not pontos.vazia():
        p = pontos.deleta_min()
        # desenha a linha
        id_linha = control.plot_vert_line (p.ponto.x)
        id_evento = p.ponto.hilight()
        control.sleep()
        
        "------------------------- Pontos da esquerda --------------------------------"
        for seg in p.ini:
            seg.seg.plot ("green")
            control.sleep()
            insere_na_linha (L, seg, pontos, p.ponto.x)
         
        "------------------------- Pontos de interseção ------------------------------"
        if len (p.inter) > 0 or (len (p.ini) + len (p.fim) > 1):
            p.ponto.hilight('yellow')
            resp.append (p)
            
        # Troca a ordem dos segmentos (do p.inter[])
        trocados = []
        # Remove todos
        for seg in p.inter:
            seg.ref = Point (p.ponto.x - 10*eps, ((seg.seg.to.x*seg.seg.init.y) -
                                                 (seg.seg.init.x*seg.seg.to.y) -
                                                 (p.ponto.x - 10*eps)*(seg.seg.init.y - seg.seg.to.y)) / 
                                                 (seg.seg.to.x - seg.seg.init.x))
            trocados.append (seg)
            L.deleta (seg)
        # Insere denovo com o novo ponto de referencia
        for seg in trocados:
            seg.ref = p.ponto
            #print("reinserindo " + str(seg))
            insere_na_linha (L, seg, pontos, p.ponto.x, trocados)
        
        "------------------------- Pontos da direita --------------------------------"
        for seg in p.fim:
            deleta_da_linha (L, seg, pontos, p.ponto.x)
            
        # apaga a linha
        control.plot_delete (id_linha)    
        control.plot_delete (id_evento)
        p.ponto.unplot()

    return resp
Exemple #8
0
def sweep_line(input_segments):
    bst = BinarySearchTree()
    event_queue = EventQueue(input_segments)

    for event_point in event_queue:
        sweep_line_id = control.plot_vert_line(
            event_point.segment.init.x
            if event_point.is_left else event_point.segment.to.x,
            color="cyan")
        bst.reset_above_below_state()

        if event_point.is_left:
            event_point.segment.hilight(color_line="blue", color_point="blue")
            control.sleep()
            bst.insert(event_point.segment)
            bst.find_above_below(event_point.segment)
            intersect_above = event_point.segment.intersects(
                bst.above.data) if bst.above is not None else False
            intersect_below = event_point.segment.intersects(
                bst.below.data) if bst.below is not None else False

            if (intersect_above or intersect_below):
                event_point.segment.hilight(color_line="yellow",
                                            color_point="yellow")

                if intersect_above:
                    bst.above.data.hilight(color_line="yellow",
                                           color_point="yellow")
                elif intersect_below:
                    bst.below.data.hilight(color_line="yellow",
                                           color_point="yellow")

                return True
        elif not event_point.is_left:
            control.sleep()
            bst.find_above_below(event_point.segment)
            intersect_above_below = bst.below.data.intersects(
                bst.above.data) if (bst.below is not None
                                    and bst.above is not None) else False

            if intersect_above_below:
                bst.above.data.hilight(color_line="yellow",
                                       color_point="yellow")
                bst.below.data.hilight(color_line="yellow",
                                       color_point="yellow")

                return True

            event_point.segment.unhilight()
            bst.delete(event_point.segment)

        control.plot_delete(sweep_line_id)
    return False
Exemple #9
0
def Bentley_Ottmann_Mod (l):
    
    L = Abbb () # Linha de varredura
    resp = [] # Os nós com os pontos de interseção que retornaremos
    
    # Pré-processamento - Transforma cada circulo em pontos-eventos
    # pontos é a ABBB de pontos eventos
    pontos = eventos (l)
    control.sleep()
    
    while not pontos.vazia():
        p = pontos.deleta_min()
        
        # desenha a linha
        id_linha = control.plot_vert_line (p.ponto.x)
        id_evento = p.ponto.hilight()
        control.sleep()
        
        "------------------------- Pontos da esquerda --------------------------------"
        for arco in p.ini:
            insere_na_linha (L, arco, pontos)
            
        "------------------------- Pontos de interseção ------------------------------"
        if len (p.inter) > 0 or len (p.inter_unico) > 0:
            p.ponto.hilight('yellow')
            resp.append (p)
            
        # Troca a ordem dos arcos (do p.inter[])
        # (Não troco a ordem do p.inter_unico[] porque os circulos não se "penetram")
        trocados = []
        # Remove todos
        for arco in p.inter:
            trocados.append (arco)
            L.deleta (trocados[-1])
    
        # Insere denovo com o novo ponto de referencia
        for arco in trocados:
            arco.ref = p.ponto
            insere_na_linha (L, arco, pontos, p.ponto.x, trocados)
        
        "------------------------- Pontos da direita --------------------------------"
        for arco in p.fim:
            deleta_da_linha (L, arco, pontos, p.ponto.x)
            
        # apaga a linha
        control.plot_delete (id_linha)    
        control.plot_delete (id_evento)
        p.ponto.unplot()
    
    return resp
Exemple #10
0
 def build_animation_lines(self):
     '''
     controi as linhas imaginarias que dividem o plano em quadrados
     '''
     delta = self.delta / 2.0
     for il in self.id_lines:
         control.plot_delete(il)
     self.id_lines.clear()
     r = self.bl[1]
     c = self.bl[0]
     while r < self.ur[1]:
         self.id_lines.append(control.plot_horiz_line(r, color='blue'))
         r += delta
     while c < self.ur[0]:
         self.id_lines.append(control.plot_vert_line(c, color='blue'))
         c += delta
     control.sleep()
Exemple #11
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
Exemple #12
0
def treat_event(event, queue, sweep_line):
    v = control.plot_vert_line(event.point.x, 'blue', 2)
    p = event.point.hilight('cyan')

    for s in event.right:
        s.hilight('yellow', None)
        control.sleep()
        treat_right(event, queue, sweep_line, s)
        s.unhilight()
    for s in event.left:
        s.hilight('yellow', None)
        control.sleep()
        treat_left(event, queue, sweep_line, s)
        s.unhilight()
    if (not event.middle.is_empty()): treat_middle(event, queue, sweep_line)
    if (event.lines > 1):
        event.print_lines()
    control.sleep()
    control.plot_delete(v)
    event.point.unhilight(p)
Exemple #13
0
def plot_vertical_lines(pm, dmin):
    vl1 = control.plot_vert_line(pm.x, "orange", 2)
    vl2 = control.plot_vert_line(pm.x - dmin, "orange", 2)
    vl3 = control.plot_vert_line(pm.x + dmin, "orange", 2)
    return vl1, vl2, vl3
Exemple #14
0
def treat_event(p, Q, T):
    ''' Recebe o ponto evento e o trata conforme seu tipo: extremo esquerdo,
    extremo direito e ponto de intersecção. 
    '''
    event = p[1]
    point = p[0]

    print(event, end="\n\n")
    print("ANTES")
    # print(dic)
    for seg in T:
        print(f"key: {T.key(seg)}, value: {seg}")

    linea = 0
    point.hilight("green")
    if event.t == "left":
        s = event.s
        T.add((s, s))
        linea = control.plot_vert_line(s.lower.x, "cyan")
        control.sleep()
        control.update()
        try:
            prev_index = T.bisect_left((s, s))
            prev_index -= 1
            if prev_index >= 0:
                pred = T[prev_index][1]
                print("PRED: ", pred)
                if s.intersects(pred):
                    print("INTERSECTA!!!!")
                    verify_new_event(point, Q, s, pred)
        except IndexError:
            pass
        try:
            next_index = T.bisect_right(s)
            if next_index <= len(T):
                succ = T[next_index][1]
                print("SUCC: ", succ)
                if s.intersects(succ):
                    verify_new_event(point, Q, s, succ)
        except IndexError:
            pass

    if event.t == "right":
        s = dic[event.s]
        segmnt = s[1]
        linea = control.plot_vert_line(segmnt.upper.x, "cyan")
        control.sleep()
        control.update()
        try:
            print(s)
            prev_index = T.bisect_left(s)
            next_index = T.bisect_right(s)
            prev_index -= 1
            if prev_index >= 0 and next_index <= len(T):
                pred = T[prev_index][1]
                succ = T[next_index][1]
                print("PRED: ", pred)
                print("SUCC: ", succ)
                T.pop(T.index(s))
                if pred.intersects(succ):
                    verify_new_event(point, Q, succ, pred)
        except IndexError:
            T.pop(T.index(s))

    if event.t == "inter":
        s1 = event.s1
        s2 = event.s2
        if right(s2.lower, s2.upper, s1.lower):
            s1, s2 = s2, s1
        rs1 = dic[s1]
        rs2 = dic[s2]

        intersection = intersection_point(s1, s2)
        intersections.append(intersection)
        intersections[len(intersections) - 1].hilight("yellow")
        print(len(intersections))
        linea = control.plot_vert_line(intersection.x, "cyan")
        control.sleep()
        control.update()
        try:
            prev_index = T.bisect_left(rs1)
            prev_index -= 1
            if prev_index < 0:
                pred = None
            if rs1 == T[prev_index]:
                prev_index -= 1
            elif prev_index >= 0:
                pred = T[prev_index][1]
                print("PRED: ", pred)
        except IndexError:
            pred = None
        try:
            next_index = T.bisect_right(rs2)
            if next_index >= len(T):
                succ = None
            if rs2 == T[next_index]:
                next_index += 1
            elif next_index < len(T):
                succ = T[next_index][1]
                print("SUCC: ", succ)
        except IndexError:
            succ = None
        print("s1: ", s1, " rs1: ", rs1)
        print("s2: ", s2, " rs2: ", rs2, "\n")
        T.pop(T.index(rs1))
        T.pop(T.index(rs2))
        # Insere ao contrário
        new_s1 = segment.Segment(intersection, s1.upper)
        new_s2 = segment.Segment(intersection, s2.upper)
        print(f"new_s1: {new_s1}, new_s2:{new_s2}")
        T.add((new_s2, s2))
        T.add((new_s1, s1))
        dic[s1] = (new_s1, s1)
        dic[s2] = (new_s2, s2)

        if pred != None and pred.intersects(s2):
            verify_new_event(point, Q, pred, s2, intersection)
        if succ != None and s1.intersects(succ):
            verify_new_event(point, Q, s1, succ, intersection)

    control.plot_delete(linea)
    control.sleep()
    control.update()
    point.unhilight()

    print("DEPOIS")
    for seg in T:
        print("key: ", str(seg))
    print("")
Exemple #15
0
def Bentley_ottman (segments_list):
    points_list = filter_points(segments_list)
    intersection_points = []
    event_queue = PBST.PointBST()  
    segment_tree = SBST.SegmentBST()
    sweepline_id = None
    
    for s in segments_list:
        s.plot()

    insert_point_segment(event_queue, points_list, segments_list)

    while(not event_queue.isEmpty()):
        event_node = event_queue.removeMinKey()
        control.plot_delete(sweepline_id)
        sweepline_id = control.plot_vert_line(event_node.key.x, color='blue')
        print("~~~O ponto evento é: (" + str(event_node.key.x) + ", " +  str(event_node.key.y) + ")")
        print("Sua lista de inserções é: ")
        print(event_node.segment[0])
        print("Sua lista de interseções é: ")
        event_node.segment[1].imprime()
        print("Sua lista de remoções é: ")
        print(event_node.segment[2])

        if (len(event_node.segment[0]) + event_node.segment[1].size() + len(event_node.segment[2]) > 1):
            print("Entrei no primeiro if")
            segment_tree.imprime()

            intersection_points.append(event_node.key)
            for segment in event_node.segment[0]:
                segment.hilight(color_line="yellow")
            event_node.segment[1].plot_segments("yellow")
            for segment in event_node.segment[2]:
                segment.hilight(color_line="yellow") 
            
            event_node.segment[1].remove_from_sweepline(segment_tree, event_node.key)
            for segment in event_node.segment[2]:
                segment_tree.remove(segment, event_node.key)
            
            for segment in event_node.segment[0]:
                segment_tree.insert(segment, event_node.key)
            event_node.segment[1].insert_in_sweepline(segment_tree, event_node.key)
            
            
            segment_tree.imprime()

            control.sleep()
            for segment in event_node.segment[0]:
                segment.plot()
            event_node.segment[1].plot_segments("red")
            for segment in event_node.segment[2]:
                segment.plot() 

        if (len(event_node.segment[0]) + event_node.segment[1].size() == 0):
            print("Entrei no segundo if")
            lower = event_node.segment[2][0]
            upper = event_node.segment[2][len(event_node.segment[2]) - 1]
            if(lower):
                print("O lower é: ")
                print(lower)
                print("O upper é: ")
                print(upper)
                lower.hilight(color_line="green")
                upper.hilight(color_line="green")
                control.sleep()
                print("Vou imprimir a SegmentBST: ")
                segment_tree.imprime()
                pred = segment_tree.get_predecessor(lower, event_node.key)
                succ = segment_tree.get_sucessor(upper, event_node.key)
                if (pred and succ):
                    pred.key.hilight(color_line="magenta")
                    succ.key.hilight(color_line="magenta")
                    find_new_event(pred.key, succ.key, event_node.key, event_queue)

                control.sleep()
                if(succ): succ.key.plot()
                if(pred): pred.key.plot()
                lower.plot()
                upper.plot()
            for segment in event_node.segment[2]:
                segment_tree.remove(segment, event_node.key)
        else:
            print("Entrei no else")
            if (len(event_node.segment[0]) == 1 and len(event_node.segment[0]) + event_node.segment[1].size() + len(event_node.segment[2]) <= 1):
                print("Tenho um segmento para inserir")
                segment_tree.insert(event_node.segment[0][0], event_node.key)
            print("Vou imprimir a SegmentBST: ")
            segment_tree.imprime()

            lower = get_lower_segment(event_node.segment[0], event_node.segment[1])
            print("O lower é: ")
            print(lower)
            lower.hilight(color_line="green")
            pred = segment_tree.get_predecessor(lower, event_node.key)
            if (pred):
                pred.key.hilight(color_line="magenta")
                find_new_event(pred.key, lower, event_node.key, event_queue)
            
            control.sleep()
            if(pred): pred.key.plot() 
            lower.plot()

            upper = get_upper_segment(event_node.segment[0], event_node.segment[1])
            print("O upper é: ")
            print(upper)
            upper.hilight(color_line="green")
            succ = segment_tree.get_sucessor(upper, event_node.key)
            if (succ):
                succ.key.hilight(color_line="magenta")
                find_new_event(upper, succ.key, event_node.key, event_queue)
            
            control.sleep()
            if(succ): succ.key.plot()
            upper.plot()
            
            for segment in event_node.segment[2]:
                segment_tree.remove(segment, event_node.key)

    for point in intersection_points:
        point.plot("yellow")
Exemple #16
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")