Esempio n. 1
0
	def set_relation(self, first_edge, second_edge):
		def match_edges(first_edge, second_edge):
			are_polygons_equivalent = \
				match_polygons(
					first_edge.polygon,
					second_edge.polygon,
					self.__equivalence_distance
				)
				
			if are_polygons_equivalent:
				are_edges_equivalent = \
					first_edge.first_vertex_index \
						== second_edge.first_vertex_index
						
				are_edges_equivalent &= \
					first_edge.second_vertex_index \
						== second_edge.second_vertex_index
			else:
				are_edges_equivalent = False
				
				
			return are_edges_equivalent
			
			
			
		first_polygon_record_index, first_polygon_record = \
			self.__get_polygon_record(
				first_edge.polygon
			)
			
		second_polygon_record_index, second_polygon_record = \
			self.__get_polygon_record(
				second_edge.polygon
			)
			
			
		# Поверхность должна содержать полигоны эквивалентные полигонам ребер
		# с точностью до self.__equivalence_distance. В противном случае
		# хотя бы одна запись полигонов не будет найдена
		if (first_polygon_record is None) or (second_polygon_record is None):
			raise Exception() #!!!!!
			
		# Полигоны ребер не дожны быть эквивалентны одному из полигонов
		# поверхности одновременно (нельзя допускать связей полигона с самим
		# собой). В противном случае индексы будут равны
		if first_polygon_record_index == second_polygon_record_index:
			raise Exception() #!!!!!
			
			
		first_polygon      = first_polygon_record['polygon']
		first_edge         = self.__map_edge(first_edge, first_polygon)
		first_relations    = first_polygon_record['relations']
		first_relation_key = \
			first_edge.first_vertex_index, \
				first_edge.second_vertex_index
				
		first_related_edge = first_relations.get(first_relation_key)
		
		
		second_polygon      = second_polygon_record['polygon']
		second_edge         = self.__map_edge(second_edge, second_polygon)
		second_relations    = second_polygon_record['relations']
		second_relation_key = \
			second_edge.first_vertex_index, \
				second_edge.second_vertex_index
				
		second_related_edge = second_relations.get(second_relation_key)
		
		
		if first_related_edge is not None:
			if second_related_edge is not None:
				are_edges_equivalent = \
					match_edges(
						first_related_edge,
						second_related_edge
					)
					
				if not are_edges_equivalent:
					raise Exception() #!!!!!
			else:
				raise Exception() #!!!!!
		else:
			if second_related_edge is not None:
				raise Exception() #!!!!!
			else:
				first_relations[first_relation_key]       = second_edge
				first_relations[first_relation_key[::-1]] = \
					invert_edge(
						second_edge
					)
					
				second_relations[second_relation_key]       = first_edge
				second_relations[second_relation_key[::-1]] = \
					invert_edge(
						first_edge
					)
def build_surface(csv_file, equivalence_distance):
	surface  = Surface(equivalence_distance)
	polygons = []
	
	
	
	vertices_pattern = \
		compile(
			'\(\s*' \
				+ '(-?[0-9]+(?:\.[0-9]+)?(?:[eE]-?[0-9]+)?)\s*,\s*' \
				+ '(-?[0-9]+(?:\.[0-9]+)?(?:[eE]-?[0-9]+)?)\s*,\s*' \
				+ '(-?[0-9]+(?:\.[0-9]+)?(?:[eE]-?[0-9]+)?)' \
				+ '\s*\)'
		)
		
	relation_pattern = \
		compile(
			'\(\s*' \
				+ '([0-9]+)\s*,\s*([0-9]+)\s*:\s*([0-9]+)' \
				+ '\s*\)'
		)
		
		
	def get_polygon(vertices_record, impassibility_record):
		def get_vertex(vertex_record):
			coordinates = \
				[float(coordinate_record) for coordinate_record \
					in vertex_record]
					
			return coordinates
			
		vertices = \
			[get_vertex(vertex_record) for vertex_record \
				in vertices_pattern.findall(vertices_record)]
				
				
		# impassibility_record = impassibility_record.strip()
		# impassibility_record = impassibility_record.lower()
		
		# if impassibility_record == 'infinity':
		impassibility = float(impassibility_record)
		
		
		polygon = \
			Polygon(
				vertices,
				impassibility
			)
			
		return polygon
		
		
	def get_relations(polygon, relations_record):
		def get_relation(relation_record):
			def get_edge(polygon, edge_number):
				if edge_number < polygon.vertices_number - 1:
					edge = Edge(polygon, edge_number, edge_number + 1)
				else:
					edge = Edge(polygon, edge_number, 0)
					
				return edge
				
				
			first_polygon_edge_number  = int(relation_record[0])
			second_polygon_number      = int(relation_record[1])
			second_polygon_edge_number = int(relation_record[2])
			
			first_edge  = get_edge(polygon, first_polygon_edge_number)
			second_edge = \
				get_edge(
					polygons[second_polygon_number],
					second_polygon_edge_number
				)
				
				
			return first_edge, second_edge
			
			
		relations = \
			[get_relation(relation_record) for relation_record \
				in relation_pattern.findall(relations_record)]
				
		return relations
		
		
		
	#!!!!! Обрабатывать исключения в случае ошибки файла
	csv_file_reader = reader(csv_file, delimiter = ';')
	
	for csv_record_index, csv_record in enumerate(csv_file_reader):
		vertices_record      = csv_record[0]
		relations_record     = csv_record[1]
		impassibility_record = csv_record[2]
		
		polygon   = get_polygon(vertices_record, impassibility_record)
		relations = get_relations(polygon, relations_record)
		
		
		surface.add_polygon(polygon, csv_record_index)
		
		for first_edge, second_edge in relations:
			surface.set_relation(first_edge, invert_edge(second_edge))
			
			
		polygons.append(polygon)
	# try:
	# except:
	# 	raise Exception() #!!!!!
		
		
	return surface