예제 #1
0
T DDT2D::globalCostFunction ( Container <HalfEdge <T> *> &half_edges )
{
        // Compute cost of the triangulation using selected criterion
        const unsigned int n = half_edges.size();
        T cost = 0;

        //Loop all edges
        for ( unsigned int i = 0; i < n; i++ )
        {

                //Take half edge
                HalfEdge <T> *e = half_edges [i];

                //Use simplex indentificator to eliminate T processing of the edge
                if ( !e->isSimplexEdge() )
                {
                        //Get the first triangle
                        const HalfEdge <T> *e12 = e->getNextEdge();
                        const HalfEdge <T> *e13 = e12->getNextEdge();

                        //Does a twin edge exist?
                        if ( e->getTwinEdge() )
                        {
                                //Get coordinates of the first triangle
                                const Point3DCartesian <T> *p11 = e->getPoint();
                                const Point3DCartesian <T> *p12 = e12->getPoint() ;
                                const Point3DCartesian <T> *p13 =  e13->getPoint() ;

                                //Get second triangle
                                HalfEdge <T> *e21 = e->getTwinEdge();
                                const HalfEdge <T> *e22 = e21->getNextEdge();
                                const HalfEdge <T> *e23 = e22->getNextEdge();

                                //Get coordinates
                                const Point3DCartesian <T> *p21 = p12;
                                const Point3DCartesian <T> *p22 = p11;
                                const Point3DCartesian <T> *p23 = e23->getPoint();

                                //Compute local criterion
                                T fi = ( *pcriterion ) ( p11, p12, p13, p21, p22, p23 );

                                //Global cost
                                cost += fi;

                                //Set both edges to be processed
                                e->setEdgeAsSimplex ( true );
                                e21->setEdgeAsSimplex ( true );
                        }
                }
        }

        //Reset attribute
        for ( unsigned int i = 0; i < n; i++ )
        {
                ( *half_edges ) [i]->setEdgeAsSimplex ( false );
        }

        //Return global cost of the triangulation
        return cost;
}
예제 #2
0
void DDT2D::DDTLOP ( Container <Node3DCartesian <T> *> &nl, Container <HalfEdge <T> *> &half_edges, unsigned short swap_criterion_selected, const bool print_message, const bool print_exception, std::ostream * output )
{
        // Data Depending triangulation using selected local criterion
        bool swap_exist = true;

        //Set iterations
        unsigned iterations = 0;

        //Create Delaunay triangulation
        DT2D::DT ( nl, half_edges, print_message );

        //Get number of HalfEdges
        const unsigned int n = half_edges->size();

        //Set local swap criterion
        setSwapCriterion ( swap_criterion_selected );

        //Global cost before swapping
        const T global_cost_old = globalCostFunction ( half_edges );
        T global_cost = global_cost_old;

        //Print info
        if ( print_message )
        {
                *output << "> Starting DDTLOP... " ;
        }

        //Initialize counters
        unsigned int counter = MAX_INT, counter_old = MAX_INT;

        try
        {
                //Run until swap exists or decrease number of swaps between two loops
                do
                {
                        //We suppose ordered set of triangles, no swap will be required
                        swap_exist = false;

                        //Remember old counter
                        counter_old = counter;

                        //Assign new counter value
                        counter = 0;

                        //Loop all edges
                        for ( unsigned int i = 0; i < n; i++ )
                        {

                                //Take half edge
                                HalfEdge <T> *e = ( *half_edges ) [i];

                                //Use simplex flag to eliminate T processing of the edge
                                if ( !e->isSimplexEdge() )
                                {
                                        //Does twin edge exist?
                                        if ( e->getTwinEdge() )
                                        {
                                                // Test of convexity for quadrilateral
                                                HalfEdge <T> *e12 = e->getNextEdge();
                                                HalfEdge <T> *e13 = e12->getNextEdge();
                                                HalfEdge <T> *e21 = e->getTwinEdge();
                                                HalfEdge <T> *e22 = e21->getNextEdge();
                                                HalfEdge <T> *e23 = e22->getNextEdge();

                                                // Get nodes, counterclockwise set of nodes
                                                const Node3DCartesian <T> *p1 = e->getPoint();
                                                const Node3DCartesian <T> *p2 = e23->getPoint();
                                                const Node3DCartesian <T> *p3 = e12->getPoint();
                                                const Node3DCartesian <T> *p4 = e13->getPoint();

                                                //Is convex (non convex can not be swapped)
                                                if ( ConvexQuadrilateral::isStrictlyConvex ( p1, p2, p3, p4 ) == 1 )
                                                {

                                                        //Set twin edge to be processed
                                                        e->getTwinEdge()->setEdgeAsSimplex ( true );

                                                        //Get first triangle
                                                        e12 = e->getNextEdge();
                                                        e13 = e12->getNextEdge();

                                                        //Get coordinates (cast to parent using static_cast)
                                                        const Point3DCartesian <T> *p11 = e->getPoint();
                                                        const Point3DCartesian <T> *p12 = e12->getPoint();
                                                        const Point3DCartesian <T> *p13 = e13->getPoint();

                                                        //Get second triangle
                                                        e21 = e->getTwinEdge();
                                                        e22 = e21->getNextEdge();
                                                        e23 = e22->getNextEdge();

                                                        //Get coordinates
                                                        const Point3DCartesian <T> *p21 = p12;
                                                        const Point3DCartesian <T> *p22 = p11;
                                                        const Point3DCartesian <T> *p23 = e23->getPoint();

                                                        //Compute local criterion
                                                        const T c1 = ( *pcriterion ) ( p11, p12, p13, p21, p22, p23 );

                                                        //Calculation local criterion from swapped diagonal
                                                        const T c2 = ( *pcriterion ) ( p13, p11, p23, p12, p13, p23 );

                                                        //Swap diagonal
                                                        if ( c2 < c1 )
                                                        {
                                                                //Swap exists
                                                                swap_exist = true;

                                                                //Swap diagonal
                                                                DT2D::swapDiagonal ( e, e12, e13, e21, e22, e23 );

                                                                counter++;
                                                        }

                                                        //Set both edges to be processed
                                                        e->setEdgeAsSimplex ( true );
                                                        e21->setEdgeAsSimplex ( true );
                                                }
                                        }
                                }
                        }

                        //Set all edges as unused
                        for ( unsigned int i = 0; i < n; i++ )
                        {


                                //Take half edge
                                HalfEdge <T> *e = ( *half_edges ) [i];

                                //Set edge not to be a simplex
                                e->setEdgeAsSimplex ( false );
                        }

                        //Number of iterations
                        iterations ++;
                }
                while ( swap_exist );

                //Global cost after swapping
                global_cost = globalCostFunction ( half_edges );

                //Compute change ratio
                T ddt_ratio = 0;

                if ( global_cost  != global_cost_old )
                {
                        ddt_ratio = 100 * ( global_cost - global_cost_old ) / global_cost_old;
                }

                //Print info
                if ( print_message )
                {
                        *output << "Completed..." << std::endl;
                        *output << "> DT global cost old: " << global_cost_old << "  DT global cost new: " << global_cost << ", ratio: " << ddt_ratio << "%" << std::endl;
                }
        }

        //Throw exception
        catch ( Error & error )
        {
                if ( print_exception )
                {
                        error.printException ( output );
                }

                //Delete lists
                half_edges->clear();

                *output << "DDT construction cancelled..." << std::endl;

                throw;
        }
}
예제 #3
0
float DDT2D::getInitialTemperature ( Container <HalfEdge <T> *> &half_edges )
{
        // Compute cost of the triangulation using selected criterion
        const unsigned int n = half_edges.size();
        T max_difference = 0; ;

        //Loop all edges
        for ( unsigned int i = 0; i < n; i++ )
        {

                //Take half edge
                HalfEdge <T> *e = half_edges [i];

                if ( !e->isSimplexEdge() )
                {
                        //Get next edges
                        const HalfEdge <T> *e12 = e->getNextEdge();
                        const HalfEdge <T> *e13 = e12->getNextEdge();

                        //Does a twin edge exist?
                        if ( e->getTwinEdge() )
                        {
                                //Get coordinates of the first triangle (cast to parent using static_cast)
                                const Point3DCartesian <T> *p11 = e->getPoint();
                                const Point3DCartesian <T> *p12 = e12->getPoint();
                                const Point3DCartesian <T> *p13 = e13->getPoint();

                                //Get second triangle
                                HalfEdge <T> *e21 = e->getTwinEdge();
                                HalfEdge <T> *e22 = e21->getNextEdge();
                                HalfEdge <T> *e23 = e22->getNextEdge();

                                //Get coordinates
                                const Point3DCartesian <T> *p21 = p12;
                                const Point3DCartesian <T> *p22 = p11;
                                const Point3DCartesian <T> *p23 = e23->getPoint();

                                //Only strictly convex quadrilaterals
                                if ( ConvexQuadrilateral::isStrictlyConvex ( p11,  p23, p12,  p13 ) == 1 )
                                {
                                        //Compute local criterion  for adjacent triangles
                                        const T fi1 = ( *pcriterion ) ( p11, p12, p13, p21, p22, p23 );

                                        //Compute local criterion  for swapped triangles
                                        const T fi2 = ( *pcriterion ) ( p13, p23, p12, p23, p13, p11 );

                                        //Find max difference
                                        if ( fabs ( fi2 - fi1 ) > max_difference )
                                        {
                                                max_difference = fabs ( fi2 - fi1 );
                                        }
                                }

                                //Set both edges to be processed
                                e->setEdgeAsSimplex ( true );
                                e21->setEdgeAsSimplex ( true );
                        }
                }
        }

        //Reset attribute
        for ( unsigned int i = 0; i < n; i++ )
        {
                ( *half_edges ) [i]->setEdgeAsSimplex ( false );
        }

        //Return result
        return ( float ) ( 2 * max_difference );
}