大多数迭代算法都需要一个初始的空三角形来使球滚动。似乎常用的技巧只是使超级三角形与点集相比非常大。
但根据“数字食谱:科学计算的艺术”:
“...如果距离仅是有限的(到边界点),构造的三角剖分可能不是完全Delaunay。例如,它的外边界可能在不寻常的情况下略微凹陷,在订单上有小的负角度“实际”点集的直径除以“虚拟”(边界)点的距离。
那么有哪些选项可以用无限远的点来增加笛卡尔坐标,而不必将所有输入转换为不同的坐标系,例如齐次坐标?这些点如何与通常的几何谓词CCW和Incircle相符?
Incircle(a,b,c)Infinity - >假。条件是a,b,c是有限的。
但是当a,b,c中的一个是无限远点时怎么办?圆圈是否成为半平面,然后测试成为CCW检查?如果外接圆上的2个或更多点是无限的怎么办?圆圈是否扩展成一个完整的平面,导致测试始终产生真实? CCW怎么样?如何对与无穷远处有一个或多个点的线相关的点进行分类?
答案 0 :(得分:0)
我认为你通过尝试定义包含无限远距离点的几何的完整数学来让自己变得困难。对于准确计算Delaunay三角剖分的原始问题,这不是必需的。
我刚刚用Java编写了一个Delaunay生成器,它可以在这里找到: http://open.trickl.com/trickl-graph/index.html
请参阅http://open.trickl.com/trickl-graph/apidocs/index.html,特别是:
// Check if fourth point is within the circumcircle defined by the first three
private boolean isWithinCircumcircle(PlanarGraph<V, E> graph, V first,
V second,
V third,
V fourth) {
// Treat the boundary as if infinitely far away
Coordinate p = vertexToCoordinate.get(fourth);
if (PlanarGraphs.isVertexBoundary(graph, first)) {
return isLeftOf(third, second, p);
} else if (PlanarGraphs.isVertexBoundary(graph, second)) {
return isLeftOf(first, third, p);
} else if (PlanarGraphs.isVertexBoundary(graph, third)) {
return isLeftOf(second, first, p);
} else if (PlanarGraphs.isVertexBoundary(graph, fourth)) {
return false;
}
Coordinate a = vertexToCoordinate.get(first);
Coordinate b = vertexToCoordinate.get(second);
Coordinate c = vertexToCoordinate.get(third);
boolean within = (a.x * a.x + a.y * a.y) * getDblOrientedTriangleArea(b, c, p)
- (b.x * b.x + b.y * b.y) * getDblOrientedTriangleArea(a, c, p)
+ (c.x * c.x + c.y * c.y) * getDblOrientedTriangleArea(a, b, p)
- (p.x * p.x + p.y * p.y) * getDblOrientedTriangleArea(a, b, c) > 0;
return within;
}
这里,在检查外接圆条件时明确检查边界点,因此可以有效地将它们视为“无限”地离开。这比弄清楚所描述的几何含义要容易得多。
答案 1 :(得分:0)
通过在无穷远处添加点来实现Delaunay三角剖分非常容易。选择无限顶点的约定(例如,顶点索引-1)。
开始时,在从输入点集取得的4个非共面点之间创建一个初始有限四面体T0,然后创建四个无限四面体,将T0的每个面连接到无限顶点0 (并且不要忘记将它们沿着它们共同的无限面正确地互连)。
然后像往常一样逐个插入每个点p(Boyer-Watson算法),通过(1)计算包含点p(四分之一)的四面体T和(2)找到冲突区域,如下所示:
(1)locate未修改:你从随机有限四面体走到p。在步行期间,如果你到达一个无限四面体,那么你就停在那里(这意味着该点位于先前插入的点的凸包之外)
(2)确定冲突区域需要进行一些小修改:
点p与有限四面体T相冲突,如果它在其外接球体中(像往常一样)
对于无限四面体T =(p1,p2,p3,p4),p1,p2,p3,p4中的一个是无限顶点(例如p2,则T = (p1,无限,p3,p4))。要检查p是否与T冲突,用p替换无限顶点,并在我们的示例中计算四面体的签名体积:signed_volume(p1,p,p3,p4),如果它是正数,则T处于冲突中与p。如果是负数,则T与p不冲突。 如果p在T的三个有限顶点的支撑平面上正好,则如果T'与p冲突则T与p冲突,其中T'是与T相邻的四面体沿着T的有限面(等效地,可以检查p是否在T的有限面的外接圆中,而不是查询T'。
参见:
中的实现