コード例 #1
0
ファイル: dehn1.cpp プロジェクト: WPettersson/regina
int main(int argc, char* argv[]) {
    if (argc < 4 || argc > 5) {
        std::cerr << "Usage: " << argv[0] << " <tri> <m> <l> [output-file]\n";
        std::cerr << "Example: " << argv[0] << " m003 -3 1\n";
        return 1;
    }

    long m = atoi(argv[2]);
    long l = atoi(argv[3]);

    int tets;
    bool orbl;
    switch (argv[1][0]) {
        case 'm':
            tets = 5; orbl = true /* ignored */; break;
        case 's':
            tets = 6; orbl = true; break;
        case 'x':
            tets = 6; orbl = false; break;
        case 'v':
            tets = 7; orbl = true; break;
        case 'y':
            tets = 7; orbl = false; break;
        default:
            std::cerr << "Cannot interpret triangulation name "
                << argv[1] << ".\n";
            return 1;
    }

    Triangulation* tri = GetCuspedCensusManifold(tets,
        orbl ? oriented_manifold : nonorientable_manifold,
        atoi(argv[1] + 1));
    if (! tri) {
        std::cerr << "Could not load triangulation " << argv[1] << ".\n";
        return 1;
    }

    set_cusp_info(tri, 0, 0, m, l);
    do_Dehn_filling(tri);
    double vol = volume(tri, 0);

    Triangulation* filled = fill_cusps(tri, 0,
        const_cast<char*>("filled"), 1);

    std::string name = triName(filled, vol);
    set_triangulation_name(filled, const_cast<char*>(name.c_str()));

    std::cout << "Writing " << name << "... ";
    save_triangulation(filled,
        argc > 4 ? argv[4] : const_cast<char*>(name.c_str()));
    std::cout << "done.\n";

    return 0;
}
コード例 #2
0
static Triangulation *try_Dirichlet_to_triangulation(
	WEPolyhedron	*polyhedron)
{
	/*
	 *	Implement Plan A as described above.
	 */
	
	Triangulation	*triangulation;
	WEEdge			*edge,
					*nbr_edge,
					*mate_edge;
	WEEdgeEnd		end;
	WEEdgeSide		side;
	Tetrahedron		*new_tet;
	FaceIndex		f;

	/*
	 *	Don't attempt to triangulate an orbifold.
	 */

	if (singular_set_is_empty(polyhedron) == FALSE)
		return NULL;
	
	/*
	 *	Set up the Triangulation.
	 */

	triangulation = NEW_STRUCT(Triangulation);
	initialize_triangulation(triangulation);

	/*
	 *	Allocate and copy the name.
	 */

	triangulation->name = NEW_ARRAY(strlen(DEFAULT_NAME) + 1, char);
	strcpy(triangulation->name, DEFAULT_NAME);

	/*
	 *	Allocate the Tetrahedra.
	 */

	triangulation->num_tetrahedra = 4 * polyhedron->num_edges;

	for (edge = polyhedron->edge_list_begin.next;
		 edge != &polyhedron->edge_list_end;
		 edge = edge->next)

		for (end = 0; end < 2; end++)	/* = tail, tip */

			for (side = 0; side < 2; side++)	/* = left, right */
			{
				new_tet = NEW_STRUCT(Tetrahedron);
				initialize_tetrahedron(new_tet);
				INSERT_BEFORE(new_tet, &triangulation->tet_list_end);
				edge->tet[end][side] = new_tet;
			}

	/*
	 *	Initialize neighbors.
	 */

	for (edge = polyhedron->edge_list_begin.next;
		 edge != &polyhedron->edge_list_end;
		 edge = edge->next)

		for (end = 0; end < 2; end++)	/* = tail, tip */

			for (side = 0; side < 2; side++)	/* = left, right */
			{
				/*
				 *	Neighbor[0] is associated to this same WEEdge.
				 *	It lies on the same side (left or right), but
				 *	at the opposite end (tail or tip).
				 */
				edge->tet[end][side]->neighbor[0] = edge->tet[!end][side];

				/*
				 *	Neighbor[1] lies on the same face of the Dirichlet
				 *	domain, but at the "next side" of that face.
				 */
				nbr_edge = edge->e[end][side];
				if (nbr_edge->v[!end] == edge->v[end])
					/* edge and nbr_edge point in the same direction */
					edge->tet[end][side]->neighbor[1] = nbr_edge->tet[!end][side];
				else if (nbr_edge->v[end] == edge->v[end])
					/* edge and nbr_edge point in opposite directions */
					edge->tet[end][side]->neighbor[1] = nbr_edge->tet[end][!side];
				else
					uFatalError("Dirichlet_to_triangulation", "Dirichlet_conversion");

				/*
				 *	Neighbor[2] is associated to this same WEEdge.
				 *	It lies at the same end (tail or tip), but
				 *	on the opposite side (left or right).
				 */
				edge->tet[end][side]->neighbor[2] = edge->tet[end][!side];

				/*
				 *	Neighbor[3] lies on this face's "mate" elsewhere
				 *	on the Dirichlet domain.
				 */
				mate_edge = edge->neighbor[side];
				edge->tet[end][side]->neighbor[3] = mate_edge->tet
					[edge->preserves_direction[side] ? end  : !end ]
					[edge->preserves_sides[side]     ? side : !side];
			}

	/*
	 *	Initialize all gluings to the identity.
	 */

	for (edge = polyhedron->edge_list_begin.next;
		 edge != &polyhedron->edge_list_end;
		 edge = edge->next)

		for (end = 0; end < 2; end++)	/* = tail, tip */

			for (side = 0; side < 2; side++)	/* = left, right */

				for (f = 0; f < 4; f++)

					edge->tet[end][side]->gluing[f] = IDENTITY_PERMUTATION;

	/*
	 *	Set up the EdgeClasses.
	 */
	create_edge_classes(triangulation);
	orient_edge_classes(triangulation);

	/*
	 *	Attempt to orient the manifold.
	 */
	orient(triangulation);

	/*
	 *	Set up the Cusps, including "fake cusps" for the finite vertices.
	 *	Then locate and remove the fake cusps.  If the manifold is closed,
	 *	drill out an arbitrary curve to express it as a Dehn filling.
	 *	Finally, determine the topology of each cusp (torus or Klein bottle)
	 *	and count them.
	 */
	create_cusps(triangulation);
	mark_fake_cusps(triangulation);
	peripheral_curves(triangulation);
	remove_finite_vertices(triangulation);
	count_cusps(triangulation);
	
	/*
	 *	Try to compute a hyperbolic structure, first for the unfilled
	 *	manifold, and then for the closed manifold if appropriate.
	 */
	find_complete_hyperbolic_structure(triangulation);
	do_Dehn_filling(triangulation);

	/*
	 *	If the manifold is hyperbolic, install a shortest basis on each cusp.
	 */
	if (	triangulation->solution_type[complete] == geometric_solution
	 	 || triangulation->solution_type[complete] == nongeometric_solution)
		install_shortest_bases(triangulation);

	/*
	 *	All done!
	 */
	return triangulation;
}
コード例 #3
0
static FuncResult drill_one_curve(
    Triangulation       **manifold,
    MergedMultiLength   *remaining_curves)
{
    int                     i;
    int                     num_curves;
    DualOneSkeletonCurve    **the_curves;
    int                     desired_index;
    Complex                 filled_length;
    Triangulation           *new_manifold;
    int                     count;

    /*
     *  See what curves are drillable.
     */
    dual_curves(*manifold, MAX_DUAL_CURVE_LENGTH, &num_curves, &the_curves);
    if (num_curves == 0)
        return func_failed;

    desired_index = -1;
    for (i = 0; i < num_curves; i++)
    {
        get_dual_curve_info(the_curves[i], NULL, &filled_length, NULL);

        if (
            fabs(remaining_curves->length - filled_length.real) < LENGTH_EPSILON
         && fabs(remaining_curves->torsion - fabs(filled_length.imag)) < TORSION_EPSILON
         && (
                (
                    remaining_curves->pos_multiplicity > 0
                 && filled_length.imag > ZERO_TORSION_EPSILON
                )
             ||
                (
                    remaining_curves->neg_multiplicity > 0
                 && filled_length.imag < -ZERO_TORSION_EPSILON
                )
             ||
                (
                    remaining_curves->zero_multiplicity > 0
                 && fabs(filled_length.imag) < ZERO_TORSION_EPSILON
                )
            )
        )
        {
            desired_index = i;
            break;
        }
    }
    if (desired_index == -1)
    {
        free_dual_curves(num_curves, the_curves);
        return func_failed;
    }

    new_manifold = drill_cusp(*manifold, the_curves[desired_index], get_triangulation_name(*manifold));

    if (new_manifold == NULL)
    {
        free_dual_curves(num_curves, the_curves);
        return func_failed;
    }

    /*
     *  Usually the complete solution will be geometric, even if
     *  the filled solution is not.  But occasionally we'll get
     *  a new_manifold which didn't simplify sufficiently, and
     *  we'll need to rattle it around to get a decent triangulation.
     */
    count = MAX_RANDOMIZATIONS;
    while (--count >= 0
            && get_complete_solution_type(new_manifold) != geometric_solution)
        randomize_triangulation(new_manifold);

    /*
     *  Set the new Dehn filling coefficient to (1, 0)
     *  to recover the closed manifold.
     */

    set_cusp_info(new_manifold, get_num_cusps(new_manifold) - 1, FALSE, 1.0, 0.0);
    do_Dehn_filling(new_manifold);

    free_dual_curves(num_curves, the_curves);

    free_triangulation(*manifold);
    *manifold = new_manifold;
    new_manifold = NULL;

    if (filled_length.imag > ZERO_TORSION_EPSILON)
        remaining_curves->pos_multiplicity--;
    else if (filled_length.imag < -ZERO_TORSION_EPSILON)
        remaining_curves->neg_multiplicity--;
    else
        remaining_curves->zero_multiplicity--;

    remaining_curves->total_multiplicity--;

    return func_OK;
}