コード例 #1
0
ファイル: simplification.cpp プロジェクト: StijnIIID/meshfix
Point Q_matrix::getOptimalPoint(Edge *e)
{
 if (IS_VISITED(e->v1)) return (*(e->v1));	// Check for sharp vertices
 if (IS_VISITED(e->v2)) return (*(e->v2));
 Point n;

 if (getMinimizer(&(n.x), &(n.y), &(n.z))) return n;
 // If not invertible, choose the best among mid, v1 and v2
 return bestAmongMidAndEndpoints(e);
}
コード例 #2
0
ファイル: simplification.cpp プロジェクト: StijnIIID/meshfix
Point Q_matrix::bestAmongMidAndEndpoints(Edge *e)
{
 if (IS_VISITED(e->v1)) return (*(e->v1));	// Check for sharp vertices
 if (IS_VISITED(e->v2)) return (*(e->v2)); 

 Point mp = e->getMidPoint();			// Get Edge Midpoint
 double erm = getError(&mp, e);			// Error at midpoint
 double er1 = getError(e->v1, e);		// Error at v1
 double er2 = getError(e->v2, e);		// Error at v2

 if (erm <= er1 && erm <= er2) return mp;
 if (er1 <= erm && er1 <= er2) return (*(e->v1));

 return (*(e->v2));
}
コード例 #3
0
int directed_MST(int root)
{
    int i, j, k;
    int has_cycle;
    int weight, weight_contracted = 0;

    int in_edge_weight[MAX_N];
    int in_edge_src[MAX_N];
    int v_in_cycle[MAX_N];
    int contracted[MAX_N];

    memset(contracted, 0, sizeof(contracted));
    for (;;)
    {
        for (i = 0; i < n; i++)
        {
            in_edge_weight[i] = 0x7fffffff;
            in_edge_src[i] = -1;
        }

        /* STEP 1 */
        for (i = 0; i < m; i++)
        {
            /* The edges should be ingored, but condition 1 & 2 are removed in the other place */
            /* 1. no edge to itself: e[i].s != e[i].d  */
            /* 2. no edge to root:   e[i].d != root    */
            /* 3. has the lowest weight in all in-edge */ 
            if (e[i].w < in_edge_weight[e[i].d])
            {
                in_edge_src[e[i].d] = e[i].s;
                in_edge_weight[e[i].d] = e[i].w;
            }
        }

        /* STEP 2 */
        weight = 0;
        has_cycle = 0;


        for (i = 0; i < n; i++)
        {
            if (contracted[i] == 1)
                continue;

            if (in_edge_src[i] == -1 && i != root)
            {
                return -1; /* no MST */
            }

            if (in_edge_src[i] != -1)
            weight += in_edge_weight[i];

            /* if three is a cycle in the graph and v[i] is one of vertex connected to the cycle,
                  the final j won't be -1. */
            RESET_VISITED();
            for (j = i;
                j != -1 && !IS_VISITED(j);
                j = in_edge_src[j])
                {
                    SET_VISITED(j);
                }

            if (j != -1 && IS_VISITED(j))
            {
                has_cycle = 1;
                for (k = 0; k < n; k++)
                    v_in_cycle[k] = -1;

                v_in_cycle[j] = j;
                weight_contracted += in_edge_weight[j];
                for (k = in_edge_src[j]; k != j; k = in_edge_src[k])
                {
                    v_in_cycle[k] = j;
                    contracted[k] = 1;
                    weight_contracted += in_edge_weight[k];
                }
                break;
            }
        }

        if (has_cycle == 0)
        {
            break;
        }

        /*  STEP 3:
           all vertexs in the cycle are contracted in to one vertex
             For an edge e not in the cycle: the new weight will be updated to 'e.w - in_edge_weight[e.d]'.
             It means if the edge is add to the MST, the edge from in_edge_src[e.d] to e.d would be removed.
        */
        for (i = 0; i < m ; i++)
        {
            if (v_in_cycle[e[i].d] >= 0)
            {
                e[i].w -= in_edge_weight[e[i].d];
                e[i].d = v_in_cycle[e[i].d];
            }

            if (v_in_cycle[e[i].s] >= 0)
            {
                e[i].s = v_in_cycle[e[i].s];
            }

            /* an edge to itself would be removed */
            if (e[i].s == e[i].d)
            {
                e[i--] = e[--m];
            }
        }
    }

    return weight + weight_contracted;
}