Esempio n. 1
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)))
Esempio n. 2
0
def monotonos (d, P, diags):
    """ Função que recebe um polígono P e particiona P em vários polígonos monótonos
        Através da inserção de diagonais
        Coloca as diagonais na DCEL d
    """
    # Ordena os vértices pela Y-coordenada
    v = P.vertices()
    v = sorted(v, key = lambda x:(-x.y))
    
    L = Abbb()
    
    # os vértices são os pontos eventos da linha de varredura
    for p in v:
        p.hilight()
        h = control.plot_horiz_line (p.y)
        control.sleep()
        
        viz_cima = p.next
        viz_baixo = p.prev
        if viz_cima.y < viz_baixo.y:
            viz_cima, viz_baixo = viz_baixo, viz_cima
        
        if viz_cima.y > p.y and p.y > viz_baixo.y:
            trata_caso_meio (p, viz_baixo, L, d, diags)
        elif viz_cima.y < p.y:
            trata_ponta_pra_cima (p, L, d, diags)
        else:
            trata_ponta_pra_baixo (p, L, d, diags) 
        
        control.plot_delete (h)
        p.unhilight()
Esempio n. 3
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
Esempio n. 4
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
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)
Esempio n. 6
0
def recursive_ham_sandwich(G1, G2, p1, p2, T):
    if len(G1) < len(G2):
        return recursive_ham_sandwich(G2, G1, p2, p1, T)
    T, is_base = new_interval(G1, G2, p1, p2, T)

    if is_base:
        valid_answers = []
        for g in G1:
            for h in G2:
                p = g.intersect(h)
                if p and isinstance(p.dual(), Line):
                    valid_answers.append(p.dual())
        return valid_answers, G1 + G2

    t = new_trapezoid(G1, p1, T)
    t_ids = []
    control.freeze_update()
    for i in range(4):
        j = (i + 1) % 4
        t_ids.append(
            control.plot_segment(t[i].x, t[i].y, t[j].x, t[j].y, 'yellow'))
    control.sleep()
    control.thaw_update()

    G1, p1 = discard_lines(G1, p1, t)
    G2, p2 = discard_lines(G2, p2, t)

    for id in t_ids:
        control.plot_delete(id)

    return recursive_ham_sandwich(G1, G2, p1, p2, T)
Esempio n. 7
0
    def process_intersection(self, a, b):
        '''
        Usada para processar a interseção entre dois eventos. 
        '''
        if a == None or b == None or a == b: return
        if a.type == INTERSECTION or b.type == INTERSECTION: return

        a_line = a.segment.plot(cor='blue')
        b_line = b.segment.plot(cor='blue')
        control.sleep()
        control.plot_delete(a_line)
        control.plot_delete(b_line)

        # Ponto de interseção
        p = segment_intersection(a, b)
        if p == None: return
        # Ponto ja foi processado, adiciono possiveis novos segmentos a inter
        if p in self.intersections:
            self.intersections[p].add(a)
            self.intersections[p].add(b)
            return

        p_plot = point.Point(p[0], p[1])
        p_plot.plot('white')

        # Cria conjunto com os segmentos que compõem aquela interseção
        self.intersections[p] = {a, b}
        # Adiciono a interseção na fila de eventos se ela esta a direita
        if p[0] >= self.current_x:
            new_event = Event(INTERSECTION, p, None)
            self.bag.insert(p, new_event)
Esempio n. 8
0
def quickhull_rec(P, p, r, point_p, point_r):
    '''Miolo recursivo da função Quickhull. Recebe uma coleção de pontos P, um
    início p e um fim r dados por meio da função partition. Devolve os hulls
    gerados a cada chamada recursiva.'''
    if p == r - 1:
        return [P[r], P[p]]

    if (point_r, point_p) in points.keys():
        id = points.pop((point_r, point_p))
        control.plot_delete(id)

    if (point_p, point_r) in points.keys():
        id = points.pop((point_p, point_r))
        control.plot_delete(id)

    s, q = partition(P, p, r, point_p, point_r)
    new_q = Point(P[q].x, P[q].y)
    new_r = Point(P[r].x, P[r].y)
    new_s = Point(P[s].x, P[s].y)

    hull = quickhull_rec(P, q, r, new_q, new_r)
    hull2 = quickhull_rec(P, s, q, new_s, new_q)

    # junta os hulls e remove uma cópia do q
    for i in range(1, len(hull2)):
        hull.append(hull2[i])
    return hull
Esempio n. 9
0
    def __triangulate(self):
        self.__stack.append(self.__sortedVertexes[0])
        self.__stack.append(self.__sortedVertexes[1])

        for i in range(2, len(self.__sortedVertexes)):
            adjacentVertexes = self.__getAdjacentVertexes(i)
            currentVertex = self.__sortedVertexes[i]
            suppPointId = currentVertex.coordinates.hilight(color="white")

            stackBase = self.__stackBase()
            stackTop = self.__stackTop()
            neighborFromBase = self.__isVertexNeighborFrom(
                adjacentVertexes, stackBase)
            neighborFromTop = self.__isVertexNeighborFrom(
                adjacentVertexes, stackTop)

            if (neighborFromTop and not neighborFromBase):
                self.__caseA(currentVertex)
            elif (not neighborFromTop and neighborFromBase):
                self.__caseB(currentVertex)
            elif (neighborFromTop and neighborFromBase):
                self.__caseC(currentVertex)

            control.sleep()
            control.plot_delete(suppPointId)
Esempio n. 10
0
    def __partitionatePolygon(self):
        BST = bst.SplayTree()

        for eventVertex in sorted(self.dcel.vertex):
            vertexNumber = eventVertex.vertexNumber()
            previousVertexNumber = self.dcel.iterateVertex(vertexNumber - 1)
            nextVertexNumber = self.dcel.iterateVertex(vertexNumber + 1)

            previousVertex = self.dcel.getVertex(previousVertexNumber)
            nextVertex = self.dcel.getVertex(nextVertexNumber)

            sweepLineId = control.plot_horiz_line(eventVertex.y, color="cyan")
            suppPointId = eventVertex.coordinates.hilight(color="white")
            control.sleep()

            if (previousVertex.y > eventVertex.y and nextVertex.y > eventVertex.y) or\
                    (eventVertex.y == nextVertex.y and nextVertex.x < eventVertex.x and previousVertex.y > eventVertex.y) or\
                    (eventVertex.y == previousVertex.y and previousVertex.x < eventVertex.x and nextVertex.y > eventVertex.y):
                self.__caseThree(BST, eventVertex)
            elif (previousVertex.y < eventVertex.y and nextVertex.y < eventVertex.y) or\
                    (eventVertex.y == nextVertex.y and eventVertex.y > previousVertex.y and eventVertex.x < nextVertex.x) or\
                    (eventVertex.y == previousVertex.y and eventVertex.y > nextVertex.y and eventVertex.x < previousVertex.x):
                self.__caseTwo(BST, previousVertex, eventVertex, nextVertex)
            else:
                self.__caseOne(BST, previousVertex, eventVertex, nextVertex)

            control.plot_delete(sweepLineId)
            control.plot_delete(suppPointId)
Esempio n. 11
0
 def rem_point(self, x, y):
     key = (x, y)
     if key not in self.points.keys():
         return
     if self.points[key][1] == 1:
         control.plot_delete(self.points[key][0])
         self.points[key][0] = None
     self.points[key][1] = self.points[key][1] - 1
Esempio n. 12
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()
Esempio n. 13
0
def delete_stuff(stuff):
    control.freeze_update()
    for s in stuff:
        if isinstance(s, Line):
            control.plot_delete(s.plot_id)
        else:
            s.tk.unplot()
    control.sleep()
    control.thaw_update
Esempio n. 14
0
def unplot_all(par_plots, hedges, sweep):
    for par in par_plots:
        control.plot_delete(par)

    for h in hedges:
        if h.segment.lid is None:
            continue
        h.segment.hide()

    control.plot_delete(sweep)
Esempio n. 15
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
Esempio n. 16
0
    def needs_fix(self, other):
        # inter are the edges self and other have in common
        inter, dif = self.get_relative_vertices(other)
        # check if quad is convex
        if (len(inter) != 2 or len(dif) != 2):
            print("ERRO NA LEGALIZACAO")
            exit(1)
        if self.v1 in inter:
            if self.v2 in inter:
                inter_0 = self.v1
                inter_1 = self.v2
                dif_0 = self.v3
            else:
                inter_0 = self.v3
                inter_1 = self.v1
                dif_0 = self.v2
        else:
            inter_0 = self.v2
            inter_1 = self.v3
            dif_0 = self.v1
        if other.v1 in inter:
            if other.v2 in inter:
                dif_1 = other.v3
            else:
                dif_1 = other.v2
        else:
            dif_1 = other.v1

        if not left(inter_0, inter_1, dif_1):
            aux = dif_0
            dif_0 = dif_1
            dif_1 = aux
        convex = left(inter_0, dif_0, inter_1) and\
                 left(dif_0, inter_1, dif_1) and\
                 left(inter_1, dif_1, inter_0) and\
                 left(dif_1, inter_0, dif_0)

        if not convex: return False
        # check if inter is best
        # only draws if passes convex
        self.draw("#ffaa33")
        other.draw("#ffaa33")
        did = control.plot_segment(inter_0.x, inter_0.y, inter_1.x,\
                                   inter_1.y, color="#ffffff")
        control.sleep()
        control.plot_delete(did)
        self.remove_draw()
        other.remove_draw()

        C = Circle(inter_0, inter_1, dif_0)
        C.draw()
        control.sleep()
        C.remove_draw()
        return C.is_inside(dif_1)
Esempio n. 17
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
Esempio n. 18
0
    def partitionatePoly(self):
        for diagonal in self.diagonalQueue:
            u = self.dcel.originVertex(diagonal[0]).coordinates
            v = self.dcel.endVertex(diagonal[0]).coordinates
            seg = segment.Segment(u, v)
            seg.hilight(color_line="cyan", color_point="cyan")

            if not self.essentialEdge(diagonal[0]):
                self.dcel.removeHalfEdge(diagonal[0])
                control.plot_delete(diagonal[1])

            control.sleep()
            seg.unhilight()
Esempio n. 19
0
    def graham(self):
        if len(self.convexHull) > 0:
            return

        self.__sortPointList()
        self.convexHull = [0, 1, 2]
        hullSegmentIdList = []
        hullSize = len(self.convexHull)

        for hullPointIndex in range(hullSize):
            hullSegmentIdList.append(
                self.__hilightSegment(
                    self.convexHull[hullPointIndex % hullSize],
                    self.convexHull[(hullPointIndex + 1) % hullSize],
                    lineColor="cyan",
                    pointColor="cyan"))

            if hullPointIndex < 2:
                control.sleep()

        for pointIndex in range(3, self.pointListSize):
            pointPlotId = self.pointList[pointIndex].hilight(color="red")
            control.sleep()

            while self.__rightOnWrap(self.convexHull[-2], self.convexHull[-1], pointIndex) and\
                    len(self.convexHull) > 2:
                linePlotId = self.__hilightLine(self.convexHull[-2],
                                                self.convexHull[-1])
                control.sleep()
                self.convexHull.pop()
                self.__unhilightSegment(hullSegmentIdList.pop())
                control.plot_delete(linePlotId)
                control.sleep()

            self.__unhilightSegment(hullSegmentIdList.pop())
            hullSegmentIdList.append(
                self.__hilightSegment(self.convexHull[-1],
                                      pointIndex,
                                      lineColor="cyan",
                                      pointColor="cyan"))
            control.sleep()
            hullSegmentIdList.append(
                self.__hilightSegment(pointIndex,
                                      self.convexHull[0],
                                      lineColor="cyan",
                                      pointColor="cyan"))
            self.convexHull.append(pointIndex)
            control.plot_delete(pointPlotId)

            if pointIndex < self.pointListSize - 1:
                control.sleep()
Esempio n. 20
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
Esempio n. 21
0
    def __caseThree(self, BST, v):
        control.sleep()
        firstTrap = BST.getTrapAndRemove(v)
        x = firstTrap.topSuppVertex

        if self.__interiorDownCusp(x):
            xNumber = x.vertexNumber()
            vNumber = v.vertexNumber()
            diagonal = (xNumber, vNumber)
            self.dcel.addHalfEdge(diagonal)

            self.partitionDiagonalList.append([
                (xNumber, vNumber),
                control.plot_segment(x.x, x.y, v.x, v.y, "yellow")
            ])

        if (firstTrap.leftEdge[1] != v) or (firstTrap.rightEdge[1] != v):
            secondTrap = BST.getTrapAndRemove(v)
            y = secondTrap.topSuppVertex

            if self.__interiorDownCusp(y):
                yNumber = y.vertexNumber()
                vNumber = v.vertexNumber()
                diagonal = (yNumber, vNumber)
                self.dcel.addHalfEdge(diagonal)

                self.partitionDiagonalList.append([
                    (yNumber, vNumber),
                    control.plot_segment(y.x, y.y, v.x, v.y, "yellow")
                ])

            if firstTrap.rightEdge[1] == v:
                newTrap = bst.Trap(firstTrap.leftEdge, v, secondTrap.rightEdge)
                BST.insert(newTrap)
                leftId = self.dcel.buildSegmentFromEdge(firstTrap.leftEdge).hilight(
                    color_line="blue", color_point="red")
                rightId = self.dcel.buildSegmentFromEdge(secondTrap.rightEdge).hilight(
                    color_line="blue", color_point="red")
            else:
                newTrap = bst.Trap(secondTrap.leftEdge, v, firstTrap.rightEdge)
                BST.insert(newTrap)
                leftId = self.dcel.buildSegmentFromEdge(secondTrap.leftEdge).hilight(
                    color_line="blue", color_point="red")
                rightId = self.dcel.buildSegmentFromEdge(firstTrap.rightEdge).hilight(
                    color_line="blue", color_point="red")

            control.sleep()
            control.plot_delete(leftId)
            control.plot_delete(rightId)
Esempio n. 22
0
def update_points(p1, p2):
    global a, b, id, hia, hib
    if (a != None and b != None):
        if (prim.dist2(p1, p2) >= prim.dist2(a, b)): return
    control.freeze_update()
    if a != None: a.unhilight(hia)
    if b != None: b.unhilight(hib)
    if id != None: control.plot_delete(id)
    a = p1
    b = p2
    hia = a.hilight()
    hib = b.hilight()
    id = a.lineto(b)
    control.thaw_update()
    control.update()
Esempio n. 23
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()
Esempio n. 24
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
Esempio n. 25
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
Esempio n. 26
0
def sweepline(segments):
    global event_heap, bst
    fix_segments(segments)
    bst = sweep_bst()
    segments = sorted(segments, key=functools.cmp_to_key(compare_segments))
    #testa_bst(bst, segments)
    make_event_points(segments)
    while (not event_heap.empty()):
        pt = event_heap.get()
        circ = control.plot_circle(pt.node.x, pt.node.y, "green", 2)
        control.sleep()
        if len(pt.intersections) + len(pt.right) == 0:
            seg = bst.search(pt.node.get_point())
            if seg is not None:  # um único segmento na árvore contem pt
                #  e pt é extremo esquerdo de alguns segmentos
                pt.add_to_segment([seg], -1)
        update_bst(pt)
        find_collision(pt)
        print_intersection(pt)
        control.plot_delete(circ)
Esempio n. 27
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)
Esempio n. 28
0
def discard_lines(G, p, t):
    nG = []
    b = 0
    for l in G:
        control.freeze_update()
        new_plot_id = control.plot_line(0, l(0), 1, l(1), 'cyan')
        control.sleep()
        control.thaw_update()
        control.freeze_update()
        is_under, is_above = intersects_trapezoid(l, t)
        if not (is_under or is_above):
            nG.append(l)
        elif is_under:
            b += 1
        if (is_under or is_above):
            delete_stuff([l])
        control.plot_delete(new_plot_id)
        control.sleep()
        control.thaw_update()

    return nG, p - b
Esempio n. 29
0
def add_circle_event(leaf1, leaf2, leaf3, node1, node2, q, Q):
    p1, p2, p3 = leaf1.point, leaf2.point, leaf3.point
    p2.hilight('yellow')
    p3.hilight('yellow')

    center = circumcenter(p1, p2, p3)
    radius = distance(center, p1)
    circle = control.plot_circle(center.x, center.y, 'blue', radius)

    is_convergent = not (is_divergent(node1, center)
                         and is_divergent(node2, center))
    if is_valid_event(center, radius, q) and is_convergent:
        point = Point(center.x, center.y - radius)
        leaf2.event = Event(point, False, leaf2, center)
        Q.additem(leaf2.event, point)
        point.plot(color='cyan')

    control.sleep()
    control.plot_delete(circle)
    p2.unhilight()
    p3.unhilight()
Esempio n. 30
0
    def check(self, p, q, r):
        '''
        Faz a checagem de atualização, checando se o ponto 'r' esta a 
        direita de p-q ou se 'q' esta na reta definida por q-r.
        '''
        a = p.lineto(q, color='blue')
        b = r.lineto(p, color='blue')
        c = r.lineto(q, color='blue')
        control.sleep()
        flag = False

        if self.left_test(p, q, r) == -1:
            flag = True

        elif self.left_test(p, q, r) == 0 and \
            min(p.x, r.x) <= q.x <= max(p.x, r.x) and \
            min(p.y, r.y) <= q.y <= max(p.y, r.y):
            flag = True

        for aux in [a, b, c]:
            control.plot_delete(aux)
        return flag
Esempio n. 31
0
    def find_hull(self):
        '''
        Metodo que efetivamente implementa o algoritmo de Jarvis. Retorna uma 
        lista contendo os pontos do convex hull, no senti anti-horario do fecho.
        '''

        # numero de pontos na coleção
        n = len(self.p)

        # armazena os indices dos pontos no fecho, é inicializado com o indice
        # do ponto mais esquerda e baixo da colecao
        hull = [min(zip(self.p, range(n)))[1]]

        # ponto extremo do fecho
        self.p[hull[0]].hilight(color='yellow')
        control.sleep()

        while (True):
            i = (hull[-1] + 1) % n
            id_h = self.p[i].hilight(color='yellow')
            control.sleep()
            # econtrando o proximo ponto do fecho
            for j in range(n):
                if self.p[j] == self.p[hull[-1]] or self.p[j] == self.p[i]:
                    continue
                if self.check(self.p[hull[-1]], self.p[i], self.p[j]):
                    control.plot_delete(id_h)
                    i = j
                    id_h = self.p[i].hilight(color='yellow')

            # poligono esta completo
            self.p[hull[-1]].lineto(self.p[i], color='yellow')
            if self.p[i] == self.p[hull[0]]: break
            hull.append(i)

        # fazendo com que hull seja uma lista de pontos
        for i in range(len(hull)):
            hull[i] = self.p[hull[i]]
        return hull
Esempio n. 32
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])
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
Esempio n. 34
0
def bhatta_sen_upper_rec (a, b, S):
	"""Constroi a parte superior do fecho convexo"""
	
	# step 1/2/3
	again = 1

	while again:
		if len (S) == 1:
			return [ S[0] ]
		j = int (random.uniform (0, len (S)/2))
		again = 0

		p1 = S[2*j+1]
		p2 = S[2*j]
		p1.hilight ()
		p2.hilight ()
		if inside_restricted (b, a, S[2*j+1], S[2*j]):
			S.remove (S[2*j])
			again = 1
		elif inside_restricted (b, a, S[2*j], S[2*j+1]):
			S.remove (S[2*j+1])
			again = 1

		p1.unhilight ()
		p2.unhilight ()

	
	# step 4
	m = 0
	if left (S[2*j], S[2*j+1], a):
		p1 = S[2*j+1]
		p2 = S[2*j]
	else:
		p1 = S[2*j]
		p2 = S[2*j+1]
	id = p1.lineto (p2, config.COLOR_ALT4)
	area_m = area2 (p1, p2, S[m])
	for i in range (1, len(S)):
		area_i = area2 (p1, p2, S[i])
		if area_i > area_m:
			m = i
			area_m = area_i
	pm = S[m]
	control.plot_delete (id)

	id = pm.hilight (config.COLOR_ALT1)
	control.sleep ()
	
	S1 = []
	S2 = []

	# step 5
	i = j
	#map (lambda p: p.hilight (config.COLOR_ALT2), S)
	#control.sleep ()
	#map (lambda p: p.unhilight (), S)
	control.sleep ()
	cont = []
	for j in range (0, len(S)/2):
		cont.extend ([2*j, 2*j+1])
		if S[2*j].x < S[2*j+1].x:
			p1 = S[2*j]
			p2 = S[2*j+1]
		else:
			p1 = S[2*j+1]
			p2 = S[2*j]

		p1.hilight ()
		p2.hilight (config.COLOR_ALT3)

		if p2.x <= pm.x:
			if left (pm, p2, p1):
				S1.append (p1)
				S1.append (p2)
			else:
				S1.append (p1)
		elif pm.x <= p1.x:
			if left (pm, p1, p2):
				S2.append (p2)
			else:
				S2.append (p1)
				S2.append (p2)
		else: # p1.x < pm.x < p2.x
			control.sleep ()
			S1.append (p1)
			S2.append (p2)

		p1.unhilight ()
		p2.unhilight ()

	pm.unhilight (id)
	if len (S) % 2 == 1:
		S1.append (S[-1])
		S2.append (S[-1])
	control.sleep ()
	
	map (lambda p: p.hilight (), S1)
	control.sleep ()
	
	# step 6
	for p in S1[:]:
		if not left (b, pm, p):
			S1.remove (p)
			p.unhilight ()

	control.sleep ()
	map (lambda p: p.unhilight (), S1)
	control.sleep ()
	map (lambda p: p.hilight (), S2)
	control.sleep ()

	for p in S2[:]:
		if not left (pm, a, p):
			S2.remove (p)
			p.unhilight ()
	control.sleep ()
	map (lambda p: p.unhilight (), S2)

	# step 7
	ret1 = []
	ret2 = []
	if len (S2) != 0:
		id = a.lineto (pm, config.COLOR_ALT4)
		ret2 = bhatta_sen_upper_rec (a, pm, S2)
		a.remove_lineto (pm, id)
		ret2[-1].lineto (pm)
	ret2.append (pm)
	if len (S1) != 0:
		id = pm.lineto (b, config.COLOR_ALT4)
		ret1 = bhatta_sen_upper_rec (pm, b, S1) 
		pm.remove_lineto (b, id)
		pm.lineto (ret1[0])
	
	ret2.extend (ret1)

	return ret2
Esempio n. 35
0
def Hull2D (P, m, H):

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

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

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

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

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