def move_2_to_2(cmpx): """ Applies a 2->2 move to the input complex, cmpx. Input must be of type complex22. """ # Declare local constants triangle_size = 3 # The number of veritces in a triangle complex_size = 2 # The complex has 2 triangles number_of_shared_vertices = 2 # The complex has 2 shared vertices number_of_unshared_vertices = 2 # The complex has 2 unshared vertices total_number_of_vertices = 4 # There should be a total of 4 # vertices in the complex. # Extract the triangles. Don't need error checking because if the # complexd is not correct, we won't be able to extract the shared # and unshared vertices. triangles = [sd.triangle.parse_input(t) for t in cmpx.get_triangles()] # Extract the shared_vertices shared_vertices = cmpx.get_shared_vertices() # Extract the unshared vertices unshared_vertices = cmpx.get_unshared_vertices() # Tiny bit of error checking just in caes assert len(triangles) == complex_size assert len(shared_vertices) == number_of_shared_vertices assert len(unshared_vertices) == number_of_unshared_vertices assert len(set(shared_vertices+unshared_vertices)) \ == total_number_of_vertices # The edge shared by the two shared vertices. If it doesn't # exist, something went very wrong! if sd.edge.exists(shared_vertices): shared_edge = sd.edge.exists(shared_vertices)[0] else: raise ValueError("The pair of vertices you gave me are not " + "endpoints of an edge!") # Calculate the vertices for the new triangles new_triangles = [set(unshared_vertices+[s]) for s in shared_vertices \ if len(set(unshared_vertices+[s])) == triangle_size] # Tiny bit of error checking just in case. The number of new # triangles should be the same as the number of old triangles. assert len(new_triangles) == complex_size # Remove the old triangles for t in triangles: sm.remove_triangle(t) # Remove the old edge we no longer need. sm.remove_edge(shared_edge) # With the old geometric constructs out of the way, make the new one! new_triangles = [sm.build_triangle_and_edges(point_list) \ for point_list in new_triangles] # Connect triangles and connect the triangles to their respective edges changed_vertices = shared_vertices + unshared_vertices set_neighbors_and_triangles(changed_vertices,new_triangles) return True
def build_torus_from_data(torus_data): """ ONLY USEFUL AT INITIALIZATION. torus_data means two_torus_point_data should be a lists of sets, each with 6 points in it. """ #First we need to check that torus_data is what we want. for t in torus_data: if not (type(t) == tuple and len(t) == 3): raise TypeError("Torus data need to be a list of tuple," + "each of length 2!") for i in t: if not (type(i) == set and len(i) == 2): raise TypeError("The edges must consists of 2 vertices.") for j in i: if not (type(j) == int and j > 0): raise TypeError("The vertices must all be" + "positive integers!") # The vertices in existence will be the union of the triangle # edge tuples. vertex_ids = ut.tuple_of_set_union(torus_data) # The last used vertex id is the maximum of the vertex ids last_used_vertex_id = max(vertex_ids) # Make sure there are no vertices are missing (print torus to # file should not let there be any) assert set(range(1, last_used_vertex_id + 1)) - vertex_ids == set([]) # Once we're sure the set is what we want, we need to make sure no # torus is currently initialized. sm.delete_all_geometries() # Make the points we need sm.make_n_vertices(last_used_vertex_id) # Ensure the points we made are the points in our list assert set(vertex.instances.keys()) == vertex_ids # Make the triangles we need out of the points. tts_triangle_ids = [sm.build_triangle_and_edges(t) for t in torus_data] # Connect all the triangles and tell points what triangles contain them ! connect_all_triangles() return tts_triangle_ids
def move_3_to_1(cmpx): "Applies a 3->1 move to the input complex, cmpx." # Extract the complex, which contains three triangles. if len(cmpx.get_triangles()) == 3: original_triangles = [sd.triangle.instances[i] \ for i in cmpx.get_triangles()] else: raise ValueError("There should be exactly 3 triangles for the " + "3->1 complex.") # Extract the boundary vertices original_vertices = [set(t.get_vertices()) for t in original_triangles] central_vertex = list(ut.set_intersection(original_vertices))[0] boundary_vertices = ut.set_union(original_vertices) \ - set([central_vertex]) boundary_vertex_ids = [v.get_id() for v in boundary_vertices] # Extract the edges to be removed (there are 3) # Lambda functions for clarity get_edges = lambda i: set(sd.triangle.instances[i].get_edges()) intersected_element = lambda L: ut.only_element(ut.set_intersection(L)) # Nested list comprehensions: take the intersection of the set of # edges associated with pairs of the triangles we care # about. These edges are flagged for deleteion. shared_edges = [intersected_element([get_edges(i) for i in c]) \ for c in ut.k_combinations(cmpx.get_triangles())] # There should only be 3 shared edges. If there are more, we messed up. assert len(shared_edges) == 3 # Make the new triangle new_triangle = sm.build_triangle_and_edges(boundary_vertex_ids) # Clean up for t in original_triangles: # Delete the old triangles: sm.remove_triangle(t) for e in shared_edges: # Delete the old edges. sm.remove_edge(e) sd.vertex.delete(central_vertex) # Delete the old vertex # Set triangles, neihgbors, and check topology set_neighbors_and_triangles(boundary_vertices,[new_triangle]) return True
def build_sphere_from_data(sphere_data): """ sphere_data should be a list of sets, each with 3 points in it. Resets the sphere and then builds it from this data. """ # First we need to check that sphere_data is what we want. for s in sphere_data: if not (type(s) == set and len(s) == 3): raise TypeError("Sphere data needs to be a list of sets, " +"each of length 3!") for i in s: if not (type(i) == int and i > 0): raise TypeError("The vertices must all be " +"positive integers!") # The vertices in existence will be the union of the triangle # point lists: vertex_ids = ut.set_union(sphere_data) # The last used vertex id is the maximum of the vertex ids last_used_vertex_id = max(vertex_ids) # make sure there are no vertices are missing (print sphere to # file shouldn't let there be any) assert set(range(1,last_used_vertex_id+1)) - vertex_ids == set([]) # Once we're sure the set is what we want, we need to make sure no # sphere is currently initialized. sm.delete_all_geometries() # Make the points we need sm.make_n_vertices(last_used_vertex_id) # Ensure the points we made are the points in our list assert set(vertex.instances.keys()) == vertex_ids # Make the triangles we need out of the points. triangle_ids = [sm.build_triangle_and_edges(t) for t in sphere_data] # Connect all the triangles and tell points what triangles contain them connect_all_triangles() return triangle_ids
def move_1_to_3(cmpx): "Applies a 1->3 move to the input complex, cmpx." # Extract the single triangle required for this move. if len(cmpx.get_triangles()) == 1: triangle_id = list(cmpx.get_triangles())[0] else: raise ValueError("There should be only one "+ "triangle for the 1->3 complex.") triangle = sd.triangle.instances[triangle_id] # Vertices original_vertices = triangle.get_vertices() # Edges original_edges = triangle.get_edges() # Endpoints of edges endpoints = [e.get_vertex_ids() for e in original_edges] # Make the point that will trisect the triangle v = sd.vertex() sd.vertex.add(v) # Generate the vertices for the three new triangles to be created vertex_list = [points | set([v.get_id()]) for points in endpoints] # Make the new triangles new_triangles = [sm.build_triangle_and_edges(tri) for tri in vertex_list] # Delete the old triangle sm.remove_triangle(triangle) # Set neighbors, triangles for each vertex, and do some error checking vertex_ids = ut.set_union(vertex_list) vertices = [sd.vertex.instances[i] for i in vertex_ids] set_neighbors_and_triangles(vertices,new_triangles) return True