예제 #1
0
파일: orient.c 프로젝트: DamianHeard/orb
void reorient(
	Triangulation	*manifold)
{
	Tetrahedron	*tet;

	for (tet = manifold->tet_list_begin.next;
		 tet != &manifold->tet_list_end;
		 tet = tet->next)

		reverse_orientation(tet);


	if (manifold->orientability == oriented_manifold)
	{
		/*
		 *	The peripheral curves haven't gone anywhere,
		 *	but the sheets they are on are now considered
		 *	the left_handed sheets rather than the right_handed
		 *	sheets.  So transfer them to what used to be the
		 *	left_handed sheets but are now the right_handed sheets.
		 */
		transfer_peripheral_curves(manifold);

		/*
		 *	To adhere to the orientation conventions for peripheral curves
		 *	(see the documentation at the top of peripheral_curves.c)
		 *	we must reverse the directions of all meridians.
		 *
		 *	Note that it was the act of transferring the peripheral curves
		 *	from the left_handed to right_handed sheets -- note the reversal
		 *	of the Tetrahedra -- that caused the violation of the orientaiton
		 *	convention.  In particular, curves in nonorientable manifold, even
		 *	on (double covers of) Klein bottle cusps, still respect the convention.
		 */
		reverse_all_meridians(manifold);

		/*
		 *	Adjust the edge orientations, too.
		 */
		make_all_edge_orientations_right_handed(manifold);
	}

	/*
	 *	The Chern-Simons invariant of the manifold will be negated,
	 *	and the fudge factor will be different.
	 */
	if (manifold->CS_value_is_known)
	{
		manifold->CS_value[ultimate]	= - manifold->CS_value[ultimate];
		manifold->CS_value[penultimate]	= - manifold->CS_value[penultimate];
	}
	compute_CS_fudge_from_value(manifold);
}
예제 #2
0
FuncResult proto_canonize(
    Triangulation   *manifold)
{
    /*
     *  95/10/12  JRW
     *  I added the needs_polishing flag so that the solution will be
     *  polished iff it needs to be.  In the past this was no big deal,
     *  but now we want the cusp neighborhoods module to be able to
     *  maintain a canonical triangulation in real time.  If no changes
     *  need to be made and all cusps are complete (so we don't have to
     *  worry about restoring the filled solution), we want to get out
     *  of here as quickly as possible.
     */

    Boolean all_done,
            needs_polishing;
    int     num_attempts, i;

    num_attempts = 0;
    needs_polishing = FALSE;

    do
    {
        /*
         *  First make sure that a hyperbolic structure is present, and
         *  all Tetrahedra are positively oriented.  Overwrite the filled
         *  structure with the complete one.
         */

        if (manifold->solution_type[complete] == geometric_solution
         && all_cusps_are_complete(manifold) == TRUE)
        {
            /*
             *  This is the express route.
             *
             *  No polishing will be required if the triangulation is
             *  already canonical, because the hyperbolic structure won't
             *  change and there is no need to restore the filled solution.
             */
        }
        else
        {
            /*
             *  This is the generic algorithm.
             *
             *  (validate_hyperbolic_structure() overwrites the filled
             *  solution with the complete solution.)
             */
            if (validate_hyperbolic_structure(manifold) == func_failed)
            {
                compute_CS_fudge_from_value(manifold);
                return func_failed;
            }
            needs_polishing = TRUE;
        }

        /*
         *  Choose cusp cross sections bounding equal volumes,
         *  and use the Tilt Theorem to compute the tilts.
         *  (See "Convex hulls..." for details.)
         */

        allocate_cross_sections(manifold);
        compute_cross_sections(manifold);
        compute_tilts(manifold);

        /*
         *  Keep going through the following loop as long as we
         *  continue to keep improving the triangulation.
         *  Do not perform any operation (i.e. any two_to_three()
         *  move) that would create negatively oriented Tetrahedra.
	 *
	 *  It is possible to get into an infinite loop here, doing an 
	 *  endless series of 2->3 and 3->2 moves, presumably 
	 *  do to numerical instability.  Thus the total number of
	 *  moves is capped. 
         */

        for(i = 0; i < MAX_MOVES*manifold->num_tetrahedra; i++)
        {
            /*
             *  Cancel pairs of Tetrahedra sharing an EdgeClass
             *  of order two.  (Since the Triangulation contains
             *  no negatively oriented Tetrahedra, Tetrahedra sharing
             *  an EdgeClass of order two will be within epsilon of
             *  being flat.)
             */
            if (attempt_cancellation(manifold) == TRUE)
            {
                needs_polishing = TRUE;
                continue;
            }

            /*
             *  Perform 3-2 moves whereever necessary.
             */
            if (attempt_three_to_two(manifold) == TRUE)
            {
                needs_polishing = TRUE;
                continue;
            }

            /*
             *  Perform 2-3 moves whereever necessary.
             */
            if (attempt_two_to_three(manifold) == TRUE)
            {
                needs_polishing = TRUE;
                continue;
            }

            /*
             *  We can't make any more progress.
             *  Break out of the loop, and then check whether we've
             *  really found a subdivision of the canonical cell
             *  decomposition, or whether we've had the misfortune to
             *  get stuck on (potential) negatively oriented Tetrahedra.
             */
            break;
        }

        /*
         *  We don't need the VertexCrossSections any more, so
         *  we might as well get rid of them before (possibly)
         *  randomizing the manifold.
         */

        free_cross_sections(manifold);

        /*
         *  Did we really find a subdivision of the canonical
         *  cell decomposition?
         *  Or did we just get stuck on (potential) negatively
         *  oriented Tetrahedra?
         */

        all_done = validate_canonical_triangulation(manifold);

        /*
         *  If we got stuck on (potential) negatively oriented
         *  Tetrahedra, randomize the Triangulation and try
         *  again.
         */

        if (all_done == FALSE)
            randomize_triangulation(manifold);

        /*
         *  The documentation says that if a hyperbolic structure
         *  with all positively oriented tetrahedra is present, then
         *  proto_canonize() will never fail.  And indeed with enough
         *  random retriangulations it should always be able to find
         *  a subdivision of the canonical cell decomposition.  But
         *  if a bug shows up somewhere we don't want this loop to run
         *  forever, so if num_attempts exceeds MAX_ATTEMPTS we should
         *  declare a fatal error and quit.
         */

        if (++num_attempts > MAX_ATTEMPTS)
            uFatalError("proto_canonize", "canonize_part_1");

    } while (all_done == FALSE);

    /*
     *  Clean up.
     */

    if (needs_polishing == TRUE)
    {
        /*
         *  polish_hyperbolic_structures() takes responsibility for
         *  the shape_histories.
         */
        tidy_peripheral_curves(manifold);
        polish_hyperbolic_structures(manifold);

        /*
         *  If the Chern-Simons invariant is present, update the fudge factor.
         */
        compute_CS_fudge_from_value(manifold);
    }

    return func_OK;
}