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