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)
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)))
def __caseC(self, currentVertex): self.__stack.pop() while (self.__stackSize() > 1): control.sleep() self.__addDiagonal(currentVertex) self.__stack.pop()
def update(self, a, b): ''' função auxiliar que recebe 2 pontos e atualiza o melhor caso necessario a, b: pontos candidatos ''' a_id = a.hilight(color='cyan') b_id = b.hilight(color='cyan') l_id = a.lineto(b, color='cyan') control.sleep() d = a.distance_to(b) if d < EPS: d = 0 if d < self.best[0][2]: # atualizando visualização control.sleep() if self.best[1][0] != None: self.best[0][0].unhilight(self.best[1][0]) if self.best[1][1] != None: self.best[0][1].unhilight(self.best[1][1]) if self.best[1][2] != None: self.best[0][0].remove_lineto(self.best[0][1], self.best[1][2]) self.best[0][0] = a self.best[0][1] = b self.best[0][2] = d self.best[1][0] = a.hilight(color='green') self.best[1][1] = b.hilight(color='green') self.best[1][2] = a.lineto(b, color='green') a.unhilight(a_id) b.unhilight(b_id) a.remove_lineto(b, l_id) return d
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)
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()
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)
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)
def trata_ponta_pra_cima (p, L, dcel, diags): viz_esq = p.next viz_dir = p.prev if left (p, viz_dir, viz_esq): viz_esq, viz_dir = viz_dir, viz_esq t = Trapezio (p) removido = (L.busca (t)).elemento if removido == None: t.a_esq = Segment (p, viz_esq) t.a_dir = Segment (p, viz_dir) t.desenha() L.insere (t) else: L.deleta (t) removido.apaga() d = Segment (p, removido.sup) d.plot('blue') dcel.add_edge (d.init, d.to) diags.append(d) control.sleep() t1 = Trapezio (p, removido.a_esq, Segment (p, viz_esq)) t2 = Trapezio (p, Segment (p, viz_dir), removido.a_dir) t1.desenha() t2.desenha() L.insere (t1) L.insere (t2) control.sleep()
def trata_caso_meio (p, viz_baixo, L, dcel, diags): # Remove da linha o trapésio que tem o p t = Trapezio (p) removido = (L.busca (t)).elemento removido.apaga() L.deleta (t) if ponta_pra_baixo (removido.sup): d = Segment (removido.sup, p) d.plot('blue') dcel.add_edge (d.init, d.to) diags.append(d) control.sleep() # Insere um novo trapésio com o p # Se o removido estava a direita if (p == removido.a_dir.to): t.a_dir = Segment (p, viz_baixo) t.a_esq = removido.a_esq # Se estava a esquerda else: t.a_esq = Segment (p, viz_baixo) t.a_dir = removido.a_dir t.desenha() L.insere (t) control.sleep()
def find_destine(pt): global DG, root visited = set() stack = [root] visited.add(root) found = None while (found is None): node = stack[-1] if (node in visited): node.draw() control.sleep() f = False for nd in DG.adj[node]: if (nd not in visited): node.remove_draw() stack.append(nd) f = True break if (f): continue #At this point: node is the leaf! else: if not node.contains_proper(pt) and not node.is_on_edge(pt): # node subtree does not contain pt stack.pop() visited.add(node) continue found = node found.remove_draw() degen = found.is_on_edge(pt) return degen, found
def trataCaso2(u,v,w,arvore,vertices,diagonais,faces): if(left(u,v[0],w)): # u<=>w aux = w w = u u = aux aux = arvore.get(v[0]) arvore.delete(v[0]) if(aux is None): #print bcolors.OKBLUE,"Inseri um trapézio com vértice de apoio ", v,": ",Segment(v[0],u),Segment(v[0],w),bcolors.ENDC arvore.insert( ( Segment(v[0],u),v,Segment(v[0],w) ) ) else: trap = aux.trap #print bcolors.OKBLUE,"Inseri dois trapézios com vértice de apoio ", v ,": ",trap[0],Segment(v[0],u)," E ",Segment(v[0],w),trap[2],bcolors.ENDC arvore.insert( (Segment(v[0],w),v,trap[2]) ) #insiro esse primeiro para respeitar a ordem correta na arvore(dado que eu escolhi comparar por x do vertice de apoio arvore.insert( (trap[0],v,Segment(v[0],u)) ) diagonais.append( Segment(trap[1][0],v[0]) ) aresta = Aresta() aresta.setAresta(Segment(trap[1],v)) aresta2 = Aresta() aresta2.setAresta(Segment(v,trap[1])) aresta.setGemeo(aresta2) aresta2.setGemeo(aresta) Segment(trap[1][0],v[0]).hilight("blue") control.sleep() insereDiagonal(vertices[trap[1][1]-1],vertices[v[1]-1],aresta,faces)
def trataCaso1(u,v,w,arvore,pontos,vertices,diagonais,faces): if(u.y < w.y): #u <=> w aux = w w = u u = aux aux = (arvore.get(v[0])).trap #aux recebe um trapézio que contem v arvore.delete(v[0]) if(v[0].x == aux[0].to.x and v[0].y == aux[0].to.y): arvore.insert((Segment(v[0],w),v,aux[2])) #print bcolors.OKBLUE,"Inseri um trapézio com vértice de apoio", v," : ",Segment(v[0],w),aux[2],bcolors.ENDC else: arvore.insert((aux[0],v,Segment(v[0],w))) #print bcolors.OKBLUE,"Inseri um trapézio com vértice de apoio ",v,": ",aux[0],Segment(v[0],w),bcolors.ENDC if(pontaParaBaixo(aux[1],pontos)): diagonais.append(Segment(aux[1][0],v[0])) aresta = Aresta() aresta.setAresta(Segment(aux[1],v)) aresta2 = Aresta() aresta2.setAresta(Segment(v,aux[1])) aresta.setGemeo(aresta2) aresta2.setGemeo(aresta) Segment(aux[1][0],v[0]).hilight("blue") control.sleep() insereDiagonal(vertices[aux[1][1]-1],vertices[v[1]-1],aresta,faces)
def marca_intersec (no1, no2, pontos, x = None): "Testa se há interseção entre o nó1 e o nó2 e adiciona em pontos, se houver" "E só marca as interseções que ocorrem do x pra direita" # Despinta de verde e pinta de amarelo no1.seg.hide() no2.seg.hide() no1.seg.plot ("yellow") no2.seg.plot ("yellow") control.sleep() # despinta de amarelo e pinta de verde denovo no1.seg.hide() no2.seg.hide() no1.seg.plot ("green") no2.seg.plot ("green") p = no1.seg.intersection (no2.seg) # Só marco se o o ponto esta pra frente do x especificado if (p != None and (x == None or p.x > x)): # Crio o nó p_no = Node_Point (p, ini = [], fim = [], inter = [no1, no2]) # insere o ponto na arvore, ou só atualiza se ele já existir p_no_abb = pontos.busca (p_no) if p_no_abb.elemento == None: pontos.insere (p_no) p_no.ponto.plot('blue') else: if no1 not in p_no_abb.elemento.inter: p_no_abb.elemento.inter.append (no1) if no2 not in p_no_abb.elemento.inter: p_no_abb.elemento.inter.append (no2) control.sleep()
def update(a, b, best): ''' a, b: pontos candidatos best: melhores pontos encontrados ''' a_id = a.hilight(color='blue') b_id = b.hilight(color='blue') l_id = a.lineto(b, color='blue') control.sleep() d = a.distance_to(b) if d < best[0][2]: # atualizando visualização control.sleep() if best[1][0] != None: best[0][0].unhilight(best[1][0]) if best[1][1] != None: best[0][1].unhilight(best[1][1]) if best[1][2] != None: best[0][0].remove_lineto(best[0][1], best[1][2]) best[0][0] = a best[0][1] = b best[0][2] = d best[1][0] = a.hilight(color='green') best[1][1] = b.hilight(color='green') best[1][2] = a.lineto(b, color='green') a.unhilight(a_id) b.unhilight(b_id) a.remove_lineto(b, l_id)
def Lee_Preparata (p): P = p[0] diags = [] d = Dcel () d.initPolygon (P) # Atualiza a DCEL colocando as diagonais parar a partição em monótonos monotonos (d, P, diags) n_face_externa = len(P.vertices()) divisoras = len(diags) # Para cada face, constrói um polígono e triangula ele if len (d.f) == 2: return Monotono([P]) for e in d.f: vertices = [e.init] while e.to != vertices[0]: vertices.append (e.to) e = e.prox if len(vertices) != n_face_externa: new_p = Polygon (vertices) new_p.plot("orange") control.sleep() # Triangula o new_p e adiciona as novas diagonais no diags diags.extend (Monotono ([new_p])) new_p.hide() # despinta as arestas for i in range(divisoras): diags[i].hide() diags[i].plot("green")
def trataCaso3(v,arvore,pontos,vertices,diagonais,faces): aux = (arvore.get(v[0])).trap arvore.delete(v[0]) if(pontaParaBaixo(aux[1],pontos)):#aux[1] = vertice de apoio do trapézio diagonais.append(Segment(aux[1][0],v[0])) aresta = criaAresta(aux[1],v) Segment(aux[1][0],v[0]).hilight("blue") control.sleep() insereDiagonal(vertices[aux[1][1]-1],vertices[v[1]-1],aresta,faces) if( ((aux[0].to.x != v[0].x and aux[0].to.y != v[0].y) or (aux[2].init.x != v[0].x and aux[2].init.y != v[0].y)) ):#caso tenham 2 trapézios com v aux2 = arvore.get(v[0]) #segundo trapexio que contem v if(aux2): aux2 = aux2.trap arvore.delete(v[0]) if(pontaParaBaixo(aux2[1],pontos)): #aux2[1] = vertice de apoio do segundo trapézio diagonais.append(Segment(aux2[1][0],v[0])) aresta = criaAresta(aux2[1],v) Segment(aux2[1][0],v[0]).hilight("blue") control.sleep() insereDiagonal(vertices[aux2[1][1]-1],vertices[v[1]-1],aresta,faces) if( aux[2].to.x == v[0].x and aux[2].to.y == v[0].y): arvore.insert( (aux[0],v,aux2[2]) ) else: arvore.insert( (aux2[0],v,aux[2]) )
def visit(self, u, target): u.setVisited(True) v = self.findNeighbor(u) while v is not None: # Printando o segmento atual do grafo seg = Segment(Point(u.x, u.y), Point(v.x, v.y)) seg.plot('cyan') control.sleep() # Continuar o DFS if (v == target): self.solved = True return 1 self.visit(v, target) # Condicao de parada do DFS if(self.solved): return 1 # Retirando o print do segmento seg.hide() control.sleep() # Pegar o próximo vizinho v = self.findNeighbor(u)
def Brute_Force(segmentos): cores = (config.COLOR_ALT1, config.COLOR_ALT7, config.COLOR_ALT6) for segmento in segmentos: segmento.intersected = False for i in range (len(segmentos)): control.freeze_update () hii = segmentos[i].hilight2 (cores[1]) control.thaw_update () control.sleep() for j in range (i + 1, len (segmentos)): control.freeze_update () hij = segmentos[j].hilight2(cores[0]) control.thaw_update () control.sleep() if prim.inter(segmentos[i],segmentos[j]): control.freeze_update () segmentos[i].hilight2 (cores[2]) segmentos[j].hilight2 (cores[2]) segmentos[i].intersected = True segmentos[j].intersected = True control.thaw_update () segmentos[j].unhilight (hij) segmentos[i].unhilight (hii)
def visGraphAlg(l): poligs = leEntrada(l) robo = poligs[0] destino = None desenhaTudo(l) #Muito codigo igual ao de baixo...mas deixa if(len(robo) == 1): print("Robo ponto na posicao ", robo[0]) probo = robo[0] destino = poligs[1][0] #Suponho ser um ponto else: robo = Robo(robo) probo = poligs[1][0] # Suponho ser um ponto poligs.pop(0) #Removo o polígono do robo da lista, iremos tratar só com o ponto destino = poligs[1][0] # Suponho ser um ponto for i in range(len(poligs)): if(len(poligs[i]) > 1): poligs[i] = robo.deformaPolig(poligs[i]) Polygon(poligs[i]).plot() control.sleep() pontos = [] for i in range(len(poligs)): poligs[i] = Polygon(poligs[i]) poligs[i].hilight() pontos.extend(poligs[i].to_list()) control.sleep() probo.prev = probo.__next__ = probo compara = criaCompara(probo) pontos.sort(key = cmp_to_key(compara), reverse = True) #Grafo G = Grafo(len(pontos)) #Numerando os pontos for i in range(len(pontos)): pontos[i].i = i; for pi in pontos: W = verticesVisiveis(pi, poligs) for pj in W: G.addAresta(pi.i,pj.i, dist2(pi,pj)**0.5) path, dist = G.dijkstra(probo.i, destino.i) for i in range(len(path)-1): v = path[i]; u = path[i+1] pontos[v].lineto(pontos[u], 'red')
def add_to_normal_case(par, pt): global DG, dcel # adds three new triangles to Digraph verts = par.get_vertices() #parent vertices counter-clockwise #new triangles -> already counter-clockwise new_t1 = Node(verts[0], verts[1], pt) new_t2 = Node(verts[1], verts[2], pt) new_t3 = Node(verts[2], verts[0], pt) DG.add_node(new_t1) DG.add_node(new_t2) DG.add_node(new_t3) DG.add_edge(par, new_t1) DG.add_edge(par, new_t2) DG.add_edge(par, new_t3) # updates the DCEL h1_1 = hedge(verts[1], pt) h1_2 = hedge(pt, verts[0]) h1_3 = dcel.get_hedge((verts[0], verts[1])) h1_1.set_data(new_t1, h1_3, h1_2) h1_2.set_data(new_t1, h1_1, h1_3) h1_3.set_data(new_t1, h1_2, h1_1) dcel.add_hedge(h1_1) dcel.add_hedge(h1_2) h2_1 = hedge(verts[2], pt) h2_2 = hedge(pt, verts[1]) h2_3 = dcel.get_hedge((verts[1], verts[2])) h2_1.set_data(new_t2, h2_3, h2_2) h2_2.set_data(new_t2, h2_1, h2_3) h2_3.set_data(new_t2, h2_2, h2_1) dcel.add_hedge(h2_1) dcel.add_hedge(h2_2) h3_1 = hedge(verts[0], pt) h3_2 = hedge(pt, verts[2]) h3_3 = dcel.get_hedge((verts[2], verts[0])) h3_1.set_data(new_t3, h3_3, h3_2) h3_2.set_data(new_t3, h3_1, h3_3) h3_3.set_data(new_t3, h3_2, h3_1) dcel.add_hedge(h3_1) dcel.add_hedge(h3_2) dcel.get_hedge((verts[2], pt)).face.draw() dcel.get_hedge((verts[1], pt)).face.draw() dcel.get_hedge((verts[0], pt)).face.draw() control.sleep() dcel.get_hedge((verts[2], pt)).face.remove_draw() dcel.get_hedge((verts[1], pt)).face.remove_draw() dcel.get_hedge((verts[0], pt)).face.remove_draw() for he in [h1_1, h2_1, h3_1]: if he.face != he.next.face or\ he.face != he.prev.face: print("BIG PROBLEM NUMBER 2") return [new_t1, new_t2, new_t3]
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()
def Incr(l): dag = DAG() for pt in l: pt.hilight() control.sleep() dag.insert(pt) pt.unhilight() print(DAG.to_graph(dag)) return dag
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
def __caseA(self, currentVertex): isTopNextOrder = self.__stackTop().vertexNumber() == self.__dcel.iterateVertex( currentVertex.vertexNumber() + 1) while (self.__stackSize() > 1 and self.__angle(currentVertex, isTopNextOrder)): control.sleep() self.__stack.pop() self.__addDiagonal(currentVertex) self.__stack.append(currentVertex)
def pontosRepetidos(l): " Verifica se há pontos coincidentes em l " for i in range(1, len(l)): l[i].hilight('green') control.sleep() if l[i] == l[i - 1]: l[i].hilight('red') return True l[i].unhilight() return False
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)
def Reflex(ui, st, stt): ui.origin.lineto(stt.origin, 'yellow') control.sleep () ui.origin.remove_lineto(stt.origin) if(collinear(st.origin, stt.origin, ui.origin)): return 1 if(st.rightSide): return left_on(stt.origin, st.origin, ui.origin) return right_on(stt.origin, st.origin, ui.origin)
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 Reflex(ui, st, stt): ui.origin.lineto(stt.origin, "yellow") control.sleep() ui.origin.remove_lineto(stt.origin) if collinear(st.origin, stt.origin, ui.origin): return 1 if st.rightSide: return left_on(stt.origin, st.origin, ui.origin) return right_on(stt.origin, st.origin, ui.origin)
def __caseB(self, currentVertex): aux = self.__stackTop() while (self.__stackSize() > 1): control.sleep() self.__addDiagonal(currentVertex) self.__stack.pop() self.__stack.pop() self.__stack.append(aux) self.__stack.append(currentVertex)
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)
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 draw_triang(pt1, pt2, pt3): seg1 = segment.Segment(pt1, pt2) seg2 = segment.Segment(pt1, pt3) seg3 = segment.Segment(pt2, pt3) seg1.hilight("yellow") seg2.hilight("yellow") seg3.hilight("yellow") control.sleep() seg1.unhilight() seg2.unhilight() seg3.unhilight()
def add_triangs_dcel(d, p, triang): " Adiciona o P na dcel d e uma aresta de p pra cada ponta do triang " d.add_vertex(p) e1 = d.add_edge(p, triang.p1, triang.a.f) e2 = d.add_edge(p, triang.p2, triang.a.f) e3 = d.add_edge(p, triang.p3, e2.f) e1.draw(color_novo) e2.draw(color_novo) e3.draw(color_novo) sleep() return e1, e2, e3
def visGraphAlg(l): poligs = leEntrada(l) robo = poligs[0] destino = None desenhaTudo(l) #Muito codigo igual ao de baixo...mas deixa if (len(robo) == 1): print("Robo ponto na posicao ", robo[0]) probo = robo[0] destino = poligs[1][0] #Suponho ser um ponto else: robo = Robo(robo) probo = poligs[1][0] # Suponho ser um ponto poligs.pop( 0 ) #Removo o polígono do robo da lista, iremos tratar só com o ponto destino = poligs[1][0] # Suponho ser um ponto for i in range(len(poligs)): if (len(poligs[i]) > 1): poligs[i] = robo.deformaPolig(poligs[i]) Polygon(poligs[i]).plot() control.sleep() pontos = [] for i in range(len(poligs)): poligs[i] = Polygon(poligs[i]) poligs[i].hilight() pontos.extend(poligs[i].to_list()) control.sleep() probo.prev = probo.__next__ = probo compara = criaCompara(probo) pontos.sort(key=cmp_to_key(compara), reverse=True) #Grafo G = Grafo(len(pontos)) #Numerando os pontos for i in range(len(pontos)): pontos[i].i = i for pi in pontos: W = verticesVisiveis(pi, poligs) for pj in W: G.addAresta(pi.i, pj.i, dist2(pi, pj)**0.5) path, dist = G.dijkstra(probo.i, destino.i) for i in range(len(path) - 1): v = path[i] u = path[i + 1] pontos[v].lineto(pontos[u], 'red')
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
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)
def trataCaso3(v,arvore,pontos,vertices,diagonais,faces): aux = (arvore.get(v[0])).trap arvore.delete(v[0]) if(pontaParaBaixo(aux[1],pontos)):#aux[1] = vertice de apoio do trapézio diagonais.append(Segment(aux[1][0],v[0])) aresta = Aresta() aresta.setAresta(Segment(aux[1],v)) aresta2 = Aresta() aresta2.setAresta(Segment(v,aux[1])) aresta.setGemeo(aresta2) aresta2.setGemeo(aresta) Segment(aux[1][0],v[0]).hilight("blue") control.sleep() insereDiagonal(vertices[aux[1][1]-1],vertices[v[1]-1],aresta,faces) print "Adicionada diagonal ",Segment(aux[1][0],v[0]) if((aux[0].to.x != v[0].x and aux[0].to.y != v[0].y) or (aux[2].to.x != v[0].x and aux[2].to.y != v[0].y)):#caso tenham 2 trapézios com v aux2 = (arvore.get(v[0])).trap #segundo trapézio que contém v arvore.delete(v[0]) if(pontaParaBaixo(aux2[1],pontos)): #aux2[1] = vertice de apoio do segundo trapézio diagonais.append(Segment(aux2[1][0],v[0])) aresta = Aresta() aresta.setAresta(Segment(aux2[1][0],v[0])) aresta2 = Aresta() aresta2.setAresta(Segment(v[0],aux2[1][0])) aresta.setGemeo(aresta2) aresta2.SetGemeo(aresta) Segment(aux2[1][0],v[0]).hilight("blue") control.sleep() insereDiagonal(vertices[aux2[1][1]-1],vertices[v[1]-1],aresta,faces) #print "Adicionada diagonal ",Segment(aux2[1][0],v[0]) if( aux[2].init.x == v[0].x and aux[2].init.y == v[0].y): arvore.insert( (aux[0],v,aux2[2]) ) #print bcolors.OKBLUE,"Inserido trapézio com vértice de apoio ",v," : ",aux[0],aux2[2] else: arvore.insert( (aux2[0],v,aux[2]) )
def trataCaso1(u,v,w,arvore,pontos,vertices,diagonais,faces): if(u.y < w.y or (u.y == w.y and u.x > w.x ) ): #u <=> w aux = w w = u u = aux aux = (arvore.get(v[0])).trap #aux recebe um trapézio que contem v arvore.delete(v[0]) if(v[0].x == aux[0].to.x and v[0].y == aux[0].to.y): arvore.insert((Segment(v[0],w),v,aux[2])) else: arvore.insert((aux[0],v,Segment(v[0],w))) if(pontaParaBaixo(aux[1],pontos)): diagonais.append(Segment(aux[1][0],v[0])) aresta = criaAresta(aux[1],v) Segment(aux[1][0],v[0]).hilight("blue") control.sleep() insereDiagonal(vertices[aux[1][1]-1],vertices[v[1]-1],aresta,faces)
def superior_tangent (v, u): """Determina a tangente superior aos poligonos que contem v e u""" v.lineto (u, config.COLOR_ALT1) hiv = v.hilight () hiu = u.hilight () ch1 = is_sup_tan_ch1 (v, u) ch2 = is_sup_tan_ch2 (v, u) while not (ch1 and ch2): while not ch1: v.remove_lineto (u) v.unhilight (hiv) v = v.next hiv = v.hilight () v.lineto (u, config.COLOR_ALT1) control.sleep () ch1 = is_sup_tan_ch1 (v, u) ch2 = is_sup_tan_ch2 (v, u) while not ch2: v.remove_lineto (u) u.unhilight (hiu) u = u.prev hiu = u.hilight () v.lineto (u, config.COLOR_ALT1) control.sleep () ch2 = is_sup_tan_ch2 (v, u) ch1 = is_sup_tan_ch1 (v, u) v.unhilight (hiv) u.unhilight (hiu) v.remove_lineto (u) return (v, u)
def trataCaso2(u,v,w,arvore,vertices,diagonais,faces): if(left(u,v[0],w )): # u<=>w aux = w w = u u = aux aux = arvore.get(v[0]) arvore.delete(v[0]) if(aux is None): arvore.insert( ( Segment(v[0],u),v,Segment(v[0],w) ) ) else: trap = aux.trap arvore.insert( (Segment(v[0],w),v,trap[2]) ) #insiro esse primeiro para respeitar a ordem correta na arvore(dado que eu escolhi comparar por x do vertice de apoio arvore.insert( (trap[0],v,Segment(v[0],u)) ) diagonais.append( Segment(trap[1][0],v[0]) ) aresta = criaAresta(trap[1],v) Segment(trap[1][0],v[0]).hilight("blue") control.sleep() insereDiagonal(vertices[trap[1][1]-1],vertices[v[1]-1],aresta,faces)
def isEar(n, p, i): p[i].hilight('yellow') control.sleep () p[(i-1)%n].lineto(p[(i+1)%n], 'yellow') control.sleep () ear = isDiagonal(n, p, (i-1)%n, (i+1)%n) p[i].unhilight() p[(i-1)%n].remove_lineto(p[(i+1)%n]) if(ear == True): p[i].hilight('green') control.sleep () return ear
def lp(l): #na arvore, cada trapezio é uma tripla (Segmento,(ponto,indice),Segmento), sendo então trapezio[0] o segmento esquerdo, trapezio[2] o direito e trapezio[1] o vértice de apoio arvore = Arvore() for x in range(len(l)): if(x != len(l)-1): l[x].lineto(l[(x+1)],'red') else: l[x].lineto(l[0],'red') N = len(l) pontos = [] #lista de pontos, juntamente com seus indices originais verticesOrdenados = [] #lista de pontos ordenada diagonais = [] #lista das diagonais que particionam o poligono em poligonos menores monótonos for i in range(N): pontos.append((l[i],i)) verticesOrdenados = sorted(pontos,key=lambda x: (x[0].y,-x[0].x), reverse=True) verticesDCEL = [] arestas = [] arestas2 = [] ### Essa parte monta a face externa na mão for a in range(N): if(a != N-1): ar = Aresta() ar.setAresta(Segment(pontos[a],pontos[a+1])) ar2 = Aresta() ar2.setAresta(Segment(pontos[a+1],pontos[a])) ar.setGemeo(ar2) ar2.setGemeo(ar) arestas.append(ar) arestas2.append(ar2) else: ar = Aresta() ar.setAresta(Segment(pontos[a],pontos[0])) ar2 = Aresta() ar2.setAresta(Segment(pontos[0],pontos[a])) ar.setGemeo(ar2) ar2.setGemeo(ar) arestas.append(ar) arestas2.append(ar2) for k in range(len(arestas)): if(k!= 0 and k!= len(arestas)-1): arestas[k].setProx(arestas[k+1]) arestas[k].setAnt(arestas[k-1]) arestas2[k].setProx(arestas2[k-1]) arestas2[k].setAnt(arestas2[k+1]) elif(k == 0): arestas[k].setProx(arestas[k+1]) arestas[k].setAnt(arestas[len(arestas)-1]) arestas2[k].setProx(arestas2[len(arestas)-1]) arestas2[k].setAnt(arestas2[k+1]) else: arestas[k].setProx(arestas[0]) arestas[k].setAnt(arestas[k-1]) arestas2[k].setProx(arestas2[k-1]) arestas2[k].setAnt(arestas2[0]) ### for a in range(N): v = Vertice(aresta=arestas2[a]) verticesDCEL.append(v) face = Face(arestas2[0]) faces = [] faces.append(face) ############## Esse pedaço verifica se o poligono passado já é estritamente monotono. Se for ele passa a lista de pontos para o algoritmo de triangulação de monótonos monotono = True for i in range(1,N-1): if(pontaParaBaixo(verticesOrdenados[i],pontos) or pontaParaCima(verticesOrdenados[i],pontos)): monotono = False if(monotono == True): triangulaMonotono(faces[0].listaFace()) return 0; ################ for k in range(0,N): verticesOrdenados[k][0].hilight("yellow") if(verticesOrdenados[k][1] == 0): ant = len(l)-1 else: ant = verticesOrdenados[k][1]- 1 if(verticesOrdenados[k][1] == len(l)-1): prox = 0 else: prox = verticesOrdenados[k][1] + 1 pontos[ant][0].hilight("cyan") pontos[prox][0].hilight("green") control.sleep() if( (maisEmBaixoQue(pontos[ant][0],verticesOrdenados[k][0]) and maisEmCimaQue(pontos[prox][0],verticesOrdenados[k][0])) or (maisEmBaixoQue(pontos[prox][0],verticesOrdenados[k][0]) and maisEmCimaQue(pontos[ant][0],verticesOrdenados[k][0])) ):#Caso 1: uma aresta acima e outra embaixo trataCaso1(pontos[ant][0],verticesOrdenados[k],pontos[prox][0],arvore,pontos,verticesDCEL,diagonais,faces) elif(maisEmBaixoQue(pontos[ant][0],verticesOrdenados[k][0])): # Caso 2: as duas arestas abaixo trataCaso2(pontos[ant][0],verticesOrdenados[k],pontos[prox][0],arvore,verticesDCEL,diagonais,faces) else: #Caso 3: as duas arestas em cima trataCaso3(verticesOrdenados[k],arvore,pontos,verticesDCEL,diagonais,faces) verticesOrdenados[k][0].hilight("red") pontos[ant][0].hilight("red") pontos[prox][0].hilight("red") for f in faces: if( f != face ): # se não for a face externa triangulaMonotono(f.listaFace()) for d in diagonais: d.hilight('blue')
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
def triangulaMonotono(l):#Os pontos devem vir em ordem anti-horária pontos = [] #lista com os pontos,juntamente com seus indices verticesOrdenados = [] #lista com os pontos ordenados pilha = [] #pilha usada no algoritmo #diagonais = [] #lista de diagonais da triangulação lado = [] for x in range(len(l)):#desenha poligono if(x != len(l)-1): l[x].lineto(l[(x+1)],'red') else: l[x].lineto(l[0],'red') N = len(l) for i in range(N): pontos.append((l[i],i)) #transforma cada ponto numa dupla (ponto,indice) lado.append(True) ########################################### verticesOrdenados = merge(pontos,lado) ######################################## pilha.append(verticesOrdenados[0]) pilha.append(verticesOrdenados[1]) for i in range(2,N): t = len(pilha) verticesOrdenados[i][0].hilight("yellow") control.sleep() if(verticesOrdenados[i][1] == 0): ant = len(l)-1 else: ant = verticesOrdenados[i][1]-1 if(verticesOrdenados[i][1] == len(l)-1): prox = 0 else: prox = verticesOrdenados[i][1]+1 #aqui pilha[t-1][1] é o St e pilha[0][1] o S1, de acordo com os slides #Caso A ######################## if((ant == pilha[t-1][1] and prox != pilha[0][1]) or (ant != pilha[0][1] and prox == pilha[t-1][1])): #adjacente a St mas nao a S1 if(lado[pilha[t-1][1]] == True): while(t>1 and left_on(pilha[t-1][0],pilha[t-2][0],verticesOrdenados[i][0]) and not (pilha[t-1][0].y == pilha[t-2][0].y and verticesOrdenados[i][0].y == pilha[t-1][0].y )): pilha.pop() t -= 1 d = Segment(verticesOrdenados[i][0],pilha[t-1][0]) d.hilight("blue") control.sleep() elif(t>1): while(t>1 and right_on(pilha[t-1][0],pilha[t-2][0],verticesOrdenados[i][0]) and not (pilha[t-1][0].y == pilha[t-2][0].y and verticesOrdenados[i][0].y == pilha[t-1][0].y )): pilha.pop() t -= 1 d = Segment(verticesOrdenados[i][0],pilha[t-1][0]) d.hilight("blue") control.sleep() pilha.append(verticesOrdenados[i]) #Caso B ######################## if((ant != pilha[t-1][1] and prox == pilha[0][1]) or (ant == pilha[0][1] and prox != pilha[t-1][1])): #adjacente a S1 mas nao a St aux = pilha[t-1] while(t>1): d = Segment(verticesOrdenados[i][0],pilha[t-1][0]) d.hilight("blue") control.sleep() pilha.pop() t -= 1 pilha.pop() pilha.append(aux) pilha.append(verticesOrdenados[i]) #Caso C ######################## if((ant == pilha[t-1][1] and prox == pilha[0][1]) or (ant == pilha[0][1] and prox == pilha[t-1][1])): #adjacente a St e S1 pilha.pop() while(t>2): t -= 1 d = Segment(verticesOrdenados[i][0],pilha[t-1][0]) d.hilight("blue") control.sleep() pilha.pop() verticesOrdenados[i][0].hilight("red")
def triangulaMonotono2(l,diagonais):#Os pontos devem vir em ordem anti-horária pontos = [] #lista com os pontos,juntamente com seus indices verts = [] #lista com os pontos ordenados pilha = [] #pilha usada no algoritmo lado = [] for x in range(len(l)):#desenha poligono if(x != len(l)-1): l[x].lineto(l[(x+1)],'red') else: l[x].lineto(l[0],'red') N = len(l) for i in range(N): pontos.append((l[i],i)) #transforma cada ponto numa dupla (ponto,indice) lado.append(True) ########################################### #Esse pedaço acha o vertice mais alto e o mais baixo e realiza o merge yMax = -20000000 yMin = 2000000 vMax = pontos[0] vMin = pontos[N-1] for i in range(N): if(pontos[i][0].y == yMax and pontos[i][0].x < vMax[0].x): vMax = pontos[i] if(pontos[i][0].y == yMin and pontos[i][0].x > vMin[0].x): vMin = pontos[i] if(pontos[i][0].y > yMax): vMax = pontos[i] yMax = vMax[0].y if(pontos[i][0].y < yMin): vMin = pontos[i] yMin = vMin[0].y if(vMax[1] != N-1):v = pontos[vMax[1]+1] else: v = pontos[0] if(vMax[1]!= 0): i = vMax[1]-1 else: i = N-1 if(vMax[1]!= N-1):j = vMax[1]+1 else: j = 0 lado[vMin[1]] = False if(vMax[1]!= 0): i = vMax[1]-1 else: i = N-1 if(vMax[1]!= N-1):j = vMax[1]+1 else: j = 0 verts.append(vMax); while(len(verts) < N): #Merge if(pontos[j] == vMin): while(pontos[i] != vMin): verts.append(pontos[i]) if(i!=0):i -= 1 else: i = N-1 elif(pontos[i] == vMin): while(pontos[j] != vMin): lado[pontos[j][1]] = False verts.append(pontos[j]) if(j != N-1):j += 1 else: j = 0 if((pontos[j][0].y >= pontos[i][0].y)): lado[pontos[j][1]] = False verts.append(pontos[j]) if(j != N-1): j+= 1 else: j = 0 else: verts.append(pontos[i]) if(i!=0):i -= 1 else: i = N-1 ######################################## #verts = sorted(pontos,key=lambda x: (x[0].y,-x[0].x), reverse=True) print verts pilha.append(verts[0]) pilha.append(verts[1]) for i in range(2,N): t = len(pilha) print "____________________" print pilha verts[i][0].hilight("yellow") control.sleep() if(verts[i][1] == 0): ant = len(l)-1 else: ant = verts[i][1]-1 if(verts[i][1] == len(l)-1): prox = 0 else: prox = verts[i][1]+1 #aqui pilha[t-1][1] é o St e pilha[0][1] o S1, de acordo com os slides #Caso A ######################## if((ant == pilha[t-1][1] and prox != pilha[0][1]) or (ant != pilha[0][1] and prox == pilha[t-1][1])): #adjacente a St mas nao a S1 print "Entrei no caso A" , "no vertice ",verts[i][0] if(lado[pilha[t-1][1]] == True): while(t>1 and left_on(pilha[t-1][0],pilha[t-2][0],verts[i][0]) ): pilha.pop() t -= 1 diagonais.append(Segment(verts[i][0],pilha[t-1][0])) d = Segment(verts[i][0],pilha[t-1][0]) d.hilight("blue") control.sleep() print "Adicionei a diagonal ", d elif(t>1): while(t>1 and right_on(pilha[t-1][0],pilha[t-2][0],verts[i][0])): pilha.pop() t -= 1 diagonais.append(Segment(verts[i][0],pilha[t-1][0])) d = Segment(verts[i][0],pilha[t-1][0]) d.hilight("blue") control.sleep() print "Adicionei a diagonal ", d pilha.append(verts[i]) #Caso B ######################## if((ant != pilha[t-1][1] and prox == pilha[0][1]) or (ant == pilha[0][1] and prox != pilha[t-1][1])): #adjacente a S1 mas nao a St print "Entrei no caso B" , "no vertice ",verts[i][0] aux = pilha[t-1] while(t>1): diagonais.append(Segment(verts[i][0],pilha[t-1][0])) d = Segment(verts[i][0],pilha[t-1][0]) d.hilight("blue") control.sleep() print "Adicionei a diagonal ", d pilha.pop() t -= 1 pilha.pop() pilha.append(aux) pilha.append(verts[i]) #Caso C ######################## if((ant == pilha[t-1][1] and prox == pilha[0][1]) or (ant == pilha[0][1] and prox == pilha[t-1][1])): #adjacente a St e S1 print "Entrei no caso C", "no vertice ",verts[i][0] pilha.pop() while(t>2): t -= 1 diagonais.append(Segment(verts[i][0],pilha[t-1][0])) d = Segment(verts[i][0],pilha[t-1][0]) d.hilight("blue") control.sleep() print "Adicionei a diagonal ", d pilha.pop() verts[i][0].hilight("red") print "--------------------" return diagonais
def blink (p, q): p.hilight () q.hilight () control.sleep () p.unhilight () q.unhilight ()
def triangulaMonotono(l):#Os pontos devem vir em ordem anti-horária pontos = [] #lista com os pontos,juntamente com seus indices verticesOrdenados = [] #lista com os pontos ordenados pilha = [] #pilha usada no algoritmo diagonais = [] #lista de diagonais da triangulação lado = [] for x in range(len(l)):#desenha poligono if(x != len(l)-1): l[x].lineto(l[(x+1)],'red') else: l[x].lineto(l[0],'red') N = len(l) for i in range(N): pontos.append((l[i],i)) #transforma cada ponto numa dupla (ponto,indice) lado.append(True) ##################################### verticesDCEL = [] arestas = [] arestas2 = [] for a in range(N): if(a != N-1): ar = Aresta() ar.setAresta(Segment(pontos[a],pontos[a+1])) ar2 = Aresta() ar2.setAresta(Segment(pontos[a+1],pontos[a])) ar.setGemeo(ar2) ar2.setGemeo(ar) arestas.append(ar) arestas2.append(ar2) else: ar = Aresta() ar.setAresta(Segment(pontos[a],pontos[0])) ar2 = Aresta() ar2.setAresta(Segment(pontos[0],pontos[a])) ar.setGemeo(ar2) ar2.setGemeo(ar) arestas.append(ar) arestas2.append(ar2) for k in range(len(arestas)): if(k!= 0 and k!= len(arestas)-1): arestas[k].setProx(arestas[k+1]) arestas[k].setAnt(arestas[k-1]) arestas2[k].setProx(arestas2[k-1]) arestas2[k].setAnt(arestas2[k+1]) elif(k == 0): arestas[k].setProx(arestas[k+1]) arestas[k].setAnt(arestas[len(arestas)-1]) arestas2[k].setProx(arestas2[len(arestas)-1]) arestas2[k].setAnt(arestas2[k+1]) else: arestas[k].setProx(arestas[0]) arestas[k].setAnt(arestas[k-1]) arestas2[k].setProx(arestas2[k-1]) arestas2[k].setAnt(arestas2[0]) for a in range(N): bla = Vertice(aresta=arestas2[a]) verticesDCEL.append(bla) face = Face(arestas2[0]) faces = [] faces.append(face) ###################################### verticesOrdenados = merge(pontos,lado) ###################################### pilha.append(verticesOrdenados[0]) pilha.append(verticesOrdenados[1]) for i in range(2,N): t = len(pilha) verticesOrdenados[i][0].hilight("yellow") control.sleep() if(verticesOrdenados[i][1] == 0): ant = len(l)-1 else: ant = verticesOrdenados[i][1]-1 if(verticesOrdenados[i][1] == len(l)-1): prox = 0 else: prox = verticesOrdenados[i][1]+1 #aqui pilha[t-1][1] é o St e pilha[0][1] o S1, de acordo com os slides #Caso A ######################## if((ant == pilha[t-1][1] and prox != pilha[0][1]) or (ant != pilha[0][1] and prox == pilha[t-1][1])): #adjacente a St mas nao a S1 if(lado[pilha[t-1][1]] == True): while(t>1 and left_on(pilha[t-1][0],pilha[t-2][0],verticesOrdenados[i][0]) and not (pilha[t-1][0].y == pilha[t-2][0].y and verticesOrdenados[i][0].y == pilha[t-1][0].y )): pilha.pop() t -= 1 d = Segment(verticesOrdenados[i][0],pilha[t-1][0]) d.hilight("green") control.sleep() diagonalASerInserida = criaAresta(verticesOrdenados[i],pilha[t-1]) diagonais.append(diagonalASerInserida) insere(verticesDCEL[verticesOrdenados[i][1]-1],verticesDCEL[pilha[t-1][1]-1],diagonalASerInserida,faces) elif(t>1): while(t>1 and right_on(pilha[t-1][0],pilha[t-2][0],verticesOrdenados[i][0]) and not (pilha[t-1][0].y == pilha[t-2][0].y and verticesOrdenados[i][0].y == pilha[t-1][0].y )): pilha.pop() t -= 1 d = Segment(verticesOrdenados[i][0],pilha[t-1][0]) d.hilight("green") control.sleep() diagonalASerInserida = criaAresta(verticesOrdenados[i],pilha[t-1]) diagonais.append(diagonalASerInserida) insere(verticesDCEL[verticesOrdenados[i][1]-1],verticesDCEL[pilha[t-1][1]-1],diagonalASerInserida,faces) pilha.append(verticesOrdenados[i]) #Caso B ######################## if((ant != pilha[t-1][1] and prox == pilha[0][1]) or (ant == pilha[0][1] and prox != pilha[t-1][1])): #adjacente a S1 mas nao a St aux = pilha[t-1] while(t>1): d = Segment(verticesOrdenados[i][0],pilha[t-1][0]) d.hilight("green") control.sleep() diagonalASerInserida = criaAresta(verticesOrdenados[i],pilha[t-1]) diagonais.append(diagonalASerInserida) insere(verticesDCEL[verticesOrdenados[i][1]-1],verticesDCEL[pilha[t-1][1]-1],diagonalASerInserida,faces) pilha.pop() t -= 1 pilha.pop() pilha.append(aux) pilha.append(verticesOrdenados[i]) #Caso C ######################## if((ant == pilha[t-1][1] and prox == pilha[0][1]) or (ant == pilha[0][1] and prox == pilha[t-1][1])): #adjacente a St e S1 pilha.pop() while(t>2): t -= 1 d = Segment(verticesOrdenados[i][0],pilha[t-1][0]) d.hilight("green") control.sleep() diagonalASerInserida = criaAresta(verticesOrdenados[i],pilha[t-1]) diagonais.append(diagonalASerInserida) insere(verticesDCEL[verticesOrdenados[i][1]-1],verticesDCEL[pilha[t-1][1]-1],diagonalASerInserida,faces) pilha.pop() verticesOrdenados[i][0].hilight("red") for d in diagonais: checaDiagonal(verticesDCEL[d.getAresta().init[1] -1 ],verticesDCEL[d.getAresta().to[1] -1 ],d)
def LeePreparata(p): print "" if(len(p) <= 3): return 0 PlotPolygon(p) n = len(p) t = avl() d = dcel() d.createDCELfromPolygon(p) od = orderedDCEL(d, p[0], n) event = MergeSort(p, range(0, n)) for i in range(0, n): p[event[i]].hilight('yellow') # Caso 2 - Ponta para cima if(upSpike(p, event[i])): node = t.findNode(p[event[i]]) # Caso nao haja trapezio em cima de do ponto evento if(node == None): left = leftEdge(p, event[i], n) trap = trapezoid(p[event[i]], event[i], p[event[i]], p[(event[i]+left)%n], p[event[i]], p[(event[i]-left)%n]) t.insert(trap) control.sleep () # Caso haja um trapezio em cima do ponto evento else: node.value.leo.lineto(node.value.led, 'green') node.value.reo.lineto(node.value.red, 'green') node.value.top.hilight('green') control.sleep () left = leftEdge(p, event[i], n) trap1 = trapezoid(p[event[i]], event[i], node.value.leo, node.value.led, p[event[i]], p[(event[i]+left)%n]) trap2 = trapezoid(p[event[i]], event[i], p[event[i]], p[(event[i]-left)%n], node.value.reo, node.value.red) insertEdgeUsingOd(od, d, event[i], node) print str(od[event[i]][0].origin)+str(od[node.value.topIndex][0].origin) od[event[i]][0].origin.lineto(od[node.value.topIndex][0].origin, 'red') control.sleep () node.value.leo.remove_lineto(node.value.led) node.value.reo.remove_lineto(node.value.red) node.value.top.unhilight() t.remove(p[event[i]]) t.insert(trap2) t.insert(trap1) # Caso 3 - Ponta para baixo elif(downSpike(p, event[i])): node = t.findNode(p[event[i]]) suc = t.sucessor(node) pred = t.predecessor(node) node.value.leo.lineto(node.value.led, 'green') node.value.reo.lineto(node.value.red, 'green') node.value.top.hilight('green') # Caso haja dois trapezios em cima do ponto evento if(suc != None and suc.value.equal(p[event[i]])): suc.value.leo.lineto(suc.value.led, 'cyan') suc.value.reo.lineto(suc.value.red, 'cyan') suc.value.top.hilight('cyan') control.sleep () trap = trapezoid(p[event[i]], event[i], node.value.leo, node.value.led, suc.value.reo, suc.value.red) if(downSpike(p, node.value.topIndex) and abs(event[i]-node.value.topIndex) > 1): insertEdgeUsingOd(od, d, event[i], node) print str(od[event[i]][0].origin)+str(od[node.value.topIndex][0].origin) od[event[i]][0].origin.lineto(od[node.value.topIndex][0].origin, 'red') if(downSpike(p, suc.value.topIndex) and abs(event[i]-suc.value.topIndex) > 1): insertEdgeUsingOd(od, d, event[i], suc) print str(od[event[i]][0].origin)+str(od[suc.value.topIndex][0].origin) od[event[i]][0].origin.lineto(od[suc.value.topIndex][0].origin, 'red') control.sleep () node.value.leo.remove_lineto(node.value.led) node.value.reo.remove_lineto(node.value.red) node.value.top.unhilight() suc.value.leo.remove_lineto(suc.value.led) suc.value.reo.remove_lineto(suc.value.red) suc.value.top.unhilight() t.remove(p[event[i]]) t.remove(p[event[i]]) t.insert(trap) control.sleep () elif(pred != None and pred.value.equal(p[event[i]])): pred.value.leo.lineto(pred.value.led, 'cyan') pred.value.reo.lineto(pred.value.red, 'cyan') pred.value.top.hilight('cyan') control.sleep () trap = trapezoid(p[event[i]], event[i], pred.value.leo, pred.value.led, node.value.reo, node.value.red) if(downSpike(p, node.value.topIndex) and abs(event[i]-node.value.topIndex) > 1): insertEdgeUsingOd(od, d, event[i], node) print str(od[event[i]][0].origin)+str(od[node.value.topIndex][0].origin) od[event[i]][0].origin.lineto(od[node.value.topIndex][0].origin, 'red') if(downSpike(p, pred.value.topIndex) and abs(event[i]-pred.value.topIndex) > 1): insertEdgeUsingOd(od, d, event[i], pred) print str(od[event[i]][0].origin)+str(od[pred.value.topIndex][0].origin) od[event[i]][0].origin.lineto(od[pred.value.topIndex][0].origin, 'red') control.sleep () node.value.leo.remove_lineto(node.value.led) node.value.reo.remove_lineto(node.value.red) node.value.top.unhilight() pred.value.leo.remove_lineto(pred.value.led) pred.value.reo.remove_lineto(pred.value.red) pred.value.top.unhilight() t.remove(p[event[i]]) t.remove(p[event[i]]) t.insert(trap) control.sleep () # Caso so haja um trapezio em cima do ponto evento else: if(downSpike(p, node.value.topIndex) and abs(event[i]-node.value.topIndex) > 1): insertEdgeUsingOd(od, d, event[i], node) print str(od[event[i]][0].origin)+str(od[node.value.topIndex][0].origin) od[event[i]][0].origin.lineto(od[node.value.topIndex][0].origin, 'red') control.sleep () node.value.leo.remove_lineto(node.value.led) node.value.reo.remove_lineto(node.value.red) node.value.top.unhilight() t.remove(p[event[i]]) control.sleep () # Caso 1 - Uma aresta para cima e outra para baixo else: node = t.findNode(p[event[i]]) node.value.leo.lineto(node.value.led, 'green') node.value.reo.lineto(node.value.red, 'green') node.value.top.hilight('green') if(collinear(node.value.leo, node.value.led, p[event[i]])): trap = trapezoid(p[event[i]], event[i], p[event[i]], p[(event[i]+downEdge(p, event[i], n))%n], node.value.reo, node.value.red) else: trap = trapezoid(p[event[i]], event[i], node.value.leo, node.value.led, p[event[i]], p[(event[i]+downEdge(p, event[i], n))%n]) if(downSpike(p, node.value.topIndex) and abs(event[i]-node.value.topIndex) > 1): insertEdgeUsingOd(od, d, event[i], node) print str(od[event[i]][0].origin)+str(od[node.value.topIndex][0].origin) od[event[i]][0].origin.lineto(od[node.value.topIndex][0].origin, 'red') control.sleep () node.value.leo.remove_lineto(node.value.led) node.value.reo.remove_lineto(node.value.red) node.value.top.unhilight() t.remove(p[event[i]]) t.insert(trap) control.sleep () p[event[i]].unhilight() control.sleep () TriangMonotoneUsingDCEL(d) return 0
def IncrProb (l): "Algoritmo incremental probabilistico para encontrar o fecho convexo" if len (l) == 0: return None # Embaralhando o vetor de entrada for i in range (len (l) -1, -1, -1): index = int (random.uniform (0, i+1)) aux = l[i] l[i] = l[index] l[index] = aux # Inicializando alguns campos... for i in range (0, len(l)): l[i].L = [] l[i].interior = 0 # Criando um fecho convexo com 1 ponto fecho = Polygon ([ l[0] ]) fecho.plot () length = 1 k = 0 hi = l[k].hilight () # Como nao posso admitir que os pontos estao em posicao geral, # preciso tomar cuidado ate' conseguir um fecho convexo com # 3 pontos for k in range (1, len (l)): pts = fecho.pts l[k-1].unhilight (hi) hi = l[k].hilight () control.thaw_update () if length == 1: if l[k].x == pts.x and l[k].y == pts.y: continue fecho.hide () pts.next = pts.prev = l[k] l[k].next = l[k].prev = pts fecho.pts = pts fecho.plot () length = length + 1 elif length == 2: next = pts.next dir = area2 (pts, next, l[k]) if dir == 0: #Mais um ponto colinear -> pega o par mais distante fecho.hide () dist_pts_next = dist2 (pts, next) dist_pts_lk = dist2 (pts, l[k]) dist_next_lk = dist2 (next, l[k]) if dist_pts_next >= dist_pts_lk and dist_pts_next >= dist_next_lk: a = pts b = next elif dist_pts_lk >= dist_pts_next and dist_pts_lk >= dist_next_lk: a = pts b = l[k] elif dist_next_lk >= dist_pts_lk and dist_next_lk >= dist_pts_next: a = next b = l[k] else: print('pau!!!') a.next = a.prev = b b.next = b.prev = a fecho.pts = a fecho.plot () continue fecho.hide () # Um ponto /nao/ colinear :) -> tomar cuidado com a # orientacao if dir > 0: pts.prev = next.next = l[k] l[k].next = pts l[k].prev = next else: pts.next = next.prev = l[k] l[k].prev = pts l[k].next = next length = length + 1 fecho.pts = pts fecho.plot () O = classify (fecho, l, k) break # Ja temos um fecho com 3 pontos -> basta cresce-lo for k in range (k+1, len (l)): pts = fecho.pts l[k-1].unhilight (hi) hi = l[k].hilight () control.thaw_update () if l[k].interior: control.sleep () continue l[k].remove_lineto (l[k].intersect) control.sleep () tan = vertices_tangentes (l[k].intersect, l[k]) l[k].intersect.L.remove (l[k]) l0 = [] l1 = [] # atualizando a classificacao dos pontos vertex = tan[0] while vertex != tan[1]: for p in vertex.L: id = p.hilight (config.COLOR_ALT3) p.remove_lineto (p.intersect) if p == l[k]: p.unhilight (id) continue if left (l[k], O, p): if left_on (tan[0], l[k], p): p.interior = 1 p.intersect = None else: p.intersect = tan[0] p.lineto (p.intersect, config.COLOR_ALT1) l0.append (p) else: if left_on (l[k], tan[1], p): p.interior = 1 p.intersect = None else: p.intersect = l[k] p.lineto (p.intersect, config.COLOR_ALT1) l1.append (p) p.unhilight (id) vertex = vertex.next tan[0].L = l0 l[k].L = l1 # atualizando o fecho control.freeze_update () fecho.hide () tan[0].next.prev = None tan[0].next = l[k] l[k].prev = tan[0] if tan[1].prev: tan[1].prev.next = None tan[1].prev = l[k] l[k].next = tan[1] fecho.pts = tan[0] fecho.plot () control.thaw_update () l[k].unhilight (hi) fecho.plot () fecho.extra_info = 'vertices: %d'%len (fecho.to_list ()) return fecho
def TriangMonotoneUsingDCEL(d): for f in range(1, len(d.faces)): if d.faces[f].verified == False: event = generateDecreasingVerticeList(d, f) s = stack() s1 = event[0] s.insert(event[0]) s.insert(event[1]) s1.origin.hilight("cyan") for i in range(2, len(event)): st = s.getTop() staux = s.getTop().origin staux.hilight("green") aux = event[i].origin aux.hilight("yellow") control.sleep() if not Adjacent(event[i], s1) and Adjacent(event[i], st): while s.size > 1 and not Reflex(event[i], st, s.getSecond()): s.remove() st = s.getTop() print (str(event[i].origin) + " " + str(st.origin)) event[i].origin.lineto(st.origin, "red") control.sleep() s.insert(event[i]) staux.unhilight() elif Adjacent(event[i], s1) and not Adjacent(event[i], st): while s.size > 1: print (str(event[i].origin) + " " + str(s.getTop().origin)) event[i].origin.lineto(s.getTop().origin, "red") control.sleep() s.remove() s.remove() s.insert(st) s.insert(event[i]) s1.origin.unhilight() s1 = st staux.unhilight() control.sleep() s1.origin.hilight("cyan") elif Adjacent(event[i], s1) and Adjacent(event[i], st): s.remove() while s.size > 1: print (str(event[i].origin) + " " + str(s.getTop().origin)) event[i].origin.lineto(s.getTop().origin, "red") control.sleep() s.remove() s1.origin.unhilight() staux.unhilight() else: print "wtf" aux.unhilight() control.sleep() return 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
def shamos_hoey(segmentos, estrutura): global cores if len(segmentos) == 0: return None # Abaixo, redefinimos as funcoes de comparacao de segmentos para nosso proposito Segment.__lt__ = lambda s1, s2: prim.compara_segmentos(x_linha_varredura, s1, s2) == -1 Segment.__ge__ = lambda s1, s2: prim.compara_segmentos(x_linha_varredura, s1, s2) >= 0 E = [] # inicializa fila de eventos for i, segmento in enumerate(segmentos): # se e_x > d_x, entao inverte os pontos que determinam o segmento # (pontos da esquerda nao podem ter x-coordenada maior que pontos da direita) if (segmento.init.x > segmento.to.x): segmento.reverse() # tambem inverte se for segmento vertical com inicio (init) com menor y-coordenada do que fim (to) elif (segmento.init.x == segmento.to.x and segmento.init.y < segmento.to.y): segmento.reverse() segmento.id = i segmento.intersected = False # coloca na fila de eventos E E.append(PontoEvento(segmento.init, 'esquerdo', i)) E.append(PontoEvento(segmento.to, 'direito', i)) E.sort() # ordena pontos eventos por x-coordenada global x_linha_varredura pred,suc = None, None for ponto_evento in E: x_linha_varredura = ponto_evento.ponto.x #Remove o destaque da iteracao passada destaca_segs( [pred, suc], 'presente') seg = segmentos[ponto_evento.id_segmento] pred = estrutura.predecessor(seg) suc = estrutura.sucessor(seg) #Destaca os segmentos que serao analisados destaca_segs( [pred, suc], 'vizinho') if ponto_evento.tipo == 'esquerdo': destaca_segs([seg], 'presente') estrutura.insere(seg) if pred != None: if prim.inter(seg,pred) == True: # Detectou interseccao do seg com o pred destaca_segs([seg,pred], 'intersectado') seg.intersected, pred.intersected = True, True break if suc != None: if prim.inter(seg,suc) == True: # Detectou interseccao do seg com o suc destaca_segs([seg,suc], 'intersectado') seg.intersected, suc.intersected = True, True break elif ponto_evento.tipo == 'direito': destaca_segs([seg], 'passado') estrutura.remove(seg) if (pred != None and suc != None): if prim.inter(pred,suc) == True: # Detectou interseccao do pred com o suc destaca_segs([pred,suc], 'intersectado') pred.intersected, suc.intersected = True, True break linha_varredura_plotada_id = control.gui.plot_vert_line (x_linha_varredura, config.COLOR_LINE_SPECIAL, 1) # plota a linha de varredura control.sleep() # dorme control.gui.plot_delete(linha_varredura_plotada_id) # desplota a linha de varredura if estrutura.__class__.__name__ == 'Skiplist': ret = Segment() # pequeno hack, porque resolvemos um problema de decisão, e não temos nada (nenhum polígono, por exemplo) para retornar # e para o algoritmo de Skip List queremos devolver essa informacao extra abaixo ret.extra_info = 'SL: p = ' + str(estrutura.p) + ' nivelmax = ' + str(estrutura.maxnivel) + ' (media de niveis = ' + str( (estrutura.somaniveis / (2*len(segmentos)))) + ')' return ret
def Brute(p): print "" if(len(p) <= 3): return 0 PlotPolygon(p) n = len(p) ear = findAllEars(n, p) while(n > 3): i = 0 while ( not ear[i] ): i = i+1 aux = p[i] p[i].unhilight() p[i].hilight('cyan') control.sleep () if(ear[(i-1)%n]): p[(i-1)%n].unhilight() if(ear[(i+1)%n]): p[(i+1)%n].unhilight() p[(i-1)%n].lineto(p[(i+1)%n], 'red') control.sleep () control.sleep () v2 = p[i] v1 = p[(i-1)%n] v3 = p[(i+1)%n] p.pop(i) ear.pop(i) n = n - 1 indv1 = (i-1)%n indv3 = i%n ear[indv1] = isEar(n, p, indv1) control.sleep () ear[indv3] = isEar(n, p, indv3) control.sleep () aux.unhilight() control.sleep() print(str(v1)+" "+str(v3)) for i in range(0, 3): if(ear[i] == True): p[i].unhilight() return 0;
def __update(self): control.thaw_update() control.update() control.freeze_update() control.sleep()
def lp2(l): #na arvore, cada trapezio é uma tripla (Segmento,(ponto,indice),Segmento), sendo então trapezio[0] o segmento esquerdo, trapezio[2] o direito e trapezio[1] o vértice de apoio arvore = Arvore() for x in range(len(l)): if(x != len(l)-1): l[x].lineto(l[(x+1)],'red') else: l[x].lineto(l[0],'red') N = len(l) pontos = [] #lista de pontos, juntamente com seus indices originais verts = [] #lista de pontos ordenada diagonais = [] #lista das diagonais que particionam o poligono em poligonos menores monótonos for i in range(N): pontos.append((l[i],i)) verts = sorted(pontos,key=lambda x: (x[0].y,-x[0].x), reverse=True) aux = [] arestas = [] arestas2 = [] for a in range(N): if(a != N-1): ar = Aresta() ar.setAresta(Segment(pontos[a],pontos[a+1])) ar2 = Aresta() ar2.setAresta(Segment(pontos[a+1],pontos[a])) ar.setGemeo(ar2) ar2.setGemeo(ar) arestas.append(ar) arestas2.append(ar2) else: ar = Aresta() ar.setAresta(Segment(pontos[a],pontos[0])) ar2 = Aresta() ar2.setAresta(Segment(pontos[0],pontos[a])) ar.setGemeo(ar2) ar2.setGemeo(ar) arestas.append(ar) arestas2.append(ar2) for k in range(len(arestas)): if(k!= 0 and k!= len(arestas)-1): arestas[k].setProx(arestas[k+1]) arestas[k].setAnt(arestas[k-1]) arestas2[k].setProx(arestas2[k-1]) arestas2[k].setAnt(arestas2[k+1]) elif(k == 0): arestas[k].setProx(arestas[k+1]) arestas[k].setAnt(arestas[len(arestas)-1]) arestas2[k].setProx(arestas2[len(arestas)-1]) arestas2[k].setAnt(arestas2[k+1]) else: arestas[k].setProx(arestas[0]) arestas[k].setAnt(arestas[k-1]) arestas2[k].setProx(arestas2[k-1]) arestas2[k].setAnt(arestas2[0]) for a in range(N): bla = Vertice(aresta=arestas2[a]) aux.append(bla) face = Face(arestas2[0]) faces = [] faces.append(face) ############## Esse pedaço verifica se o poligono passado já é monotono. Se for ele passa a lista de pontos para o algoritmo de triangulação de monótonos #monotono = True #for i in range(1,N-1): # if(pontaParaBaixo(verts[i],pontos) or pontaParaCima(verts[i],pontos)): # monotono = False #if(monotono == True): # triangulaMonotono(faces[0].listaFace()) # return 0; ################ for k in range(0,N): verts[k][0].hilight("yellow") if(verts[k][1] == 0): ant = len(l)-1 else: ant = verts[k][1]-1 if(verts[k][1] == len(l)-1): prox = 0 else: prox = verts[k][1] +1 pontos[ant][0].hilight("blue") pontos[prox][0].hilight("green") control.sleep() if( (pontos[ant][0].y <= verts[k][0].y and verts[k][0].y < pontos[prox][0].y) or (pontos[prox][0].y <= verts[k][0].y and verts[k][0].y < pontos[ant][0].y) ): #Caso 1: uma aresta acima e outra embaixo print "ENTREI NO CASO 1 NO VÉRTICE ", verts[k][0] trataCaso1(pontos[ant][0],verts[k],pontos[prox][0],arvore,pontos,aux,diagonais,faces) elif(pontos[ant][0].y <= verts[k][0].y): #Caso 2: as duas arestas embaixo print "ENTREI NO CASO 2 NO VÉRTICE ",verts[k][0] trataCaso2(pontos[ant][0],verts[k],pontos[prox][0],arvore,aux,diagonais,faces) else: #Caso 3: as duas arestas em cima print "ENTREI NO CASO 3 NO VÉRTICE ", verts[k][0] trataCaso3(verts[k],arvore,pontos,aux,diagonais,faces) verts[k][0].hilight("red") pontos[ant][0].hilight("red") pontos[prox][0].hilight("red") for bla in faces: if( bla != face ): triangulaMonotono2(bla.listaFace(),diagonais) for d in diagonais: d.hilight('blue') return diagonais
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
def Graham (l): "Algoritmo de Graham para achar o fecho convexo de uma lista l de pontos" if len (l) == 0: return None # So um ponto foi passado. Retorna um fecho c/ apenas um ponto if len (l) == 1: ret = Polygon (l) ret.plot () ret.extra_info = 'vertices: 1' return ret p0 = l[0] # acha o ponto mais baixo for i in range (1, len(l)): if l[i].y < p0.y: p0 = l[i] elif l[i].y == p0.y: if l[i].x > p0.x: p0 = l[i] l.remove (p0) def cmp (x, y, z = p0): """Funcao para ordenar os pontos ao redor de z Usada com a funcao sort, ordena os pontos de uma lista de acordo com o angulo que cada ponto forma com o ponto z e a reta horizontal. Em caso de empate, o ponto mais distante aparece primeiro.""" area = area2 (z, x, y) if area > 0: return -1 elif area < 0: return 1 else: dist_z_x = dist2 (z, x) dist_z_y = dist2 (z, y) if dist_z_y < dist_z_x: return -1 return dist_z_y > dist_z_x # Ordena os pontos pelo seus angulos l.sort (cmp) # eliminando pontos colineares l2 = [ l[0] ] for i in range (1, len (l)): if collinear (p0, l[i-1], l[i]): continue l2.append (l[i]) l = l2 # So sobraram dois pontos -> retorna fecho c/ os dois if len (l) < 2: ret = Polygon ( [ p0, l[0] ] ) ret.plot () ret.extra_info = 'vertices: 2' return ret pilha = [ p0, l[0], l[1] ] p0.lineto (l[0]) l[0].lineto (l[1]) control.sleep () for i in range (2, len(l)): l[i].hilight () pilha[-1].lineto (l[i]) control.sleep () while not left (pilha[-2], pilha[-1], l[i]): pilha[-2].remove_lineto (pilha[-1]) pilha[-1].remove_lineto (l[i]) pilha.pop () pilha[-1].lineto (l[i]) control.sleep () pilha.append (l[i]) l[i].unhilight () pilha[-1].lineto (pilha[0]) for i in range (0, len(pilha)-1): pilha[i].remove_lineto (pilha[i+1]) pilha[-1].remove_lineto (pilha[0]) poligono = Polygon (pilha) poligono.plot () control.thaw_update () poligono.extra_info = 'vertices: %d'%len (poligono.to_list ()) return poligono
def verticesVisiveis(p, poligs): pontos = [] for i in range(len(poligs)): pontos.extend(poligs[i].to_list()) compara = criaCompara(p) #Intersecta p.x -> inf+ T = Tree(); pontos.sort(key = cmp_to_key(compara), reverse = True) for i in range(len(poligs)): listaPs = poligs[i].to_list() n = len(listaPs) for j in range(n): a = listaPs[j]; b = listaPs[(j+1)%n]; if(passaEixoX(a, b, p)): if(left_on(p,b,a)): T.insert(Segment(a,b)); else: T.insert(Segment(b,a)); W = []; for i in range(len(pontos)): a = pontos[i] idBranco = p.lineto(a, 'white') a.hilight('yellow') control.sleep() a.hilight('red') a.unhilight() if(visivel(T, pontos, p, i)): if(a is not p): W.append(a) p.remove_lineto(a, idBranco) p.lineto(a, 'blue') else: continue; else: p.remove_lineto(a, idBranco) b = a.prev; c = a.next; if( a.x == b.x and a.y == b.y): continue #a não está em um #polígono if(left_on(p,a,b)): T.delete(Segment(b,a)) if(left_on(p,a,c)): T.delete(Segment(c,a)) else: T.insert(Segment(a,c)) #else do primeiro if #Tentando evitar q na hora da inserção tenha segmentos terminando #na linha de varredura. if(right(p,a,b)): T.insert(Segment(a,b)) return W