I have an array of points in 2D space. I'm trying to create from those points as many triangles as possible but:
- All triangles must be valid (a < b + c and b < a + c and c < a + b)
- No triangles can contain a point (just their vertices)
- No triangles can intersect any other triangles
By intersection I mean that a triangle can't be inside another triangle and a triangle's side can't cross an other's (but they can share an edge).
I think there's no problem with my algorithm (pseudo for simplicity):
newTriangles := false
do:
newTriangles := false
for a in points:
for b in points:
if b = a:
continue
for c in points:
if c = a or c = b:
continue
// So now we have every combination of a, b and c
// Now the tests
if not valid_triangle(a, b, c) then continue
containsPoint := false
for p in points:
if p = a or p = b or p = c:
continue
if contains(a, b, c, p):
containsPoint := true // first 3 params are the vertices of the triangle, the 4th is the point for test
if containsPoint:
continue
// Now the last test, the existing triangle intersection
intersects := false
for triangle in triangles:
if intersects(triangle, a, b, c):
intersects := true
// It passed every test, it can be a triangle
if not intersects:
triangles.add(new triange(a, b, c))
newTriangles := true
while newTriangles
This connects some triangles, but every triangle is isolated from the others. I guess that intersection checking returns true. Now to illustrate my problem a bit better:
So the first step happens, but the second one won't, it keeps every triangle (and sometimes single points) isolated. However if I change my intersection checking code, then this code will never halt. What could be the solution?
Edit:
Here's my intersects algorithm (this is real Java code):
public static boolean intersects(Vector2f a, Vector2f b, Vector2f c, Triangle other) {
boolean x = (Line.segmentIntersects(a, b, other.a, other.b) || Line.segmentIntersects(b, c, other.a, other.b)) ||
(Line.segmentIntersects(a, b, other.a, other.b) || Line.segmentIntersects(a, c, other.a, other.b)) ||
(Line.segmentIntersects(a, c, other.a, other.b) || Line.segmentIntersects(b, c, other.a, other.b));
boolean y = (Line.segmentIntersects(a, b, other.b, other.c) || Line.segmentIntersects(b, c, other.b, other.c)) ||
(Line.segmentIntersects(a, b, other.b, other.c) || Line.segmentIntersects(a, c, other.b, other.c)) ||
(Line.segmentIntersects(a, c, other.b, other.c) || Line.segmentIntersects(b, c, other.b, other.c));
boolean z = (Line.segmentIntersects(a, b, other.a, other.c) || Line.segmentIntersects(b, c, other.a, other.c)) ||
(Line.segmentIntersects(a, b, other.a, other.c) || Line.segmentIntersects(a, c, other.a, other.c)) ||
(Line.segmentIntersects(a, c, other.a, other.c) || Line.segmentIntersects(b, c, other.a, other.c));
return (x || y || z ||
other.contains(a) || other.contains(b) || other.contains(c));
}
Segment intersects is:
public static boolean segmentIntersects(Vector2f ps1, Vector2f pe1, Vector2f ps2, Vector2f pe2) {
return (Line2D.linesIntersect(ps1.x, ps1.y, pe1.x, pe1.y, ps2.x, ps2.y, pe2.x, pe2.y));
}
And contains:
private static float sign(Vector2f p1, Vector2f p2, Vector2f p3) {
return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y);
}
public static boolean contains(Vector2f a, Vector2f b, Vector2f c, Vector2f p) {
boolean b1, b2, b3;
b1 = sign(p, a, b) < 0.0f;
b2 = sign(p, b, c) < 0.0f;
b3 = sign(p, c, a) < 0.0f;
return ((b1 == b2) && (b2 == b3));
}
point cloud triangulation
perhaps? Or maybe evenDelaunay triangulation
? – n. 1.8e9-where's-my-share m.