void fix_peripheral_orientations( Triangulation *manifold) { Tetrahedron *tet; VertexIndex v; FaceIndex f; Cusp *cusp; /* * This function should get called only for orientable manifolds. */ if (manifold->orientability != oriented_manifold && manifold->orientability != oriented_orbifold) uFatalError("fix_peripheral_orientations", "orient"); /* * Compute the intersection number of the meridian and longitude. */ copy_curves_to_scratch(manifold, 0, FALSE); copy_curves_to_scratch(manifold, 1, FALSE); compute_intersection_numbers(manifold); /* * Reverse the meridian on cusps with intersection_number[L][M] == -1. */ /* which Tetrahedron */ for (tet = manifold->tet_list_begin.next; tet != &manifold->tet_list_end; tet = tet->next) /* which ideal vertex */ for (v = 0; v < 4; v++) if (tet->cusp[v]->intersection_number[L][M] == -1) /* which side of the vertex */ for (f = 0; f < 4; f++) if (v != f) { tet->curve[M][right_handed][v][f] = - tet->curve[M][right_handed][v][f]; if (tet->curve[M][left_handed][v][f] != 0.0 || tet->curve[L][left_handed][v][f] != 0.0) uFatalError("fix_peripheral_orientations", "orient"); } /* * When we reverse the meridian we must also negate the meridional * Dehn filling coefficient in order to maintain the same (oriented) * Dehn filling curve as before. However, this Dehn filling curve * will wind clockwise around the core geodesics, relative to * the global orientation on the manifold (because the global * orientation disagrees with the local orientation we had been using * on the nonorientable manifold's torus cusp). This forces a whole * new solution to be found to the gluing equations. To avoid this, * we reverse the direction of the Dehn filling curve (i.e. we * negate both the m and l coefficients). The net effect is that * we negate the l coefficient. * * This reversal of the Dehn filling curve is not really * necessary, and could be eliminated if it's ever causes problems. */ for (cusp = manifold->cusp_list_begin.next; cusp != &manifold->cusp_list_end; cusp = cusp->next) if (cusp->intersection_number[L][M] == -1) cusp->l = - cusp->l; }
static void compute_cusp_map( Triangulation *manifold0, Triangulation *manifold1, Isometry *isometry) { Tetrahedron *tet; VertexIndex v; int i; /* * Copy the manifold1's peripheral curves into * scratch_curves[0], and copy the images of manifold0's * peripheral curves into scratch_curves[1]. * * When the manifold is orientable and the Isometry is * orientation-reversing, and sometimes when the manifold * is nonorientable, the images of the peripheral curves * of a torus will lie on the "wrong" sheet of the Cusp's * orientation double cover. (See peripheral_curves.c for * background material.) Therefore we copy the images of * the peripheral curves of torus cusps to both sheets of * the orientation double cover, to guarantee that the * intersection numbers come out right. */ copy_curves_to_scratch(manifold1, 0, FALSE); copy_images_to_scratch(manifold0, 1, TRUE); /* * Compute the intersection numbers of the images of manifold0's * peripheral curves with manifold1's peripheral curves.. */ compute_intersection_numbers(manifold1); /* * Now extract the cusp_maps from the linking numbers. * * There's a lot of redundancy in this loop, but a trivial * computation so the redundancy hardly matters. * * Ignore negatively indexed Cusps -- they're finite vertices. */ for (tet = manifold0->tet_list_begin.next; tet != &manifold0->tet_list_end; tet = tet->next) for (v = 0; v < 4; v++) if (tet->cusp[v]->index >= 0) for (i = 0; i < 2; i++) /* i = M, L */ { isometry->cusp_map[tet->cusp[v]->index][M][i] = + tet->image->cusp[EVALUATE(tet->map, v)]->intersection_number[L][i]; isometry->cusp_map[tet->cusp[v]->index][L][i] = - tet->image->cusp[EVALUATE(tet->map, v)]->intersection_number[M][i]; } }
static void adjust_Klein_cusp_orientations( Triangulation *manifold) { /* * As explained at the top of this file, a Cusp's peripheral curves * live in the its orientation double cover. When I first wrote this * file, I didn't worry about the orientation of peripheral curves * in nonorientable manifolds. Subsequently it became clear that * they should have the standard orientation relative to the Cusp's * (oriented, not just orientable) orientation double cover. In * the case of a torus Cusp, the peripheral curves live in one * (arbitrarily chosen) component of the orientation double cover; * in the case of a Klein bottle Cusp, the orientation double cover * is connected. * * Fortunately, it's very easy to check whether the peripheral curves * have the standard orientation, and to correct them if necessary. * The definition of the standard orientation for peripheral curves on * a torus is that when the fingers of your right hand point in the * direction of the meridian and your thumb points in the direction * of the longitude, the palm of your hand should face the cusp and * the back of your hand should face the fat part of the manifold. * Combining this with the definition of the intersection number * found at the top of intersection_numbers.c reveals that the * intersection number of the longitude and the meridian (in that * order) should be +1. If it happens to be -1, we must reverse * the meridian. */ /* * If the manifold is oriented, then the peripheral curves will * already have the correct orientation. In fact, they will lie * on the right handed sheet of the Cusp's orientation double * cover, relative to the orientation of the manifold. */ if (manifold->orientability == oriented_manifold) return; /* * The scratch curves might already be in use, so let's make * a copy of whatever's there. */ backup_scratch_curves(manifold); /* * Copy the peripheral curves to both sets of scratch_curve fields. */ copy_curves_to_scratch(manifold, 0, FALSE); copy_curves_to_scratch(manifold, 1, FALSE); /* * Compute their intersection numbers. */ compute_intersection_numbers(manifold); /* * Restore whatever used to be in the scratch_curves. */ restore_scratch_curves(manifold); /* * On Cusps where the intersection number of the longitude and * meridian is -1, reverse the meridian. */ reverse_meridians_where_necessary(manifold); }