65.9K
CodeProject 正在变化。 阅读更多。
Home

C# 实现 Fortune's Voronoi 算法

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.95/5 (31投票s)

2005年8月10日

MPL

2分钟阅读

viewsIcon

489135

downloadIcon

3422

使用 C# 实现 Fortune 算法来计算二维 Voronoi 图。

注意:代码已迁移至 Google Code 

介绍 

给定一组二维向量(或数据点),Voronoi 图是将这些点划分为若干区域,其中一个区域内的所有点都比任何其他数据点更接近该区域内包含的数据点。我在这里不进行任何演示,但如果您想了解更多关于 Voronoi 图的信息,请查看 这里

Voronoi 图的应用非常广泛。对于许多优化问题非常有用(在大多数情况下,可以从 Voronoi 图轻松推导出的 Delaunay 三角剖分在那里使用),甚至可以用于从位图中计算拓扑地图。

[这篇文章是为极客准备的。在编写这个东西之后,我希望它能帮助所有正在寻找这种算法的人,并且使用一种文明的语言(或者只是不想使用 Fortune 最初的 C 实现)。]

1987 年,Steve Fortune 描述了一种使用扫描线结合二叉树来计算此类图的算法。关于该算法的 PowerPoint 解释(我用来实现它的那个)可以在 这里找到。请注意,我没有使用链接的数据结构来表示图 - 我认为在 ArrayListHashSet 时代,这是一种不必要的困难。

实现

数据点由我自己的 Vector 类表示。它比这里需要的能做更多(但没有理由在引入它之前将其剥离),但我不会在这里解释它。最重要的是,虽然使用 double 类型,Vector 类会自动将值四舍五入到 10 位数字(或 Vector.Precision 字段中设置的任何位数)。是的,不幸的是,如果您想比较 double 类型,这非常重要。

VoronoiGraph 是一个类,它只包含一个 HashSet 的顶点(作为二维向量)和一个 HashSetVoronoiEdge - 每个顶点都引用左侧和右侧的数据点以及(当然)限定该边的两个顶点。如果边是(部分或完全)无界的,则使用向量 Fortune.VVUnknown

BinaryPriorityQueue 用于扫描线事件队列。

用法

该算法本身(Fortune.ComputeVoronoiGraph(IEnumerable))接受任何仅包含二维向量的 IEnumerable。它将返回一个 VoronoiGraph。该算法的复杂度为 O(n ld(n)),在我的机器(2GHz)上大约有 10 微秒的因子。

© . All rights reserved.