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)
Example #2
0
def quickhull_rec(P, p, r, point_p, point_r):
    '''Miolo recursivo da função Quickhull. Recebe uma coleção de pontos P, um
    início p e um fim r dados por meio da função partition. Devolve os hulls
    gerados a cada chamada recursiva.'''
    if p == r - 1:
        return [P[r], P[p]]

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

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

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

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

    # junta os hulls e remove uma cópia do q
    for i in range(1, len(hull2)):
        hull.append(hull2[i])
    return hull
Example #3
0
def classify(convex, points, start):
    "Associa cada ponto em points a uma aresta visivel do triangulo convex"

    first = convex.pts
    second = first.next
    third = second.next
    first.L = []
    second.L = []
    third.L = []

    # O e' um ponto dentro do fecho convexo (que ainda e' um triangulo)
    Ox = (first.x + second.x + third.x) / 3.0
    Oy = (first.y + second.y + third.y) / 3.0
    O = Point(Ox, Oy)
    O.hilight(config.COLOR_ALT2)

    for i in range(start, len(points)):
        for p in (first, second, third):
            points[i].interior = 1
            if intersect_restricted(points[i], O, p, p.next):
                p.L.append(points[i])
                points[i].intersect = p
                points[i].interior = 0
                points[i].lineto(p, config.COLOR_ALT1)
                break

    return O
Example #4
0
def eventos (circulos):
    "Função que retorna uma ABBB de pontos-eventos, que são os extremos horizontais dos circulos"
    
    Q = Abbb () # Abbb dos pontos eventos
    
    for c in circulos:
        p_esq = c.center - Point (c.r, 0)
        p_dir = c.center + Point (c.r, 0)
        
        baixo = Node_Semi_Circle (c, True, p_esq)
        cima = Node_Semi_Circle (c, False, p_esq)
        
        p1 = Node_Point_Circle (p_esq, ini = [baixo, cima], fim = [], inter = [], inter_unico = [])
        p2 = Node_Point_Circle (p_dir, ini = [], fim = [baixo, cima], inter = [], inter_unico = [])
        
        no1 = Q.busca (p1)
        no2 = Q.busca (p2)
        
        # Se os pontos já estão inseridos, só atualiza, se não, insere
        if no1.elemento != None:  
            no1.elemento.ini.append (baixo)
            no1.elemento.ini.append (cima)
        else:
            Q.insere (p1)
            p_esq.plot (color = 'red')
            
        if no2.elemento != None:
            no2.elemento.fim.append (baixo)
            no1.elemento.fim.append (cima)
            
        else:
            Q.insere (p2)
            p_dir.plot (color = 'red')
        
    return Q
Example #5
0
def classify (convex, points, start):
	"Associa cada ponto em points a uma aresta visivel do triangulo convex"

	first = convex.pts
	second = first.next
	third = second.next
	first.L = []
	second.L = []
	third.L = []

	# O e' um ponto dentro do fecho convexo (que ainda e' um triangulo)
	Ox = (first.x + second.x + third.x) / 3.0
	Oy = (first.y + second.y + third.y) / 3.0
	O = Point (Ox, Oy)
	O.hilight (config.COLOR_ALT2)

	for i in range (start, len (points)):
		for p in (first, second, third):
			points[i].interior = 1
			if intersect_restricted (points[i], O, p, p.next):
				p.L.append (points[i])
				points[i].intersect = p
				points[i].interior = 0
				points[i].lineto (p, config.COLOR_ALT1)
				break
	
	return O
Example #6
0
File: disc.py Project: pepedrog/BCC
class Disc:
	"Um Disco representado por suas coordenadas cartesianas"

	def __init__ (self, x, y, r):
		"Para criar um ponto, passe suas coordenadas."
		self.center = Point(x, y)
		self.r = r
		self.seg = Segment(Point(x-r, y), Point(x+r,y))
		self.lineto_id = {}

	def __repr__ (self):
		"Retorna uma string da forma '( x, y, r )'"
		return '( ' + repr(self.center.x) + ', ' + repr(self.center.y) + ', ' + repr(self.r) + ' )'

	def plot (self, color = config.COLOR_DISC):
		"Desenha o disco na cor especificada"
		self.plot_id = control.plot_disc_grande (self.center.x, self.center.y, color,
							self.r)
		self.center.plot()
		return self.plot_id

        ################### VICTOR MUDOU  (Edu- talvez n precise disso) #######################

	def unplot(self, id = None):
		if id == None: id = self.plot_id
		control.plot_delete(id)



        ################## FIM ############################

	def hilight (self, color=config.COLOR_HI_POINT):
		"Desenha o disco com 'destaque' (com cor diferente)"
		self.hi = control.plot_disc (self.center.x, self.center.y, color,
						self.r)
		return self.hi
	
	def unhilight (self, id = None):
		"Apaga o 'destaque' do ponto"
		if id == None: id = self.hi
		control.plot_delete (id)
	
	def lineto (self, p, color=config.COLOR_LINE):
		"Desenha uma linha do centro até o ponto especificado"
		self.lineto_id[p] = control.plot_line (self.center.x, self.center.y, p.x, p.y, color)
		return self.lineto_id[p]
	
	def remove_lineto (self, p, id = None):
		"Remove a linha ate o ponto p"
		if id == None: id = self.lineto_id[p]
		control.plot_delete (id)

	def extremes(self):
		
		offsets = [self.r, - self.r]

		return [ self.center + Point(0, off) for off in offsets] + [ self.center + Point(off, 0) for off in offsets] 
	def newEdge(self, x1, y1, x2, y2):
		vertex1 = self.findVertex(x1, y1)
		vertex2 = self.findVertex(x2, y2)
		if (vertex1 != None) and (vertex2 != None):
			self.allEdge.append(Edge(vertex1, vertex2))
			point1 = Point(vertex1.getX(), vertex1.getY())
			point2 = Point(vertex2.getX(), vertex2.getY())
			Printo(Segment(point1, point2))
		else:
			print("Falhou em newEdge -- vertices errados!")
Example #8
0
 def intersection (self, other):
     "Retorna uma lista com o(s) ponto(s) de interseção entre os dois círculos"
     if not self.intersects_circ (other):
         return []
     
     # Um pouco de geometria: Montando a esquação do circulo
     # Temos: self: (x - x1)^2 + (y - y1)^2 = r1^2
     #       other: (x - x2)^2 + (y - y2)^2 = r2^2
     x1, y1 = self.center.x, self.center.y
     x2, y2 = other.center.x, other.center.y
     r1, r2 = self.r, other.r
     
     # Depois de subtrair as duas equações, teremos uma reta
     # 2x*(x2 - x1) + 2y*(y2 - y1) + x1^2 - x2^2 + y1^2 - y2^2 = r1^2 - r2^2
     
     # Isolando o x para a resposta, temos essa grande conta:
     # x = [ r1^2 - r2^2 + x2^2 - x1^2 + y2^2 - x1^2 + 2y*(y2 - y1) ] / 2*(x2 - x1)
     
     # se x1 = x2, temos um caso mais simples, basta encontrar y
     if x1 == x2:
         if y1 == y2:
             # supondo que não há circulos iguais
             return []
         res_y1 = (r1**2 - r2**2 + y2**2 - y1**2) / (2*(y2 - y1))
         res_y2 = res_y1
         res_x1 = (r1**2 - (res_y1 - y1)**2 )**(0.5) + x1
         res_x2 = -(r1**2 - (res_y1 - y1)**2 )**(0.5) + x1
     
     # Se não, temos que colocar o x em alguma das equações dos circulos e criar uma equação de 2º grau
     # Depois de (( muitas )) continhas ... 
     # conclui que os valores de a, b e c para nossa equação ay^2 + by + c = 0 são
     else:
         const = r1**2 - r2**2 + y2**2 - y1**2 + x2**2 + x1**2 - 2*x1*x2 
         
         a = (y1 - y2)**2 / (x1 - x2)**2 + 1
         b = (y1 - y2)*const / (x1 - x2)**2 - 2*y1
         c = const**2 / (4*(x1 - x2)**2) + y1**2 - r1**2
         
         # Agora a gente aplica um super bhaskara
         delta = b**2 - 4*a*c
         res_y1 = (-b + delta**(0.5)) / (2*a)
         res_y2 = (-b - delta**(0.5)) / (2*a)
         
         # Aplica os valores na reta para descobir os x
         res_x1 = ( r1**2 - r2**2 + y2**2 - y1**2 + x2**2 - x1**2 + 2*res_y1*(y1 - y2) ) / (2*(x2 - x1))
         res_x2 = ( r1**2 - r2**2 + y2**2 - y1**2 + x2**2 - x1**2 + 2*res_y2*(y1 - y2) ) / (2*(x2 - x1))
     
     p1 = Point (res_x1, res_y1)
     p2 = Point (res_x2, res_y2)
     if p1.approx_equals (p2):
         return [p1]
     return [p1, p2]
     
 ################### FIM PEDRO ######################################
Example #9
0
def Incremental(list_polygon):

    # Criando e printando o retangulo externo
    oeste = list_polygon[0].pts.x
    leste = list_polygon[0].pts.x
    norte = list_polygon[0].pts.y
    sul = list_polygon[0].pts.y

    for polygon in list_polygon:
        for point in polygon.vertices():
            if point.x < oeste: oeste = point.x
            if point.x > leste: leste = point.x
            if point.y < sul: sul = point.y
            if point.y > norte: norte = point.y

    exterior = []

    exterior.append(Point(oeste - 1, sul - 1))
    exterior.append(Point(leste + 1, sul - 1))
    exterior.append(Point(leste + 1, norte + 1))
    exterior.append(Point(oeste - 1, norte + 1))

    ext = Polygon(exterior)
    Print(ext)

    # Printando os polígonos simples
    for polygon in list_polygon:
        Print(polygon)

    # Parte 1.1 - Transformando os polígonos iniciais em arestas(segmentos de retas)
    lsegments = []
    for polygon in list_polygon:
        foo = Generate(polygon.vertices())
        for x in foo:
            p1 = x.p_left
            p2 = x.p_right
            x.swap = 0

            if p1.x > p2.x or (p1.x == p2.x and p1.y > p2.y):
                x.p_left = p2
                x.p_right = p1
                x.swap = 1
            if len(polygon.vertices()) == 2:
                x.swap = 0
            lsegments.append(x)

    # Parte 1.2 - Criando o mapa de trapezoidação

    print("lsegments size is " + str(len(lsegments)))
    mapa = STrapezoidMap(lsegments)
    mapa.construct()

    return mapa
Example #10
0
def menorAnguloX(v1,v2, w1, w2):
        a = Point(v2.x - v1.x, v2.y - v1.y)
        b = Point(w2.x - w1.x, w2.y - w1.y)
        if((a.y >= 0) != (b.y >= 0)):
                if(a.y >= 0):
                        return -1
                else: 
                        return 1
        else:
                if(left(Point(0,0), a, b)):
                        return -1;
                elif(right(Point(0,0), a, b)):
                        return 1;
                else: return 0;
Example #11
0
def read_segments(filename):
    if filename is None:
        raise ValueError("File name is None")
    with open(filename) as file:
        segments = set()
        for line in file:
            line = line.split()
            if len(line) != 4:
                raise ValueError("Invalid input from file: {}: {}".format(
                    filename, line))
            segments.add(
                Segment(Point(float(line[0]), float(line[1])),
                        Point(float(line[2]), float(line[3]))))
        return segments
Example #12
0
def read_point_link(filename):
    if filename is None:
        raise ValueError("File name is None")
    with open(filename) as file:
        link = {}
        for line in file:
            line = line.split()
            if len(line) != 4:
                raise ValueError("Invalid input from file: {}: {}".format(
                    filename, line))
            key = Point(float(line[0]), float(line[1]))
            adj = Point(float(line[2]), float(line[3]))
            if key not in link:
                link[key] = set()
            link[key].add(adj)
        return link
Example #13
0
 def __gt__ (self, other):
     
     if self.circ == other.circ:
         return self.baixo and not other.baixo
     
     ref = other.ref
     x = self.circ.center.x
     y = self.circ.center.y
     
     # Se o ponto de referencia é uma interseção, 
     if abs((ref.x - x)**2 + (ref.y - y)**2 - self.circ.r**2) < eps:
         # então eu pego um ponto um pouco posterior pra ser o ponto de refencia, 
         # aplicando a formula do circulo pra 2*epsilon pra frente
         if other.baixo:
             sinal = -1
         else:
             sinal = 1
         
         # Formula do circulo
         x_novo = ref.x + 2*eps
         x_novo = min (x_novo, other.circ.center.x + other.circ.r)
         
         y_novo = other.circ.center.y
         y_novo += sinal*(other.circ.r**2 - (x_novo - other.circ.center.x)**2)**0.5
      
         ref = Point (x_novo, y_novo)
         
     # Self > other <=> other está a esquerda do self
     return self.esquerda (ref, other.baixo)
Example #14
0
def read_intersections(filename):
    if filename is None:
        raise ValueError("File name is None")
    with open(filename) as file:
        intersections = {}
        point = None
        for line in file:
            line = line.split()
            if len(line) == 2:
                point = Point(float(line[0]), float(line[1]))
                intersections[point] = set()
            if len(line) == 4:
                intersections[point].add(
                    Segment(Point(float(line[0]), float(line[1])),
                            Point(float(line[2]), float(line[3]))))
        return intersections
Example #15
0
def somaMinkowski(lista1, lista2):
        n = len(lista1); m = len(lista2);
        #l1 e l2 serão as listas deslocadas de forma que
        #o primeiro ponto tenha coordenada minima dentre os
        #pontos do polígono
        
        pmin = lista1[0]
        imin = 0
        for i in range(len(lista1)):
                p = lista1[i]
                if(p.y < pmin.y):
                        pmin = p
                        imin = i
                elif(p.y == pmin.y and p.x < pmin.x):
                        pmin = p
                        imin = i
        l1 = shift(lista1, imin)
        
        pmin = lista2[0]
        imin = 0
        for i in range(len(lista2)):
                p = lista2[i]
                if(p.y < pmin.y):
                        pmin = p
                        imin = i
                elif(p.y == pmin.y and p.x < pmin.x):
                        pmin = p
                        imin = i
        l2 = shift(lista2, imin)

        # adicionando sentinelas...

        l2.append(l2[0]); l2.append(l2[1]);
        l1.append(l1[0]); l1.append(l1[1]);


        i = 0; j = 0;
        soma = []
        while True:
                soma.append(Point(l1[i].x + l2[j].x, l1[i].y + l2[j].y))
                

                ### condições de parada
                if(i == n):
                        j = j + 1
                elif(j == m):
                        i = i + 1
                #####

                elif(menorAnguloX(l1[i],l1[i+1],l2[j],l2[j+1]) == -1): 
                        i = i + 1
                elif(menorAnguloX(l1[i],l1[i+1],l2[j],l2[j+1]) == 1): 
                        j = j + 1
                else:
                        i = i + 1
                        j = j + 1
                if(i == n and j == m): break;
        
        return soma
Example #16
0
def Brute(list_polygon):

    #####################################################################################################

    "Coloque aqui o ponto que o robô está e o ponto que o robô quer ir, respectivamente."
    "O primeiro argumento é o x do ponto e o segundo é o y do ponto"

    box = Box_Box()

    print(box.sx, box.sy, box.ex, box.ey)

    start = SPoint(int(box.sx), int(box.sy))
    target = SPoint(int(box.ex), int(box.ey))
    #####################################################################################################

    mapa = Incremental(list_polygon)

    # Parte 1.3 - Removendo as extensões vérticais dentro dos polígonos
    mapa.checking()

    # Achando o grafo de locomoção

    startTrap = mapa.query(mapa.node_list[0], start)
    targetTrap = mapa.query(mapa.node_list[0], target)

    # Parte 2.1 - Transformando em grafo
    grafo = mapa.make_graph()

    #start = Point(0, 0)
    grafo.newVertex(start.x, start.y)
    #target = Point(10, 10)
    grafo.newVertex(target.x, target.y)

    grafo.newEdge(start.x, start.y,
                  startTrap.info.center().x,
                  startTrap.info.center().y)
    grafo.newEdge(target.x, target.y,
                  targetTrap.info.center().x,
                  targetTrap.info.center().y)

    Print_S_and_T(Point(start.x, start.y))
    Print_S_and_T(Point(target.x, target.y))

    grafo.DFS(grafo.findVertex(target.x, target.y),
              grafo.findVertex(start.x, start.y))
    '''
Example #17
0
def read_points(filename):
    with open(filename) as file:
        points = set()
        for line in file:
            line = line.split()
            if len(line) != 2:
                raise ValueError("Invalid input from file: {}: {}".format(
                    filename, line))
            points.add(Point(float(line[0]), float(line[1])))
        return points
Example #18
0
def Bentley_Ottmann (l):
    
    L = Abbb () # Linha de varredura
    resp = [] # Os nós com os pontos de interseção que retornaremos
    
    # Pré-processamento - Transforma cada circulo em pontos-eventos
    # pontos é a ABBB de pontos eventos
    pontos = eventos (l)
    control.sleep()
    
    while not pontos.vazia():
        p = pontos.deleta_min()
        # desenha a linha
        id_linha = control.plot_vert_line (p.ponto.x)
        id_evento = p.ponto.hilight()
        control.sleep()
        
        "------------------------- Pontos da esquerda --------------------------------"
        for seg in p.ini:
            seg.seg.plot ("green")
            control.sleep()
            insere_na_linha (L, seg, pontos, p.ponto.x)
         
        "------------------------- Pontos de interseção ------------------------------"
        if len (p.inter) > 0 or (len (p.ini) + len (p.fim) > 1):
            p.ponto.hilight('yellow')
            resp.append (p)
            
        # Troca a ordem dos segmentos (do p.inter[])
        trocados = []
        # Remove todos
        for seg in p.inter:
            seg.ref = Point (p.ponto.x - 10*eps, ((seg.seg.to.x*seg.seg.init.y) -
                                                 (seg.seg.init.x*seg.seg.to.y) -
                                                 (p.ponto.x - 10*eps)*(seg.seg.init.y - seg.seg.to.y)) / 
                                                 (seg.seg.to.x - seg.seg.init.x))
            trocados.append (seg)
            L.deleta (seg)
        # Insere denovo com o novo ponto de referencia
        for seg in trocados:
            seg.ref = p.ponto
            #print("reinserindo " + str(seg))
            insere_na_linha (L, seg, pontos, p.ponto.x, trocados)
        
        "------------------------- Pontos da direita --------------------------------"
        for seg in p.fim:
            deleta_da_linha (L, seg, pontos, p.ponto.x)
            
        # apaga a linha
        control.plot_delete (id_linha)    
        control.plot_delete (id_evento)
        p.ponto.unplot()

    return resp
def angle_from_origin(origin_point: Point, test_point: Point) -> float:
    ''' Returns the angle, in radians, of the test point
        from the origin point, sweeping like a clock, starting from
        the right and working counter-clockwise, just like
        the sine/cosine unit cicle.
    '''
    # shifts so that the origin point is at 0,0
    shifted_test_point = Point(test_point.x - origin_point.x,
                               test_point.y - origin_point.y)
    angle = math.atan2(shifted_test_point.y, shifted_test_point.x)
    return angle if angle >= 0 else angle + 2 * math.pi
Example #20
0
def Generate(l):
    # Dado a lista de pontos do poligono e gera todos os segmentos de retas
    lsegments = []
    n = len(l)
    if (n == 2):
        lsegments.append(
            SSegment(SPoint(l[0].x, l[0].y), SPoint(l[1].x, l[1].y)))
        seg = Segment(Point(l[0].x, l[0].y), Point(l[1].x, l[1].y))
        seg.plot('green')
        control.sleep()
    else:
        for i in range(n):
            lsegments.append(
                SSegment(SPoint(l[i % n].x, l[i % n].y),
                         SPoint(l[(i + 1) % n].x, l[(i + 1) % n].y)))
            seg = Segment(Point(l[i % n].x, l[i % n].y),
                          Point(l[(i + 1) % n].x, l[(i + 1) % n].y))
            seg.plot('green')
            control.sleep()
    return lsegments
Example #21
0
    def desenha (self):
        cima = self.sup.y
        baixo = max (self.a_esq.to.y, self.a_dir.to.y)
        
        # Acha os dois pontos da esquerda
        x1, y1 = self.a_esq.init.x, self.a_esq.init.y
        x2, y2 = self.a_esq.to.x, self.a_esq.to.y
        cima_esq = Point ((x2*y1 - x1*y2 + cima*(x1 - x2))/(y1 - y2), cima)
        baixo_esq = Point ((x2*y1 - x1*y2 + baixo*(x1 - x2))/(y1 - y2), baixo)

        # Acha os dois pontos da direita
        x1, y1 = self.a_dir.init.x, self.a_dir.init.y
        x2, y2 = self.a_dir.to.x, self.a_dir.to.y
        cima_dir = Point ((x2*y1 - x1*y2 + cima*(x1 - x2))/(y1 - y2), cima)
        baixo_dir = Point ((x2*y1 - x1*y2 + baixo*(x1 - x2))/(y1 - y2), baixo)
        
        self.aresta_cima = (Segment (cima_esq, cima_dir)).plot('green')
        self.aresta_baixo = (Segment (baixo_esq, baixo_dir)).plot('green')
        self.aresta_esq = (Segment (baixo_esq, cima_esq)).plot('green')
        self.aresta_dir = (Segment (baixo_dir, cima_dir)).plot('green')
Example #22
0
def pontos_infinitos(p):
    " Devolve três pontos fictícios tais que o triangulo formado por eles "
    " contém todos os pontos de p "

    # Vou montar um quadradão que contém todos os pontos
    cima = baixo = direito = esquerdo = p[0]
    for i in range(1, len(p)):
        if p[i].y > cima.y: cima = p[i]
        if p[i].y < baixo.y: baixo = p[i]
        if p[i].x < esquerdo.x: esquerdo = p[i]
        if p[i].x > direito.x: direito = p[i]

    # Agora monto um triângulão que contém esse quadrado
    p1 = Point(esquerdo.x - 10 * (direito.x - esquerdo.x),
               baixo.y - 10 * (cima.y - baixo.y))
    p2 = Point(esquerdo.x + (direito.x - esquerdo.x) / 2,
               cima.y + 10 * (cima.y - baixo.y))
    p3 = Point(esquerdo.x + 10 * (direito.x - esquerdo.x),
               baixo.y - 10 * (cima.y - baixo.y))
    return p1, p2, p3
Example #23
0
def intersection_point(s1, s2):
    x1, y1 = s1.init.x, s1.init.y
    x2, y2 = s1.to.x, s1.to.y
    x3, y3 = s2.init.x, s2.init.y
    x4, y4 = s2.to.x, s2.to.y
    if vertical(s1):
        x = s1.init.x
        m2 = (y4 - y3) / (x4 - x3)
        y = m2 * (x - x3) + y3
        p = Point(x, y)
        return p
    if vertical(s2):
        x = s2.init.x
        m1 = (y2 - y1) / (x2 - x1)
        y = m1 * (x - x1) + y1
        p = Point(x, y)
        return p
    m1 = (y2 - y1) / (x2 - x1)
    m2 = (y4 - y3) / (x4 - x3)
    x = (m1 * x1 - m2 * x3 - y1 + y3) / (m1 - m2)
    y = m1 * x + (-m1 * x1 + y1)

    p = Point(x, y)
    return p
Example #24
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
Example #25
0
def read_polygons(filename):
    if filename is None:
        raise ValueError("File name is None")
    with open(filename) as file:
        polygons = []
        vertices = []
        for line in file:
            line = line.split()
            if len(line) == 0:
                polygons.append(Polygon(vertices))
                vertices = []
                continue
            if len(line) != 2:
                raise ValueError("Invalid input from file: {}: {}".format(
                    filename, line))
            vertices.append(Point(float(line[0]), float(line[1])))
        polygons.append(Polygon(vertices))
        return polygons
Example #26
0
def read(filename):
    """Reads any type of geometric primitive data structures (Point,
    Polygon, Segment) from a file and returns it as a list.

    This method reads geometric data from a file. Any empty line or
    any line started by '#' (considered  a commentary) is ignored.
    The input can be mixed, it can contains a set of Polygons, Points
    and Segments and not necessarily only one type of data.

    The following patterns are required during the input operation:

    Point: defined by two floating point coordinates, on a line,
           separated by whitespaces. For example:

               0 0
               0.5 1.5
               1.5 3

    Polygon: defined by a list of adjacent points, enclosed by '['
             at the beginning and ']' at the end, in the order that
             they appear in the polygon boundary, i.e., any pair of
             consecutive points defines an edge on the polygon
             boundary. For example, the following input defines a
             square:

             [
             0 0
             1 0
             1 1
             0 1
             ]

    Segment: defined by four floating point coordinates, on a line,
             separated by whitespaces. Each pair of consecutive
             coordinates defines a segment endpoint. For example,
             the following input defines a segment from (0, 0) to
             (0.5, 1.5):

             0 0 0.5 1.5

     Disc: Atualmente, ele espera que o arquivo contenha uma lista de
           discos, um disco por linha, as 3 coordenadas em cada linha
           (x, y, r). Exemplo:
    
            0 0 0
            0 1 2
            10 100 50

    :param filename: (str) The name of the file that will be read

    :return: (list) A list of geometric primitive data structures
             read from the file

    Raises:
        FileNotFoundError: if file could not be found

        TypeError: if 'filename' is None

        ValueError: if some input from the file does not follow the
                    required patterns

    """
    with open(filename) as file:
        i = 0
        vertices = []
        data = []
        expecting_polygon = False
        for line in file:
            i += 1
            line = line.split()
            if len(line) == 0 or line[0] == "#":
                continue
            if line[0] == "[":
                expecting_polygon = True
            elif line[0] == "]":
                expecting_polygon = False
                data.append(Polygon(vertices))
                vertices = []
            elif len(line) == 3:
                data.append(Disc(float(line[0]), float(line[1]), float(line[2])))
            elif len(line) == 4:
                data.append(
                    Segment(
                        Point(float(line[0]), float(line[1])),
                        Point(float(line[2]), float(line[3]))
                    )
                )
            elif len(line) == 2:
                if expecting_polygon:
                    vertices.append(Point(float(line[0]), float(line[1])))
                else:
                    data.append(Point(float(line[0]), float(line[1])))
            else:
                raise ValueError(
                    "Invalid input from file: {}: line: {}: {}".format(filename, i, line))
        return data
Example #27
0
def pre_process(points):
    global DG, dcel, root
    shuffle(points)
    inside = []
    not_inside = [i for i in range(len(points))]
    min_x = min_y = float('inf')
    max_x = max_y = -float('inf')
    for i, pt in enumerate(points):
        if pt.x < min_x: min_x = pt.x
        if pt.x > max_x: max_x = pt.x
        if pt.y > max_y: max_y = pt.y
        if pt.y < min_y: min_y = pt.y
        points[i] = Point(pt[0], pt[1])
    mid_hor = (max_x + min_x) / 2.0  #fixed
    left_hor = mid_hor - (max_x - min_x) * 0.75  #fixed
    hor_fact = (max_x - min_x)  #variable
    mid_ver = (max_y + min_y) / 2.0  #fixed
    len_ver = (max_y - min_y)  #variable
    node = None
    while (len(not_inside) > 0):
        node = Node(
            Point(left_hor, mid_ver + len_ver),  #top left
            Point(left_hor, mid_ver - len_ver),  #bottom left
            Point(mid_hor + hor_fact, mid_ver))  #center right
        for i in range(len(not_inside)):
            if node.contains_proper(points[not_inside[i]]) or\
                    node.is_on_edge(points[not_inside[i]]):
                inside.append(i)
        for ind in reversed(inside):
            not_inside.pop(ind)
        inside = []
        hor_fact *= 1.15
        len_ver *= 1.5
    DG = nx.DiGraph()
    dcel = DCEL()
    root = node
    DG.add_node(root)
    vtcs = root.get_vertices()

    ext1 = hedge(vtcs[1], vtcs[0])
    ext2 = hedge(vtcs[0], vtcs[2])
    ext3 = hedge(vtcs[2], vtcs[1])
    int1 = hedge(vtcs[0], vtcs[1])
    int2 = hedge(vtcs[2], vtcs[0])
    int3 = hedge(vtcs[1], vtcs[2])

    ext1.next = ext2
    ext1.prev = ext3
    ext1.twin = int1
    ext2.next = ext3
    ext2.prev = ext1
    ext2.twin = int2
    ext3.next = ext1
    ext3.prev = ext2
    ext3.twin = int3

    int1.next = int3
    int1.prev = int2
    int1.twin = ext1
    int1.face = root
    int2.next = int1
    int2.prev = int3
    int2.twin = ext2
    int2.face = root
    int3.next = int2
    int3.prev = int1
    int3.twin = ext3
    int3.face = root

    dcel.add_hedge(ext1)
    dcel.add_hedge(ext2)
    dcel.add_hedge(ext3)
    dcel.add_hedge(int1)
    dcel.add_hedge(int2)
    dcel.add_hedge(int3)
Example #28
0
class Disc:
    "Um Disco representado por suas coordenadas cartesianas"

    def __init__ (self, x, y, r):
        "Para criar um disco, passe suas coordenadas."
        self.center = Point(x, y)
        self.r = r
        self.seg = Segment(Point(x-r, y), Point(x+r,y))
        self.lineto_id = {}

    def __repr__ (self):
        "Retorna uma string da forma '( x, y, r )'"
        return '( ' + repr(self.center.x) + ', ' + repr(self.center.y) + ', ' + repr(self.r) + ' )'

    def plot (self, color = config.COLOR_DISC):
        "Desenha o disco na cor especificada"
        self.plot_id = control.plot_disc_grande (self.center.x, self.center.y, color,
                            self.r)
        self.center.plot()
        return self.plot_id

        ################### VICTOR MUDOU  (Edu- talvez n precise disso) #######################

    def unplot(self, id = None):
        if id == None: id = self.plot_id
        control.plot_delete(id)



        ################## FIM ############################

    def hilight (self, color=config.COLOR_HI_POINT):
        "Desenha o disco com 'destaque' (com cor diferente)"
        self.hi = control.plot_disc (self.center.x, self.center.y, color,
                        self.r)
        return self.hi
    
    def unhilight (self, id = None):
        "Apaga o 'destaque' do disco"
        if id == None: id = self.hi
        control.plot_delete (id)
    
    def lineto (self, p, color=config.COLOR_LINE):
        "Desenha uma linha do centro até o ponto especificado"
        self.lineto_id[p] = control.plot_line (self.center.x, self.center.y, p.x, p.y, color)
        return self.lineto_id[p]
    
    def remove_lineto (self, p, id = None):
        "Remove a linha ate o ponto p"
        if id == None: id = self.lineto_id[p]
        control.plot_delete (id)

    def extremes(self):
        
        offsets = [self.r, - self.r]

        return [ self.center + Point(0, off) for off in offsets] + [ self.center + Point(off, 0) for off in offsets]
    
    ################ PEDRO GF MUDOU ##########################################
    
    def hilight_circ (self, color = "yellow", width = 2):
        "Desenha a circunferência (contorno) com destaque"
        self.circ_id = control.plot_circle (self.center.x, self.center.y, color, self.r, width = width)
        return self.circ_id
    
    def unhilight_circ (self, id = None):
        "Apaga o destaque da circunferência (contorno)"
        if id == None: id = self.circ_id
        control.plot_delete (id)
    
    def hilight_semi_circle (self, up, color="red", width = 2):
        "Desenha o meio circulo, up indica se é a metade de cima ou de baixo"
        if up:
            self.id_semi_up = control.plot_semi_circle (self.center.x, self.center.y, self.r, up, color, width = width)
            return self.id_semi_up
        self.id_semi_down = control.plot_semi_circle (self.center.x, self.center.y, self.r, up, color, width = width)
        return self.id_semi_down
    
    def unhilight_semi_circle (self, up):
        "Apaga o semi_circulo"
        if up:
            return control.plot_delete (self.id_semi_up)
        return control.plot_delete (self.id_semi_down)
    
    def intersects_circ (self, other):
        "Confere se a circunferência do disco intersecta com a circunferência do other"
        d = (prim.dist2 (self.center, other.center))**0.5
        sum_r = self.r + other.r
        
        # Deixa o menor no self
        if self.r > other.r:
            self, other = other, self
            
        # Confere se o menor não está dentro do maior
        if d + self.r < other.r:
            return False
        
        # Confere se os discos se intersectam
        if d <= sum_r and d :
            return True
        else:
            return False
    
    def intersection (self, other):
        "Retorna uma lista com o(s) ponto(s) de interseção entre os dois círculos"
        if not self.intersects_circ (other):
            return []
        
        # Um pouco de geometria: Montando a esquação do circulo
        # Temos: self: (x - x1)^2 + (y - y1)^2 = r1^2
        #       other: (x - x2)^2 + (y - y2)^2 = r2^2
        x1, y1 = self.center.x, self.center.y
        x2, y2 = other.center.x, other.center.y
        r1, r2 = self.r, other.r
        
        # Depois de subtrair as duas equações, teremos uma reta
        # 2x*(x2 - x1) + 2y*(y2 - y1) + x1^2 - x2^2 + y1^2 - y2^2 = r1^2 - r2^2
        
        # Isolando o x para a resposta, temos essa grande conta:
        # x = [ r1^2 - r2^2 + x2^2 - x1^2 + y2^2 - x1^2 + 2y*(y2 - y1) ] / 2*(x2 - x1)
        
        # se x1 = x2, temos um caso mais simples, basta encontrar y
        if x1 == x2:
            if y1 == y2:
                # supondo que não há circulos iguais
                return []
            res_y1 = (r1**2 - r2**2 + y2**2 - y1**2) / (2*(y2 - y1))
            res_y2 = res_y1
            res_x1 = (r1**2 - (res_y1 - y1)**2 )**(0.5) + x1
            res_x2 = -(r1**2 - (res_y1 - y1)**2 )**(0.5) + x1
        
        # Se não, temos que colocar o x em alguma das equações dos circulos e criar uma equação de 2º grau
        # Depois de (( muitas )) continhas ... 
        # conclui que os valores de a, b e c para nossa equação ay^2 + by + c = 0 são
        else:
            const = r1**2 - r2**2 + y2**2 - y1**2 + x2**2 + x1**2 - 2*x1*x2 
            
            a = (y1 - y2)**2 / (x1 - x2)**2 + 1
            b = (y1 - y2)*const / (x1 - x2)**2 - 2*y1
            c = const**2 / (4*(x1 - x2)**2) + y1**2 - r1**2
            
            # Agora a gente aplica um super bhaskara
            delta = b**2 - 4*a*c
            res_y1 = (-b + delta**(0.5)) / (2*a)
            res_y2 = (-b - delta**(0.5)) / (2*a)
            
            # Aplica os valores na reta para descobir os x
            res_x1 = ( r1**2 - r2**2 + y2**2 - y1**2 + x2**2 - x1**2 + 2*res_y1*(y1 - y2) ) / (2*(x2 - x1))
            res_x2 = ( r1**2 - r2**2 + y2**2 - y1**2 + x2**2 - x1**2 + 2*res_y2*(y1 - y2) ) / (2*(x2 - x1))
        
        p1 = Point (res_x1, res_y1)
        p2 = Point (res_x2, res_y2)
        if p1.approx_equals (p2):
            return [p1]
        return [p1, p2]
        
    ################### FIM PEDRO ######################################
Example #29
0
    def extremes(self):
        
        offsets = [self.r, - self.r]

        return [ self.center + Point(0, off) for off in offsets] + [ self.center + Point(off, 0) for off in offsets]
Example #30
0
def visGraphAlg(l):
	print "HUE"
	poligs = leEntrada(l)

	robo = poligs[0]
	if(len(robo) == 1):
		print "Robo ponto na posicao ", robo[0] 
		probo = robo[0]
	else:
		print "Busca de rotas para robos não pontuais não implementado ainda"




def leEntrada(l):
	poligs = []
	temp = []
	for i in range(len(l)):
		if( len(temp) == 0 ): 
			temp.append(l[i])
		elif( l[i].x == temp[0].x and l[i].y == temp[0].y ):
			poligs.append(temp)
			temp = []
		else:
			temp.append(l[i])
	return poligs

pontos = [Point(-2,-2),Point(-2,-2),Point(0,0),Point(1,1),Point(2,0),Point(-1,-1),Point(0,0)]
visGraphAlg(pontos)
	
Example #31
0
 def __init__ (self, x, y, r):
     "Para criar um disco, passe suas coordenadas."
     self.center = Point(x, y)
     self.r = r
     self.seg = Segment(Point(x-r, y), Point(x+r,y))
     self.lineto_id = {}