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 plot(self):
     if self.rank != 0:
         return
     self.drawing = []
     for i in range(3):
         self.drawing.append(self.P[i - 1].inner.lineto(
             self.P[i].inner, COLOR_TRIANG))
     control.thaw_update()
     control.update()
     control.freeze_update()
Beispiel #4
0
def e_lineto(p, q, color=config.COLOR_PRIM):
    if max(p.inf, q.inf) > 0:
        return
    keep = p.inner.lineto(q.inner, color)

    control.thaw_update()
    control.update()
    control.freeze_update()
    control.sleep()

    p.inner.remove_lineto(q, keep)
Beispiel #5
0
def Fortune(P):
    Q = event_queue(P)
    V = DCEL()
    T = BST()

    for event in Q.keys():
        V.add_face(event.face)

    while Q:
        q = Q.pop()
        q.point.hilight()
        par_plots, sweep = plot_all(T.all_leaves(), V, q.point.y)
        control.sleep()

        if q.is_site_event:
            handle_site_event(q, T, Q, V)
        else:
            handle_circle_event(q, T, Q, V)
            q.point.unplot()
        control.sleep()

        if len(Q) > 0:
            next_y = Q.top().point.y
            line_y = q.point.y
            leaves = T.all_leaves()
            # while not math.isclose(line_y, next_y, rel_tol=4*FORTUNE_PLOT_RATE):
            # FORTUNE_PLOT_RATE = abs(line_y - next_y)/100
            while line_y > next_y:
                control.thaw_sleep()
                if abs(line_y - next_y) > FORTUNE_PLOT_RATE * 10**3:
                    line_y -= abs(line_y - next_y) / 10
                else:
                    line_y -= FORTUNE_PLOT_RATE

                unplot_all(par_plots, V.hedges, sweep)

                par_plots, sweep = plot_all(leaves, V, line_y)
                control.thaw_update()
                control.update()
                control.freeze_update()

        unplot_all(par_plots, V.hedges, sweep)

        q.point.unhilight()
        control.update()

    vertices = [v.p for v in V.vertices]
    borders = find_borders(P + vertices)
    finalize_voronoi(V, T, borders)

    for h in V.hedges:
        h.segment.plot()
    return V
Beispiel #6
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()
Beispiel #7
0
def partition(P, p, r, point_p, point_r):
    '''Recebe uma coleção de pontos em posição geral, com pelo menos 3 pontos tal
    que os pontos de índice p e r são extremos consecutivos na fronteira do fecho
    convexo da coleção no sentido anti-horário. Rearranja a coleção de pontos e
    devolve (s,q) para o algoritmo do QuickHull.'''
    q = extreme(P, p, r)
    points[(point_r, P[q])] = point_r.lineto(P[q], 'cyan')
    points[(P[q], point_p)] = P[q].lineto(point_p, 'cyan')
    control.thaw_update()
    control.update()
    control.freeze_update()
    control.sleep()

    P[p + 1], P[q] = P[q], P[p + 1]
    s = q = r

    for point, id in ids:
        point.unhilight(id)

    for k in range(r - 1, p + 1, -1):
        if left(P[p], P[p + 1], P[k]):
            id = P[k].hilight('green')
            ids.append((P[k], id))
            s -= 1
            P[s], P[k] = P[k], P[s]
        elif left(P[p + 1], P[r], P[k]):
            id = P[k].hilight('red')
            ids.append((P[k], id))
            s -= 1
            q -= 1
            P[k], P[q] = P[q], P[k]
            if s != q:
                P[k], P[s] = P[s], P[k]

    control.thaw_update()
    control.update()
    control.freeze_update()
    control.sleep()

    s -= 1
    q -= 1
    P[q], P[p + 1] = P[p + 1], P[q]

    if s != q:
        P[s], P[p + 1] = P[p + 1], P[s]
    s -= 1
    P[s], P[p] = P[p], P[s]
    return s, q
Beispiel #8
0
def triang (a, b, c):
	"desenha  (e apaga) os lados do triangulo abc"
	a.lineto (c, config.COLOR_PRIM)
	#b.lineto (a, config.COLOR_PRIM)
	c.lineto (b, config.COLOR_PRIM)
	c.hilight ()
	control.thaw_update ()
	control.update ()
	control.freeze_update ()

	control.sleep ()

	c.unhilight ()
	a.remove_lineto (c)
	#b.remove_lineto (a)
	c.remove_lineto (b)
Beispiel #9
0
def triang(a, b, c):
    "desenha  (e apaga) os lados do triangulo abc"
    a.lineto(c, config.COLOR_PRIM)
    #b.lineto (a, config.COLOR_PRIM)
    c.lineto(b, config.COLOR_PRIM)
    c.hilight()
    control.thaw_update()
    control.update()
    control.freeze_update()

    control.sleep()

    c.unhilight()
    a.remove_lineto(c)
    #b.remove_lineto (a)
    c.remove_lineto(b)
Beispiel #10
0
def ear_tip(P, v):
    '''Recebe um polígono P e um vértice v desse polígono, e decide se ele é
    uma ponta de orelha'''
    u = P.prev(v)
    w = P.next(v)
    v.hilight('green')
    u.hilight('yellow')
    w.hilight('yellow')
    control.sleep()
    control.thaw_update()
    control.update()
    diag = diagonal(P, u, w)
    u.unhilight()
    w.unhilight()
    if not diag:
        v.unhilight()
    control.sleep()
    control.thaw_update()
    control.update()
    return diag
Beispiel #11
0
def Quickhull(P):
    '''Recebe uma coleção de pontos P e devolve seu fecho convexo'''
    n = len(P)
    if n == 1:
        return [P[0]]

    # encontra primeiro ponto extremo
    k = 0
    for i in range(n):
        # desempata por x
        if P[i].y < P[k].y or (P[i].y == P[k].y and P[i].x < P[k].x):
            k = i
    P[0], P[k] = P[k], P[0]

    # encontra extremo consecutivo ao primeiro
    i = 1
    dist = 0
    for j in range(2, n):
        if right(P[0], P[i], P[j]):
            i = j
        # desempata pelo mais distante
        elif collinear(P[0], P[i],
                       P[j]) and dist2(P[0], P[i]) < dist2(P[0], P[j]):
            i = j
    P[n - 1], P[i] = P[i], P[n - 1]

    P[0].lineto(P[n - 1], 'cyan')
    control.thaw_update()
    control.update()
    control.freeze_update()
    control.sleep()
    quick = quickhull_rec(P, 0, n - 1, Point(P[0].x, P[0].y),
                          Point(P[n - 1].x, P[n - 1].y))
    for p in quick:
        p.hilight('yellow')
    return quick
Beispiel #12
0
def triangulation(n, P):
    '''Recebe um polígono P com n lados e devolve a triangulação de P'''
    ears = find_ears(P)
    v3 = P.pts
    while n > 3:
        v2 = v3
        while not ears[v2]:
            v2 = P.next(v2)
        v2.hilight("blue")
        v1 = P.prev(v2)
        v3 = P.next(v2)
        v1.lineto(v3, "blue")
        control.sleep()
        control.thaw_update()
        control.update()
        print(v1, v3)
        v2.unhilight()
        control.sleep()
        control.thaw_update()
        control.update()
        P.remove_vertex(v2)
        n -= 1
        ears[v1] = ear_tip(P, v1)
        ears[v3] = ear_tip(P, v3)
Beispiel #13
0
 def __update(self):
     control.thaw_update()
     control.update()
     control.freeze_update()
     control.sleep()
Beispiel #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("")
Beispiel #15
0
def fortune(l, triang):
    # Inicializa as estruturas de dados
    Q = EventQueue()
    Beach = BeachLine()
    Vor = dcel()
    CircDraw = draw_circ_events()
    #
    # Remove pontos repetidos na entrada
    l = unique_points(l)
    # Inicializa as variáveis
    global DelaunayTriangDraw
    DelaunayTriangDraw = triang
    lineid = None
    partiallines = None
    parabola_list = None
    max_x = min_x = l[0].x
    max_y = min_y = l[0].y
    first_y = None
    high_y = None
    cur_c = None
    y_count = 1
    last_y = None
    #
    # Busca a bounding box dos pontos, e insere os pontos na fila
    for p in l:
        if p.x > max_x:
            max_x = p.x
        if p.x < min_x:
            min_x = p.x
        if p.y > max_y:
            max_y = p.y
        if p.y < min_y:
            min_y = p.y
        if high_y is None:
            high_y = p.y
        elif p.y > high_y:
            high_y = p.y
            y_count = 1
        elif p.y == high_y:
            y_count = y_count + 1
        Q.put(Ponto(p.x, p.y), Ponto(p.x, p.y))
        # Desenhas os pontos um pouco maiores
        control.plot_disc(p.x, p.y, config.COLOR_POINT, 4)
    #
    # Define os bounds da tela
    yd = max_y - min_y
    xd = max_x - min_x
    dd = max(yd, xd)
    mfactor = 0.7
    bounds = {
        "maxx": (max_x + min_x) / 2 + dd * mfactor,
        "minx": (max_x + min_x) / 2 - dd * mfactor,
        "maxy": (max_y + min_y) / 2 + dd * mfactor,
        "miny": (max_y + min_y) / 2 - dd * mfactor
    }
    Beach.bounds = bounds

    # Caso os primeiros pontos tenham a mesma y-coordenada, trata este caso particular
    if y_count > 1:
        aligned = []
        for i in range(y_count):
            aligned.append(Q.takeHighest())
        aligned = list(reversed(aligned))
        for i in range(len(aligned) - 1):
            drawDelaunayEdge(aligned[i].x, aligned[i].y, aligned[i + 1].x,
                             aligned[i + 1].y)
        Beach.create_particular(aligned)

    # Loop principal
    while Q.n > 0:
        atual = Q.takeHighest()
        ## Remove o desenho do ponto evento círculo da iteração anterior, e desenha a nova posição da linha de varredura
        control.freeze_update()
        if cur_c is not None:
            control.plot_delete(cur_c)
            cur_c = None
        lineid = control.plot_horiz_line(atual.y)
        ##

        # Trata evento ponto ou círculo
        if atual.isPonto:
            trataPonto(atual, Q, Beach, CircDraw)
        else:
            cur_c = control.plot_disc(atual.x, atual.y, config.COLOR_ALT5, 4)
            CircDraw.rem_point(atual.x, atual.y)
            trataCirculo(atual, Q, Beach, CircDraw)
        #

        # Desenha as parábolas e as arestas de Voronoi parciais
        parabola_list = Beach.draw_parabolas(atual.y)
        partiallines = Beach.draw_partial(atual.y)
        control.thaw_update()
        control.update()
        control.sleep()
        # Remove o desenho das parábolas e da linha de varredura desta iteração
        if lineid is not None: control.plot_delete(lineid)
        if parabola_list is not None:
            for i in parabola_list:
                control.plot_delete(i)

        # Remove as parábolas que 'sairam da tela', remove seus respectivos eventos e o desenho destes eventos
        evlist = Beach.trata_extremos(atual.y)
        for ev in evlist:
            CircDraw.rem_point(ev.x, ev.y)
            Q.take(ev)
        last_y = atual.y

    # Atualiza o desenho para a última iteração
    lower = last_y - 2 * (Beach.bounds["maxy"] - Beach.bounds["miny"])
    partiallines = Beach.draw_partial(lower)
    if cur_c is not None:
        control.plot_delete(cur_c)
        cur_c = None

    # Desenha as arestas de Delaunay que não foram consideradas durante o algoritmo (por conta das parabolas serem removidas)
    if Beach.llist:
        for i in range(len(Beach.llist) - 1):
            p1, q1 = Beach.llist[i]
            p2, q2 = Beach.llist[i + 1]
            x, y = lineIntersect(p1, q1, p2, q2)
            if x is not None and x < Beach.bounds["minx"]:
                Beach.llist[i + 1] = [p1, q1]
                if q1 == p2:
                    drawDelaunayEdge(p1.x, p1.y, q2.x, q2.y)
                elif q1 == p1:
                    drawDelaunayEdge(p2.x, p2.y, q2.x, q2.y)
                elif q2 == p2:
                    drawDelaunayEdge(p1.x, p1.y, q1.x, q1.y)
                else:
                    drawDelaunayEdge(p2.x, p2.y, q1.x, q1.y)

    if Beach.rlist:
        for i in range(len(Beach.rlist) - 1):
            p1, q1 = Beach.rlist[i]
            p2, q2 = Beach.rlist[i + 1]
            x, y = lineIntersect(p1, q1, p2, q2)
            if x is not None and x > Beach.bounds["maxx"]:
                Beach.rlist[i + 1] = [p1, q1]
                if q1 == p2:
                    drawDelaunayEdge(p1.x, p1.y, q2.x, q2.y)
                elif q1 == p1:
                    drawDelaunayEdge(p2.x, p2.y, q2.x, q2.y)
                elif q2 == p2:
                    drawDelaunayEdge(p1.x, p1.y, q1.x, q1.y)
                else:
                    drawDelaunayEdge(p2.x, p2.y, q1.x, q1.y)

    # Constroi a DCEL
    Vor.constroi(edges)

    return Vor