예제 #1
0
def boundary_cycles_from_surface(tri, angle, surface, tet_vert_coorientations = None):
    """ 
    Takes a carried surface. For each cusp of tri, look at the boundary curve
    of the surface on the boundary torus for that cusp. Push it up slightly, record 
    which faces of tri it goes through.
    """

    if tet_vert_coorientations == None:
        tet_vert_coorientations = is_transverse_taut(tri, angle, return_type = "tet_vert_coorientations")
    # set up output vectors
    out = []
    for vertex in tri.faces(0):  # 0 is the dimension of the face, so this is cusps
        out.append([0] * tri.countFaces(2))

    edge_sides = edge_side_face_collections(tri, angle, tet_vert_coorientations = tet_vert_coorientations)

    face_coorientations = convert_tetrahedron_coorientations_to_faces(tri, tet_vert_coorientations)

    for f in tri.faces(2):
        weight = surface[f.index()]  # this should be an integer. :)
        for vert_num in range(3):
            cusp_index = f.face(0, vert_num).index()

            sgn = face_coorientations[f.index()]
            trailing_vert_num = (vert_num + sgn) % 3
            trailing_edge = f.face(1, trailing_vert_num) 
            leading_vert_num = (vert_num - sgn) % 3
            leading_edge = f.face(1, leading_vert_num) 
            # these are with respect to right hand rule on surface as viewed from above
            # the faces above us on the trailing edge get -weight, 
            # the faces above us on the leading edge get +weight.

            left, right = edge_sides[trailing_edge.index()]
            pair = (f.index(), trailing_vert_num)
            if pair in left:
                side = left
            else:
                assert pair in right
                side = right
            above = side[side.index(pair) + 1:]
            for (f_ind, vert) in above:
                out[cusp_index][f_ind] -= weight

            left, right = edge_sides[leading_edge.index()]
            pair = (f.index(), leading_vert_num)
            if pair in left:
                side = left
            else:
                assert pair in right
                side = right
            above = side[side.index(pair) + 1:]
            for (f_ind, vert) in above:
                out[cusp_index][f_ind] += weight
    return out
예제 #2
0
def edge_equation_matrix_taut(triangulation, angle_struct):
    """
    For each edge, find the face numbers on either side of the pis,
    put +1 for one side and -1 for the other.
    """
    matrix = []

    edge_sides = edge_side_face_collections(triangulation, angle_struct)
    for left_faces, right_faces in edge_sides:
        row = [0] * triangulation.countTriangles()
        for (face_num, vert) in left_faces:
            row[face_num] = row[face_num] + 1
        for (face_num, vert) in right_faces:
            row[face_num] = row[face_num] - 1
        matrix.append(row)
    return matrix
예제 #3
0
def pairing_of_faces_across_an_edge(tri,
                                    angle,
                                    weights,
                                    edge_index,
                                    tet_vert_coorientations=None):
    """
    given a solution to the system of branch equations gives a pairing of faces across an edge (together with the index of the edge in that face)
    """

    if tet_vert_coorientations == None:
        tet_vert_coorientations = is_transverse_taut(
            tri, angle, return_type="tet_vert_coorientations")

    edge_sides = edge_side_face_collections(
        tri, angle,
        tet_vert_coorientations=tet_vert_coorientations)[edge_index]

    side0 = edge_sides[0]
    for i in range(len(side0)):
        face_index = side0[i][0]
        weight = weights[face_index]
        side0[i] = [
            side0[i], weight
        ]  #first replace side_collections into weighted_side_collections

    sum_of_weights0 = sum(weight for [_, weight] in side0)

    side0_nonzero_weights = []
    for x in side0:
        for k in range(x[1]):
            side0_nonzero_weights.append(x[0])

    side1 = edge_sides[1]
    for i in range(len(side1)):
        face_index = side1[i][0]
        weight = weights[face_index]
        side1[i] = [side1[i], weight]

    sum_of_weights1 = sum(weight for [_, weight] in side1)
    assert sum_of_weights0 == sum_of_weights1

    side1_nonzero_weights = []
    for x in side1:
        for k in range(x[1]):
            side1_nonzero_weights.append(x[0])

    return ([side0_nonzero_weights, side1_nonzero_weights])
예제 #4
0
def appears_twice_on_the_same_side(tri,
                                   angle,
                                   face_index,
                                   edge_index,
                                   tet_vert_coorientations=None):
    """
    tells if a face is attached twice on the same side of an edge (if so, then lowermost and uppermost)
    """

    if tet_vert_coorientations == None:
        tet_vert_coorientations = is_transverse_taut(
            tri, angle, return_type="tet_vert_coorientations")

    edge_sides = edge_side_face_collections(
        tri, angle,
        tet_vert_coorientations=tet_vert_coorientations)[edge_index]
    side0 = edge_sides[0]
    side1 = edge_sides[1]

    return side0[0][0] == side0[-1][0] and side0[-1][0] == face_index or side1[
        0][0] == side1[-1][0] and side1[-1][0] == face_index
예제 #5
0
def is_uppermost(tri,
                 angle,
                 face_index,
                 edge_index_in_face,
                 edge_index,
                 tet_vert_coorientations=None):
    """
    tells if (face_index, edge_index_in_face) is uppermost for that edge
    """

    if tet_vert_coorientations == None:
        tet_vert_coorientations = is_transverse_taut(
            tri, angle, return_type="tet_vert_coorientations")

    edge_sides = edge_side_face_collections(
        tri, angle,
        tet_vert_coorientations=tet_vert_coorientations)[edge_index]
    side0 = edge_sides[0]
    side1 = edge_sides[1]

    return (side0[-1] == (face_index, edge_index_in_face)
            or side1[-1] == (face_index, edge_index_in_face))
예제 #6
0
def where_faces_are_uppermost(tri, angle, tet_vert_coorientations=None):
    """
    returns a list whose ith elements is the index of the edge where the ith face is uppermost
    """
    if tet_vert_coorientations == None:
        tet_vert_coorientations = is_transverse_taut(
            tri, angle, return_type="tet_vert_coorientations")

    n = tri.countTetrahedra()

    where_uppermost = [None] * 2 * n
    sides = edge_side_face_collections(tri, angle, tet_vert_coorientations)
    for edge in tri.edges():
        uppermost0_index = sides[edge.index()][0][-1][0]
        where_uppermost[uppermost0_index] = edge.index()
        uppermost1_index = sides[edge.index()][1][-1][0]
        where_uppermost[uppermost1_index] = edge.index()

    for x in where_uppermost:
        assert x != None

    return where_uppermost
예제 #7
0
def make_continent_drill_flow_cycle(veering_isosig, flow_cycle, num_steps):
    tri, angle = isosig_to_tri_angle(veering_isosig)
    vt = veering_triangulation(tri, angle)  #, tet_shapes = tet_shapes)
    ### format for loops: it is a list of tuples,
    ### each tuple is (tet_index, edge_index within this tet that we exit through)
    tet_0 = flow_cycle[0][0]
    face_0 = 0  ### only used for initial numbering of vertices of the continent, so who cares
    initial_tet_face = tet_face(vt,
                                tet_0,
                                face_0,
                                verts_pos=[None, None, None, None])
    con = continent(vt, initial_tet_face)

    side_face_collections, side_tet_collections = edge_side_face_collections(
        vt.tri,
        vt.angle,
        tet_vert_coorientations=vt.coorientations,
        return_tets=True,
        order_bottom_to_top=False)
    # print('sfc', side_face_collections)
    # print('stc', side_tet_collections)
    ### identify the next edge in the cycle

    init_tetrahedron = con.tetrahedra[0]
    init_edge = flow_edge_in_continent(init_tetrahedron, flow_cycle[0][1])

    flow_tetrahedra = [init_tetrahedron]
    flow_edges = [init_edge]
    ### both in the continent

    upwards_flow_index = 0
    downwards_flow_index = 0
    for i in range(num_steps):
        # print(i)
        if i % 2 == 0:  ### go up
            edge = flow_edges[-1]
            last_tet = None
            while True:
                con.update_boundary()
                upper_boundary_triangles = [
                    t for t in edge.boundary_triangles if t.is_upper
                ]
                if len(upper_boundary_triangles) == 0:
                    break  ## out of while loop
                last_tet = con.bury(upper_boundary_triangles[0])
            assert last_tet != None
            upwards_flow_index = (upwards_flow_index + 1) % len(flow_cycle)
            assert last_tet.index == flow_cycle[upwards_flow_index][0]
            flow_tetrahedra.append(last_tet)
            flow_edges.append(
                flow_edge_in_continent(last_tet,
                                       flow_cycle[upwards_flow_index][1]))
            con.make_convex(
            )  ### could this take us further up dual_cycle? We don't think so
        else:  ### go down
            tet = flow_tetrahedra[0]
            edge = tet.lower_edge()
            flow_edges = [edge] + flow_edges
            ### now build the continent to get new_lowest_tet
            manifold_edge = tri.edge(edge.index)
            downwards_flow_index = (downwards_flow_index - 1) % len(flow_cycle)
            ### is the flow cycle vertical through the tetrahedron?
            tet_below = get_tet_above_edge(
                vt.tri,
                vt.angle,
                manifold_edge,
                tet_vert_coorientations=vt.coorientations,
                get_tet_below_edge=True)
            tet_below_num = tet_below.index()
            top_vert_nums = get_tet_top_vert_nums(vt.coorientations,
                                                  tet_below_num)
            top_edge_num = vert_pair_to_edge_num[tuple(top_vert_nums)]

            if (tet_below_num, top_edge_num) == flow_cycle[
                    downwards_flow_index]:  ### flow cycle went straight up
                while True:
                    con.update_boundary()
                    lower_boundary_triangles = [
                        t for t in edge.boundary_triangles if not t.is_upper
                    ]
                    if len(lower_boundary_triangles) == 0:
                        break  ## out of while loop
                    last_tet = con.bury(lower_boundary_triangles[0])
            else:
                ### find which side of the edge our tet is in
                # print('edge index', edge.index)
                side_tet_collections_at_edge = side_tet_collections[
                    edge.index]  ## index in the manifold
                side_face_collections_at_edge = side_face_collections[
                    edge.index]
                downward_path = None
                flow_step = flow_cycle[downwards_flow_index]
                for i, side_tet_collection in enumerate(
                        side_tet_collections_at_edge):
                    if flow_step in side_tet_collection:
                        downward_path = side_tet_collection[:
                                                            side_tet_collection
                                                            .index(flow_step) +
                                                            1]
                        downward_path_faces = side_face_collections_at_edge[
                            i][:side_tet_collection.index(flow_step) + 1]
                assert downward_path != None
                for j, (tet_num, edge_num) in enumerate(downward_path):
                    con.update_boundary()
                    lower_boundary_triangles = [
                        t for t in edge.boundary_triangles if not t.is_upper
                        and t.index == downward_path_faces[j][0]
                    ]
                    assert len(lower_boundary_triangles) == 1
                    last_tet = con.bury(lower_boundary_triangles[0])
            assert last_tet != None
            flow_tetrahedra = [last_tet] + flow_tetrahedra
            con.make_convex(
            )  ### could this take us further down dual_cycle? We don't think so

    con.update_boundary()
    return con, flow_tetrahedra, flow_edges