示例#1
0
    def _iter_items(self,
                    left=attrgetter("left"),
                    right=attrgetter("right"),
                    start_key=None,
                    end_key=None):
        node = self._root
        stack = []
        go_left = True
        in_range = self._get_in_range_func(start_key, end_key)

        while True:
            if left(node) is not None and go_left:
                stack.append(node)
                node = left(node)
            else:
                if in_range(node.key):
                    yield node.key, node.value
                if right(node) is not None:
                    node = right(node)
                    go_left = True
                else:
                    if not len(stack):
                        return  # all done
                    node = stack.pop()
                    go_left = False
示例#2
0
 def angulo (v3):
     " Devolve algo proporcional ao angulo em v2 de v1-v2-v3 "
     # Vou achar, na verdade, o cosseno do angulo com a lei do cosseno
     a2 = (v3.x - v1.x)**2 + (v3.y - v1.y)**2
     b2 = (v3.x - v2.x)**2 + (v3.y - v2.y)**2
     c2 = (v1.x - v2.x)**2 + (v1.y - v2.y)**2
     ang = ((b2 + c2 - a2)/(2*((b2*c2)**0.5)))
     if right(v1, v2, v3):
         ang = - ang - 1000
     return -ang
示例#3
0
def particione (P, l, r):

    # P[l + 1] recebe ponto extremo
    for i in range(l + 1, r):
        P[i].lineto(P[l], "gray")
        P[i].lineto(P[r], "gray")
        sleep()
        P[i].remove_lineto(P[l])
        P[i].remove_lineto(P[r])
        if abs(area2(P[i], P[l], P[r])) > abs(area2(P[l + 1], P[l], P[r])):
            P[i], P[l + 1] = P[l + 1], P[i]

    # Desenha o triangulo
    if hasattr(P[l + 1], 'hi'): P[l + 1].unhilight()
    P[l + 1].hilight("firebrick")
    linha_esq = P[l].lineto(P[l + 1], "green")
    linha_dir = P[r].lineto(P[l + 1], "red")
    sleep()
    
    p = q = r
    for k in range(r - 1, l + 1, -1):
        if hasattr(P[k], 'hi'): P[k].unhilight()
        P[k].hilight("yellow")
        sleep()
        P[k].unhilight()
        if left (P[l], P[l + 1], P[k]):
            # ponto da partição esquerda (verde)
            p -= 1
            P[p], P[k] = P[k], P[p]
            P[p].hilight("green")
            sleep()
        elif right (P[r], P[l + 1], P[k]):
            # ponto da partição direita (vermelho)
            p -= 1
            q -= 1
            P[q], P[k] = P[k], P[q]
            if p != q: P[p], P[k] = P[k], P[p]
            P[q].hilight("red")
            sleep()
    
    # Ajustes finais no vetor
    p -= 1
    q -= 1
    P[q], P[l + 1] = P[l + 1], P[q]
    if p != q:
        P[p], P[l + 1] = P[l + 1], P[p]
    p -= 1
    P[l], P[p] = P[p], P[l]

    return p, q, linha_esq, linha_dir
示例#4
0
 def _search(self, node, reference):
     if node is None:
         ret = None
     elif left(node.seg.init, node.seg.to, reference):
         ret = self._search(node.left, reference)
     elif right(node.seg.init, node.seg.to, reference):
         ret = self._search(node.right, reference)
     elif on_segment(node.seg.init, node.seg.to, reference):
         ret = node
     else:  #already is collinear
         ret = self._search(node.right, reference)
         if ret is None:
             ret = self._search(node.left, reference)
     return ret
示例#5
0
def quickhull (P):
    if len(P) <= 1: return P

    # Ponto mais baixo
    for i in range(len(P)):
        if P[i].y < P[0].y or (P[i].y == P[0].y and P[i].x > P[0].x): 
            P[0], P[i] = P[i], P[0]

    # Ponto mais a direita do ponto mais baixo
    for i in range(len(P)):
        if right (P[0], P[-1], P[i]): P[-1], P[i] = P[i], P[-1]
    
    P[0].hilight("green")
    P[-1].hilight("red")
    P[0].lineto(P[-1], "orange")
    sleep()
    
    return quickhull_rec (P, 0, len(P) - 1)
示例#6
0
def q_hull(points):
    n = len(points)
    if n == 1:
        return set(points)
    f_ind = 0
    for i, pt in enumerate(points):
        if pt.y < points[f_ind].y or\
            (pt.y == points[f_ind].y and pt.x < points[f_ind].x):
            f_ind = i
    swap(points, 0, f_ind)
    s_ind = 1
    for i in range(1, len(points)):
        if prim.right(points[0], points[s_ind], points[i]) or\
           (prim.collinear(points[0], points[s_ind], points[i]) and\
            (prim.dist2(points[0], points[s_ind]) <
                prim.dist2(points[0], points[i]))):
            s_ind = i
    swap(points, n - 1, s_ind)
    hull = q_hull_rec(points, 0, n - 1)
    for pt in hull:
        pt.hilight("blue")
    return hull
示例#7
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
示例#8
0
def right (a, b, c):
	"retorna verdadeiro se c esta a direita do segmento ab"
	ret = prim.right (a, b, c)
	triang (a, b, c)
	return ret
示例#9
0
def right(a, b, c):
    "retorna verdadeiro se c esta a direita do segmento ab"
    ret = prim.right(a, b, c)
    triang(a, b, c)
    return ret
示例#10
0
 def _succ_comp(self, seg, reference):
     return right(seg.init, seg.to, reference) or\
            collinear(seg.init, seg.to, reference)
示例#11
0
def Monotono(p):

    # Essa é a forma que eu recebo o polígono do front-end :/
    P = p[0]
    # lista com as diagonais, nosso return
    resp = []

    v = ordenaY(P)
    n = len(v)

    s = [v[0], v[1]]  # pilha
    v[0].hilight('blue')
    v[1].hilight('blue')
    t = 1  # index do fim da pilha

    for i in range(2, n):
        v[i].hilight('green')
        sleep()
        vizinho_ultimo = adj(v[i], s[t])
        vizinho_primeiro = adj(v[i], s[0])

        if vizinho_ultimo and not vizinho_primeiro:
            while t > 0:
                a = s[t - 1]
                b = s[t]
                if a.x > b.x:
                    a, b = b, a
                if right(a, b, v[i]):
                    s[t].unhilight()
                    s.pop()
                    t -= 1
                    # acrescenta a nova diagonal
                    d = Segment(s[t], v[i])
                    d.plot('green')
                    sleep()
                    resp.append(d)
                else:
                    break
            t += 1
            s.append(v[i])
            v[i].unhilight()
            v[i].hilight('blue')

        elif vizinho_primeiro and not vizinho_ultimo:
            aux = s[t]
            while t > 0:
                # acrescenta a nova diagonal
                d = Segment(s[t], v[i])
                d.plot('green')
                sleep()
                resp.append(d)

                s.pop()
                t -= 1
                s[t].unhilight()
            s = []
            s.append(aux)
            s.append(v[i])
            v[i].unhilight()
            v[i].hilight('blue')
            t = 1

        else:
            while t > 1:
                s[t].unhilight()
                t -= 1
                # acrescenta a nova diagonal
                d = Segment(s[t], v[i])
                d.plot('green')
                sleep()
                resp.append(d)
            s[0].unhilight()
            s[1].unhilight()
            v[i].unhilight()
    return resp
示例#12
0
 def __gt__(self, other):
     if (right(other.seg.init, other.seg.to, self.point)): return True
     elif (other.seg.has_inside(self.point)
           and right(other.seg.init, other.seg.to, self.seg.to)):
         return True
     return False
示例#13
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("")