Delaunay三角剖分退化案例4的随机增量方法表现不正常

时间:2014-11-28 16:06:22

标签: c++ algorithm computational-geometry delaunay

我正在尝试实现(1)中给出的算法来获得一组点的Delaunay三角剖分,但是当我尝试处理退化情况时我会陷入困境。首先,我实现了Glenn Eguchi在2001年10月11日的6.838 Computational Geometry中提出的方法,因为这个过程使用了三个起点而不是书中提出的两个起点,并且更容易处理有向无环图的搜索。存储三角形。另一方面,书中给出的关于如何处理属于附加三角形的点的解释有点棘手,我根本不理解。

嗯,问题在于,根据这种方法,在程序开始时,有必要处理这样的情况,即具有三角形顶点的任何边界点添加到原始点集中,结果四个退化例:

案例1)指数i和j都是否定的。

  • (pi,pj)是边界三角形的边缘
  • (pi,pj)是合法的,想要保留边界三角形的边缘

案例2)指数i,j,k和l均为正数。

  • 这是正常情况。
  • (pi,pj)是非法的,如果它位于(pi,pj,pk)的外接圆内

案例3)i,j,k,l中的一个是负的

  • 我们不希望我们的边界三角形破坏任何Delaunay边缘。
  • 如果我或j是否定的,则pipj是非法的。
  • 否则,pipj是合法的。

案例4)i,j,k,l中只有两个是否定的。

  • k和l不能都是负数(pk或pl必须是pr)
  • i和j不能都是否定的
  • i或j中的一个和k或l中的一个必须为负
  • 如果i和j的负指数小于k和l的负指数,则(pi,pj)是合法的。
  • 否则(pi,pj)是非法的。

Case 4 representation

提出的三个起点是:

  • p-1 =(3M,0)
  • p-2 =(0,3M)
  • p-3 =( - 3M,-3M)

M = P

中某点的任何坐标的最大绝对值

可以找到更多其他帮助here

参考文献:

(1)De Berg,M.,Van Kreveld,M.,Overmars,M。,& Schwarzkopf,O。C.(2000).Compigureational geometry(pp.1-17)。施普林格柏林海德堡。

如果我将第4个案例放在算法中,我会给你一个简单的测试用例。原因是,如果我包含这样的情况,那么当我只从点集中添加两个点时,由于情况4,在找到非法边缘后,无法找到包含上述情况的任何合法部分的边缘。现在,我删除了我的实现的这种情况并且算法有效,但我想如果我不包括这种情况,算法没有完成,因为对于某些点集很重要。我还在努力找到它:

3 
0 0
4 0
0 4

第一行,给出的分数。然后,每行每个点的x和y坐标。插入点的顺序(这很重要,因为在这种方法中点是随机插入的)是以下(0,4) - > (0,0) - > (4,0)。

这是我实施的函数legalizeEdge,评论的行属于案例4:

/* Take into account that the symbolical points at the bounding triangle
* could be part of the edges to legalize */
void legalizeEdge(point pr, seg s) {
    bool ill = 0;
    int fn = 0, sn = 0;
    pair<int, int> adj = Q[s];
    point pl =
            contain(nodes[adj.first].t, pr) ?
                    getPoint(nodes[adj.second].t, s) :
                    getPoint(nodes[adj.first].t, s);

    if (s.first == p_1 || s.first == p_2 || s.first == p_3) {
        fn = s.first == p_3 ? -3 : s.first == p_1 ? -1 : -2;
        if (s.second == p_1 || s.second == p_2 || s.second == p_3) {
            return; // Case 1: is always legal
        }
    }

    if (s.second == p_1 || s.second == p_2 || s.second == p_3) {
        fn = s.first == p_3 ? -3 : s.first == p_1 ? -1 : -2;
    }

    if (pl == p_1 || pl == p_2 || pl == p_3) {
        // Case 4: both either(i,j) and l must be negative
        /*sn = pl == p_1 ? -3 : pl == p_1 ? -1 : -2;
        if(!fn) {
            return; // Case 3: is legal only when i or j are not negative
        }
        else if (fn < sn)
            return; // if min(i,j) < l
        else
            ill = 1;*/
        return;
    } else if(fn) {
        ill = 1; // Case 3 read above
    }

    if (ill || inCircle(pr, s.first, s.second, pl)) { // is illegal
        // Case 2 or illegal Case 3
        seg news;
        int firstt, secondd;
        pair<int, int> nadj;
        point pj = s.first, pi = s.second;

        // replace s(pj,pi) with s(pr,pl) flip edge!!!

        firstt = contain(nodes[adj.first].t,pl) ? adj.first:adj.second;
        secondd = firstt == adj.first ? adj.second:adj.first;

        Q.erase(s);
        news = getSeg(pr,pl);
        insTrang(pr, pj, pl), nadj.first = IDX,
        nodes[adj.first].son.push_back(IDX), nodes[adj.second].son.push_back(
        IDX);

        updateMap(pl,pj,firstt);
        updateMap(pr,pj,secondd);

        insTrang(pr, pl, pi), nadj.second = IDX,
        nodes[adj.first].son.push_back(IDX), nodes[adj.second].son.push_back(
        IDX);

        updateMap(pi,pr,secondd);
        updateMap(pi,pl,firstt);

        Q[news] = nadj;

        seg sa = getSeg(pi,pl);
        legalizeEdge(pr, sa);

        seg sb = getSeg(pj,pl);
        legalizeEdge(pr, sb);
    }
}

提前致谢。

0 个答案:

没有答案