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
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
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
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
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)
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
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
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
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
def _succ_comp(self, seg, reference): return right(seg.init, seg.to, reference) or\ collinear(seg.init, seg.to, reference)
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
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
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("")