Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 66 additions & 73 deletions src/nl/tue/geometrycore/algorithms/delaunay/DelaunayTriangulation.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ private TVertex compute(int low, int high) {
System.err.println("Should not occur");
return null;
case 1: {
// one vertex
// one vertex
// System.err.println("CALL " + low + "-" + (high - 1) + " :: " + _vertices.get(low) + "-" + _vertices.get(high - 1));
TVertex u = _vertices.get(low);
// System.err.println("RET " + u + " << " + low + "-" + (high - 1));
Expand All @@ -104,7 +104,10 @@ private TVertex compute(int low, int high) {
TVertex w = _vertices.get(low + 2);
addEdge(u, v);
addEdge(v, w);
addEdge(w, u);
// detects collinear by sine value
if (Vector.crossProduct(Vector.subtract(u, v), Vector.subtract(v, w)) != 0) {
addEdge(w, u);
}
TVertex min = u.getY() <= v.getY() && u.getY() <= w.getY()
? u : (v.getY() <= w.getY() ? v : w);
// System.err.println("RET " + min + " << " + low + "-" + (high - 1));
Expand Down Expand Up @@ -164,14 +167,24 @@ private TVertex compute(int low, int high) {

if (u_cand != null) {
if (addEdge(u_cand, v)) {
System.err.println("DUPLICATE EDGE -- aborting" + " << " + low + "-" + (high - 1));
return null;
// detects collinear by sine value
if (Vector.crossProduct(Vector.subtract(u, u_cand), Vector.subtract(v, u_cand)) == 0) {
_input.removeEdge(u.getEdgeTo(v));
} else {
System.err.println("DUPLICATE EDGE -- aborting" + " << " + low + "-" + (high - 1));
return null;
}
}
u = u_cand;
} else { // v_cand != null
} else { // v_cand != null
if (addEdge(u, v_cand)) {
System.err.println("DUPLICATE EDGE -- aborting" + " << " + low + "-" + (high - 1));
return null;
// detects collinear by sine value
if (Vector.crossProduct(Vector.subtract(u, v_cand), Vector.subtract(v, v_cand)) == 0) {
_input.removeEdge(u.getEdgeTo(v));
} else {
System.err.println("DUPLICATE EDGE -- aborting" + " << " + low + "-" + (high - 1));
return null;
}
}
v = v_cand;
}
Expand Down Expand Up @@ -245,10 +258,9 @@ private TVertex shiftHull(TVertex vertex, TVertex other, int mid, Side side) {
private TVertex candidate(TVertex vertex, TVertex other, int mid, Side side) {

Vector dir = Vector.subtract(other, vertex);
dir.normalize();

// System.err.println(" candidate? "+vertex+" "+other);

TVertex first = findFirst(vertex, dir, mid, side);
// System.err.println(" first "+first);
if (first == null) {
Expand All @@ -271,119 +283,100 @@ private TVertex candidate(TVertex vertex, TVertex other, int mid, Side side) {
private TVertex findFirst(TVertex vertex, Vector dir, int mid, Side side) {

TVertex min = null;
double opt = Double.POSITIVE_INFINITY;
double opt = Double.NEGATIVE_INFINITY;
for (TEdge e : vertex.getEdges()) {
TVertex nbr = e.getOtherVertex(vertex);
if (side == Side.LEFT && _graph_to_sorted[nbr.getGraphIndex()] >= mid) {
continue;
} else if (side == Side.RIGHT && _graph_to_sorted[nbr.getGraphIndex()] < mid) {
continue;
}
Vector edir = Vector.subtract(nbr, vertex);
edir.normalize();
double a = side == Side.LEFT
? dir.computeCounterClockwiseAngleTo(edir, false, false)
: dir.computeClockwiseAngleTo(edir, false, false);
// if (a > Math.PI * 2 - DoubleUtil.EPS) {
// a = 0;
// }
if (a < opt) {
Vector e_dir = Vector.subtract(nbr, vertex);
var cross = Vector.crossProduct(dir, e_dir);
var dot = Vector.dotProduct(dir, e_dir);
if (cross == 0) {
if (dot < 0) {
continue; // theta = pi
}
} else if ((side == Side.LEFT) ^ (cross > 0)) {
continue; // theta > pi
}
var cos_sim = dot / (dir.length() * e_dir.length());
if (cos_sim > opt) {
min = nbr;
opt = a;
opt = cos_sim;
}
}

if (min == null) {
return null;
}

if (opt >= Math.PI) {
return null;
}

return min;
}

private TVertex findSecond(TVertex vertex, Vector dir, int mid, Side side) {

TVertex min = null;
double opt = Double.POSITIVE_INFINITY;
double opt = Double.NEGATIVE_INFINITY;
TVertex sec = null;
double sec_opt = Double.POSITIVE_INFINITY;
double sec_opt = Double.NEGATIVE_INFINITY;
for (TEdge e : vertex.getEdges()) {

TVertex nbr = e.getOtherVertex(vertex);
if (side == Side.LEFT && _graph_to_sorted[nbr.getGraphIndex()] >= mid) {
continue;
} else if (side == Side.RIGHT && _graph_to_sorted[nbr.getGraphIndex()] < mid) {
continue;
}
Vector edir = Vector.subtract(nbr, vertex);
edir.normalize();
double a = side == Side.LEFT
? dir.computeCounterClockwiseAngleTo(edir, false, false)
: dir.computeClockwiseAngleTo(edir, false, false);

// System.err.println(" "+nbr+" :: "+a);
// if (a > Math.PI * 2 - DoubleUtil.EPS) {
// a = 0;
// }
if (a < opt) {
Vector e_dir = Vector.subtract(nbr, vertex);
var cross = Vector.crossProduct(dir, e_dir);
var dot = Vector.dotProduct(dir, e_dir);
if (cross == 0) {
if (dot < 0) {
continue; // theta = pi
}
} else if ((side == Side.LEFT) ^ (cross > 0)) {
continue; // theta > pi
}
var cos_sim = dot / (dir.length() * e_dir.length());
if (cos_sim > opt) {
sec = min;
sec_opt = opt;
min = nbr;
opt = a;
} else if (a < sec_opt) {
opt = cos_sim;
} else if (cos_sim > sec_opt) {
sec = nbr;
sec_opt = a;
sec_opt = cos_sim;
}
}

if (sec == null) {
return null;
}

if (sec_opt >= Math.PI) {
return null;
}

return sec;
}

private TVertex findLast(TVertex vertex, Vector dir, int mid, Side side) {

TVertex min = null;
double opt = Double.POSITIVE_INFINITY;
double opt = Double.NEGATIVE_INFINITY;
for (TEdge e : vertex.getEdges()) {
TVertex nbr = e.getOtherVertex(vertex);
if (side == Side.LEFT && _graph_to_sorted[nbr.getGraphIndex()] >= mid) {
continue;
} else if (side == Side.RIGHT && _graph_to_sorted[nbr.getGraphIndex()] < mid) {
continue;
}
Vector edir = Vector.subtract(nbr, vertex);
edir.normalize();
// SWAPPED WRT find first/second
double a = side == Side.RIGHT
? dir.computeCounterClockwiseAngleTo(edir, false, false)
: dir.computeClockwiseAngleTo(edir, false, false);
// if (a > Math.PI * 2 - DoubleUtil.EPS) {
// a = 0;
// }
if (a < opt) {
Vector e_dir = Vector.subtract(nbr, vertex);
var cross = Vector.crossProduct(dir, e_dir);
var dot = Vector.dotProduct(dir, e_dir);
if (cross == 0) {
if (dot < 0) {
continue; // theta = pi
}
} else if ((side == Side.LEFT) ^ (cross < 0)) { // SWAPPED WRT find first/second
continue; // theta >= pi
}
var cos_sim = dot / (dir.length() * e_dir.length());
if (cos_sim > opt) {
min = nbr;
opt = a;
opt = cos_sim;
}
}

if (min == null) {
return null;
}

if (opt >= Math.PI) {
return null;
}

return min;
}
}