使用Bowyer-Watson算法在Delaunay三角剖分中丢失/重叠三角形

时间:2017-10-26 16:25:15

标签: java algorithm geometry triangulation

我使用Bowyer-Watson算法进行Delaunay三角测量并且几乎完全完成了,但是代码中仍然存在一个小的边缘情况,导致三角测量中存在缺失/重叠的三角形。有人知道我应该改变什么来消除三角测量中的孔/重叠三角形吗?

    public ArrayList<NTriangle> triangulate() {
        //Based off this: https://en.wikipedia.org/wiki/Bowyer%E2%80%93Watson_algorithm

        ArrayList<NTriangle> tri = new ArrayList<NTriangle>();
        superT = new NTriangle(new NPoint(-WIDTH,HEIGHT+HEIGHT), new NPoint(WIDTH/2, -HEIGHT), new NPoint(WIDTH+WIDTH, HEIGHT+HEIGHT));

        tri.add(superT);

        for(NPoint p : origPoints) {
            ArrayList<NTriangle> badTri = new ArrayList<NTriangle>();

            for(NTriangle t : tri) {
                int dist = dist(t.circ,p);
                if(dist <= t.rad) 
                    badTri.add(t);
            }
            ArrayList<NLine> unique = new ArrayList<NLine>();
            for(NTriangle t : badTri) {
                for(NLine l : t.lines) {
                    if(!edgeInTri(badTri,l)) { // checks if the edge l is not in any of the badTri triangles
                        unique.add(l);
                    }
                }
            }
            for(NTriangle t : badTri)
                tri.remove(t);

            for(NLine l : unique) {
                NTriangle t = new NTriangle(p,l.a,l.b);
                tri.add(t);
            }
        }

        // remove everything connected to the supertringle
        ArrayList<NTriangle> remove = new ArrayList<NTriangle>();

        for(NTriangle t : tri) {
            for(NPoint p : superT.points) {
                if(contains(t.points, p))  // checks in p is in t.points
                    remove.add(t);
            }
        }

        for(NTriangle t : remove) 
            tri.remove(t);

        return tri;
    }

    public void paint(Graphics g) {
        for(NTriangle t : triangles )
            t.paint(g);

        for(NPoint p : origPoints)
            System.out.println(p.y);

    }
}

算法部分上面的代码,我将发布下面的对象。我使用维基百科伪代码作为指导。

NPoint课程     包几何;

public class NPoint {
    public int x, y;
    public NPoint(int x_, int y_) {
        x = x_;
        y = y_;
    }

    public static NPoint multiply(NPoint n, double i) {
        return new NPoint((int)(n.x*i), (int)(n.y*i));
    }

    public static NPoint add(NPoint n, NPoint m) {
        return new NPoint((int)(n.x+m.x), (int)(n.y+m.y));
    }

    public static boolean overlap(NPoint a, NPoint b) {
        if(a.x == b.x && a.y == b.y) 
            return true;
        else
            return false;
    }
}

NLine课程     包几何;

public class NLine {
    public int ax, ay;
    public int bx, by;

    public NPoint a, b;

    public NLine(int ax_, int ay_, int bx_, int by_) {
        a = new NPoint(ax, ay);
        a = new NPoint(bx, by);

        ax = ax_;
        ay = ay_;
        bx = bx_;
        by = by_;
    }

    public NLine(NPoint a_, NPoint b_) {
        this.a=a_;
        this.b=b_;
    }

    public static boolean overlap(NLine n, NLine l) {
        if((NPoint.overlap(n.a, l.a) && (NPoint.overlap(n.b, l.b))) || (NPoint.overlap(n.a, l.b) && (NPoint.overlap(n.b, l.a))))
            return true;
        else
            return false;

    }
}

NTriangle class

package geometry;

import java.awt.Color;
import java.awt.Graphics;


public class NTriangle {

    public NPoint a, b, c;

    public NPoint circ = new NPoint(0,0);
    public int rad = 0;

    public NPoint[] points = new NPoint[3];
    public NLine[] lines = new NLine[3];

    public NTriangle(NPoint p1_, NPoint p2_, NPoint p3_) {
        a = p1_;
        b = p2_;
        c = p3_;

        points[0] = a;
        points[1] = b;
        points[2] = c;

        lines[0] = new NLine(a,b);
        lines[1] = new NLine(a,c);
        lines[2] = new NLine(b,c);

        circumCenter(a,b,c);
    }

    public void circumCenter(NPoint p0, NPoint p1, NPoint p2) {
        float dA, dB, dC, aux1, aux2, div;

        dA = p0.x * p0.x + p0.y * p0.y;
        dB = p1.x * p1.x + p1.y * p1.y;
        dC = p2.x * p2.x + p2.y * p2.y;

        aux1 = (dA*(p2.y - p1.y) + dB*(p0.y - p2.y) + dC*(p1.y - p0.y));
        aux2 = -(dA*(p2.x - p1.x) + dB*(p0.x - p2.x) + dC*(p1.x - p0.x));
        div = (2*(p0.x*(p2.y - p1.y) + p1.x*(p0.y-p2.y) + p2.x*(p1.y - p0.y)));

        if(div == 0){ 
            return;
        }

        circ.x = (int) (aux1/div);
        circ.y = (int) (aux2/div);

        rad = (int) Math.sqrt((circ.x - p0.x)*(circ.x - p0.x) + (circ.y - p0.y)*(circ.y - p0.y));
    }

// paint function removed for readability
}

提前致谢

0 个答案:

没有答案