我在2D空间中有一系列点。我试图从这些点创建尽可能多的三角形,但是:
通过交叉,我的意思是三角形不能在另一个三角形内,而三角形的一边不能与另一个三角形交叉(但它们可以共享边缘)。
我认为我的算法没有问题(为简单而假):
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
这会连接一些三角形,但每个三角形都与其他三角形隔离。我想交叉检查会返回true。现在来说明我的问题好一点:
所以第一步发生了,但第二步不会发生,它会保持每个三角形(有时是单个点)被隔离。但是,如果我更改交叉检查代码,则此代码将永远不会停止。可能是什么解决方案?
编辑:
这是我的交叉算法(这是真正的Java代码):
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));
}
段相交是:
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));
}
并包含:
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));
}
答案 0 :(得分:1)
我不能给你完整的工作代码,但我可以给你一些建议和一些可能的错误点:
首先请注意,在intersects
方法中,您正在进行大量冗余检查!
boolean x = (Line.segmentIntersects(a, b, other.a, other.b) ||
(Line.segmentIntersects(a, b, other.a, other.c) ||
(Line.segmentIntersects(a, b, other.b, other.c);
boolean y = (Line.segmentIntersects(a, c, other.a, other.b) ||
(Line.segmentIntersects(a, c, other.a, other.c) ||
(Line.segmentIntersects(a, c, other.b, other.c);
boolean z = (Line.segmentIntersects(b, c, other.a, other.b) ||
(Line.segmentIntersects(b, c, other.a, other.c) ||
(Line.segmentIntersects(b, c, other.b, other.c);
你需要的一切!在这里,您要检查三角形abc
的每一边是否与另一个三角形的任何一边相交。
在您的回程中,您还可以通过不检查other.contains(a) || other.contains(b) || other.contains(c)
来节省一些时间。由于other
被选为有效三角形,我们可以假设other
不包含三角形abc
中的任何点。
如果您的代码永远在运行,那么我愿意打赌,因为您没有检查三角形abc
是否等于另一个三角形。如果确实如此,那么你应该停止查看abc
,因为它已经被添加了!
请注意,根据您的伪代码,您的代码确实应该暂停,因为您只使用for循环,应该保证终止。也许您应该检查这些循环的退出条件:)
希望这有帮助!