Click here to Skip to main content
Click here to Skip to main content

Fortune's Voronoi algorithm implemented in C#

By , 21 Apr 2013
 

 

NOTE: Code has moved to Google Code! 

Introduction 

Given a set of two dimensional vectors (or data points), a Voronoi graph is a separation of those points into compartments where all points inside one compartment are closer to the contained data point than to any other data point. I won't give any demonstration here, but if you want to know more about Voronoi graphs, check out this.

The applications of Voronoi graphs are quite broad. Very useful for a lot of optimization problems (in most cases, the Delaunay Triangulation which can be easily derived from a Vononoi graph is used there), it ranges to computing topological maps from bitmaps.

[This is an article for freaks. After a rather painful experience writing the thing I hope it will benefit everyone who is looking for this algorithm in a civilized language (or simply does not want to use Fortune's original C implementation).]

In 1987, Steve Fortune described an algorithm to compute such a graph by using a sweep line in combination with a binary tree. A PowerPoint explanation of the algorithm (the one I used to implement it) can be found here. Note that I did not use the linked data structure to represent a graph - I think that is an unnecessary difficulty in the age of ArrayLists and HashSets.

The Implementation

Data points are represented by my own Vector class. It can do much more than needed here (but there was no reason to strip it before bringing it) but I won't explain it here. The most important fact is that although working with doubles the Vector class automatically rounds values to 10 digits (or whatever is set in the Vector.Precision field). Yes, sadly, this is very important if you want to sort of compare doubles.

A VoronoiGraph is a class that only contains a HashSet of vertices (as 2D vectors) and a HashSet of VoronoiEdges - each with references to the left and right data point and (of course) the two vertices that bound the edge. If the edge is (partially or completely) unbounded, the vector Fortune.VVUnknown is used.

BinaryPriorityQueue is used for the sweep line event queue.

Usage

The algorithm itself (Fortune.ComputeVoronoiGraph(IEnumerable)) takes any IEnumerable containing only two dimensional vectors. It will return a VoronoiGraph. The algorithm's complexity is O(n ld(n)) with a factor of about 10 microseconds on my machine (2GHz).

License

This article, along with any associated source code and files, is licensed under The Mozilla Public License 1.1 (MPL 1.1)

About the Author

BenDi
Software Developer (Senior)
Germany Germany
Member
I did my diploma in Dresden and Sydney where I dealt with algorithms, agents and other cool AI stuff. Now I moved to Frankfurt to work on my PhD dealing with software structures for artificial intelligence systems. If I can, I do things in C# and ASP.NET, but if I have to, my C++, Java and SQL are not that bad.
Long Live .NET.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionMESSAGE FROM THE OWNER: Help improve this project on Google Code!memberBenDi21 Apr '13 - 6:59 
QuestionRounding error when creating circles for new nodesmemberBwd Yeti19 Apr '13 - 0:50 
AnswerRe: Rounding error when creating circles for new nodesmemberBenDi21 Apr '13 - 6:56 
QuestionDon't know where to start [modified]memberMember 998975818 Apr '13 - 16:58 
GeneralMy vote of 4memberPehGuevara7 Mar '13 - 21:40 
QuestionGetting regions from graphmemberBixel6 Feb '13 - 14:14 
AnswerRe: Getting regions from graphmemberBenDi6 Feb '13 - 23:50 
GeneralRe: Getting regions from graphmemberBixel7 Feb '13 - 12:06 
QuestionSeparating braches of a medial axis sampled from inner voronoi points of a polygonmemberMember 917583217 Jul '12 - 16:19 
QuestionFinding distance for VoronoiGraph vertizes representing Medial Axis of closed boundarymemberMember 917583214 Jul '12 - 5:02 
GeneralRe: Finding distance for VoronoiGraph vertizes representing Medial Axis of closed boundarymemberBenDi15 Jul '12 - 0:27 
AnswerRe: Finding distance for VoronoiGraph vertizes representing Medial Axis of closed boundarymemberKenneth Haugland17 Jul '12 - 9:31 
GeneralRe: Finding distance for VoronoiGraph vertizes representing Medial Axis of closed boundarymemberMember 917583217 Jul '12 - 16:11 
QuestionIs there a way to construct polygons from all the edges ? And how ?memberseb.493 Jun '12 - 21:36 
QuestionPossible issue. When I draw 2 points I haven't 2 areamemberseb.4930 May '12 - 23:59 
AnswerRe: Possible issue. When I draw 2 points I haven't 2 areamemberBenDi31 May '12 - 3:11 
GeneralRe: Possible issue. When I draw 2 points I haven't 2 areamemberseb.4931 May '12 - 4:44 
GeneralRe: Possible issue. When I draw 2 points I haven't 2 areamemberBenDi31 May '12 - 7:00 
GeneralRe: Possible issue. When I draw 2 points I haven't 2 areamemberseb.4931 May '12 - 9:53 
QuestionThis code is shittedmemberMember 868370514 May '12 - 4:42 
QuestionAny way to handle boundaries and holes?memberJames Maeding16 Dec '10 - 11:03 
AnswerRe: Any way to handle boundaries and holes?memberxinaesthetic30 Sep '11 - 7:38 
GeneralMy vote of 5membermaurice.calvert31 Aug '10 - 23:08 
GeneralRe: My vote of 5memberMember 868370514 May '12 - 4:45 
GeneralRe: My vote of 5membermaurice.calvert14 May '12 - 5:32 
GeneralRe: My vote of 5memberMember 868370514 May '12 - 21:38 
GeneralRe: My vote of 5membermaurice.calvert15 May '12 - 4:56 
Generalplease help soonmemberdaskan8 Aug '09 - 1:55 
QuestionVoronoi CellsmemberC-Bl27 Jul '09 - 23:08 
Answer3 data points casememberSOAD_21 Jun '09 - 6:08 
GeneralRe: 3 data points casememberrhill-ca26 Jun '09 - 6:45 
GeneralThiessen PolygonsmemberSOAD_19 Jun '09 - 14:46 
GeneralAnother wrong vertexmemberSunil Terkar11 May '09 - 2:04 
GeneralRe: Another wrong vertexmemberBenDi11 May '09 - 10:03 
GeneralRe: Another wrong vertexmemberSunil Terkar12 May '09 - 0:37 
GeneralRe: Another wrong vertexmemberSunil Terkar12 May '09 - 5:09 
GeneralRe: Another wrong vertexmemberrhill-ca26 Jun '09 - 6:34 
GeneralShort of one edge and one vertexmemberSunil Terkar5 May '09 - 23:11 
GeneralRe: Short of one edge and one vertexmemberrhill-ca26 Jun '09 - 6:31 
Generalmedial axismemberled16 Apr '09 - 9:38 
GeneralThanks!memberReconstructivism30 Mar '09 - 2:48 
GeneralRaysmemberWayne Romer22 Mar '09 - 20:55 
GeneralRe: RaysmemberReconstructivism30 Mar '09 - 2:56 
GeneralRe: RaysmemberBenDi30 Mar '09 - 8:57 
GeneralRe: RaysmemberPavel Vladov29 Apr '09 - 0:54 
GeneralRe: RaysmemberBenDi29 Apr '09 - 9:49 
GeneralRe: RaysmemberPavel Vladov29 Apr '09 - 23:39 
GeneralRe: RaysmemberBenDi30 Apr '09 - 8:04 
GeneralRe: RaysmemberPavel Vladov30 Apr '09 - 22:36 
GeneralRe: RaysmemberSlagh14 May '09 - 22:10 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 22 Apr 2013
Article Copyright 2005 by BenDi
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid