我使用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
}
提前致谢