【发布时间】:2012-04-26 19:39:48
【问题描述】:
我一直在研究Delaunay triangulation(不是作业),我想到了以下问题:给定平面上的一组点S(基数为n)和一组三角形T (应该是n-2的基数)——如何确定三角形集T是否形成一个德劳内三角剖分DT(S)?
第一个问题是 Delaunay 三角剖分不是唯一的,因此再次为点集重建它并与三角形集进行比较不会给我们答案。此外,最优的 Delaunay 三角剖分算法很难实现(但是,使用像 CGAL 这样的库就可以了)。
假设我们知道如何检查三角形集是否是三角剖分(不一定是 Delaunay)。那么我们应该使用 Delanuay 三角剖分的定义:对于三角剖分中的每个三角形t,S 中的任何点都严格位于t 的圆周内。这导致我们采用以下方法:
- 简单的方法。只需遍历
T,计算圆周并遍历S,检查点是否在圆周内。但是,这需要O(n^2)时间,这不是很理想。 - 魔法方法。同样,遍历
T并计算周长。如果有一点s在圆周内,则表示它到圆周中心的距离小于半径。使用S上的最近邻搜索结构,我们将加快我们的算法。例如,简单的kd-tree 结构平均会导致我们使用O(n log n)算法,而在最坏的情况下会导致O(n sqrt(n))。 - 有人知道更简单的方法吗?
现在让我们回到检查T 是否是三角剖分的问题。 S 的相等性和三角形顶点集等琐碎的前置要求的执行速度不会比 O(n log n) 快。剩下的——检查T 中的每两个三角形是否在一个共同的面上相交,或者根本不相交。
- 同样,我们可以通过迭代
T并再次迭代T来检查交叉点,但这是O(n^2)算法。 - 让我们想想«三角形
t1和t2相交»是什么意思?如果它们的边相交或者如果一个三角形完全位于另一个三角形中,则它们相交。与所有边相交的问题可以在O(n log n)时间使用Bentley-Ottmann algorithm 解决(最坏的情况是O((n + k) log n),其中k是相交的数量,但我们可以在找到第一个路口)。此外,我们没有认识到一个三角形完全包含另一个三角形的情况,但我相信我们可以修改 Bentley-Ottmann 算法以保持三角形穿过扫描线而不是线段,正如我所说,这产生了O(n log n)算法。但是,实现起来确实很复杂。 - 我考虑过迭代算法——让我们保持不相交(或仅通过边相交)三角形的结构(它应该与 kd-tree 非常相似)。然后我们尝试添加下一个三角形
t:首先检查t的任何顶点是否已经在其中一个三角形中——然后我们得到了一个交点。否则,将t添加到结构中。但是,如果我们希望O(log n)或O(sqrt(n))有时间用于搜索和添加查询,我们必须平衡这个结构的高度,这对于 kd-trees 来说也太难了。
那么,有人知道这个问题的简单解决方案吗?
【问题讨论】:
-
假设它是一个三角剖分,可以迭代测试每条边的合法性吗?另一个想法——你有没有想过对偶空间的问题?我们可以判断一个细分是否是 voronoi 图吗?
-
对于一般位置的点,DTs 实际上是唯一的。而且这种三角剖分的角度向量也是独一无二的!我的观点是,这不是排除方法的理由。
标签: computational-geometry triangulation kdtree