Sie sind auf Seite 1von 13

16/8/2014

A Simple QuadTree Implementation in C# - CodeProject

10,798,674 members

home
features

articles

quick answers

community

Sign in

discussions
Search for articles, questions, tips

help

Articles General Programming Algorithms & Recipes Computational Geometry

A Simple QuadTree
Implementation in C#
Michael Coyle, 29 Oct 2008
4.70 (21 votes)
Rate this:

A QuadTree is a spatial
indexing method well suited to 2 dimensional spatial problems

Download demo project - 10.81 KB


Download source - 19.82 KB

http://www.codeproject.com/Articles/30535/A-Simple-QuadTree-Implementation-in-C

1/13

16/8/2014

A Simple QuadTree Implementation in C# - CodeProject

Introduction
A QuadTree is a spatial partitioning strategy used to make
queries on relationships between 2D spatial data such as
coordinates in a Geographic Information System (GIS), or the
location of objects in a video game. For instance, you may
need to know all of the objects within a region on a map, test
whether objects are visible by a camera, or optimize a collision
detection algorithm.
The QuadTree is so named because it recursively partitions
http://www.codeproject.com/Articles/30535/A-Simple-QuadTree-Implementation-in-C

2/13

16/8/2014

A Simple QuadTree Implementation in C# - CodeProject

regions into four parts, with leaf nodes containing references


to the spatial objects. Querying the QuadTree is a function of
traversing the tree nodes that intersect the query area.
The OctTree is the analogous structure used for 3 dimensional
problems.
For a masterful collection of demos and variations on the
QuadTree and other spatial indexing methods, see Frantisek
Brabec and Hanan Samet's site, or use the references at the
end of this article.

Background
There are many spatial partitioning methods, each with the
goal of providing an efficient way of determining the position
of an item in a spatial domain. For example, a database query
can be considered as a graphical problem. Consider a query on
a database containing date of birth and income: a query
against all people between 35 and 50 years of age and
incomes between 30,000 and 60,000 per year is the same as a
query for all restaurants in the city of Vancouver: they are 2
dimensional spatial queries.
Several spatial indexing methods are more efficient in time and
space, and are easily generalizable to higher dimensions.
However, the QuadTree is specialized to the 2D domain, and it
is easy to implement.

Algorithm
The general strategy of the QuadTree is to build a tree
structure that partitions a region recursively into four parts, or
Quads. Each Quad can further partition itself as necessary. A
pre-requisite is that you must know the bounds of the area to
be encompassed; the basic algorithm does not lend itself to
the addition or removal of areas under consideration without
rebuilding the index.

Insertion
When an item is inserted into the tree, it is inserted into a
Quad that encompasses the item's position (or spatial index).
Each Quad has a maximum capacity. When that capacity is
exceeded, the Quad splits into four sub-quads that become
child nodes of the parent Quad, and the items are
http://www.codeproject.com/Articles/30535/A-Simple-QuadTree-Implementation-in-C

3/13

16/8/2014

A Simple QuadTree Implementation in C# - CodeProject

redistributed into the new leaves of the QuadTree. Some


variations set the maximum capacity to one, and subdivide
until each leaf contains at most a single item (Adaptive
QuadTree).

Querying
To query a QuadTree for items that are inside a particular
rectangle, the tree is traversed. Each Quad is tested for
intersection with the query area.
1. Quads that do not intersect are not traversed, allowing
large regions of the spatial index to be rejected rapidly.

2. Quads that are wholly contained by the query region


have their sub-trees added to the result set without
further spatial tests: this allows large regions to be
covered without further expensive operations.

3. Quads that intersect are traversed, with each sub-Quad


tested for intersection recursively.
http://www.codeproject.com/Articles/30535/A-Simple-QuadTree-Implementation-in-C

4/13

16/8/2014

A Simple QuadTree Implementation in C# - CodeProject

4. When a Quad is found with no sub-Quads, its contents


are individually tested for intersection with the query
rectangle.

Other Operations
Other operations on the QuadTree could include:
1. Deletion: An object is removed from the QuadTree,
empty quads are removed
2. Merge: Two quadtrees are merged, indexes are rebuilt
3. Nearest Neighbour: Common to more advanced spatial
indexes, a Query could ask for the nearest neighbours
to a given object. A simple implementation would be to
take the object's bounding rect and inflate it by an
amount based on the neighbor proximity. Objects in the
result set would be sorted by increasing distance.
These operations are not demonstrated in this code.

Variation
This implementation of the QuadTree has the following
variations:
The QuadTree has been changed to index items with
rectangular bounds rather than points. This allows it to be
used with lines, and polygons.
On insertion, new quads are created until there are no
Quads able to contain an item's rectangle. IE: the item is
inserted into the smallest quad that will contain it.
There is no maximum number of items in a Quad, there
is a minimum Quad size (necessary to avoid massive
tree growth if an item happens to have a very small
http://www.codeproject.com/Articles/30535/A-Simple-QuadTree-Implementation-in-C

5/13

16/8/2014

A Simple QuadTree Implementation in C# - CodeProject

area).
Because the Quad an item is stored in is related to the
size of the item, both leaf nodes and parent nodes store
items.
The QuadTree's performance will be severely impacted if
there are many large items.
The Quadtree's performance will be best when the size
of most items are close to the minimum quad size.
After writing this code, I find that this particular variation bears
a striking resemblance to the "MX-CIF QuadTree".
Note: There are other operations on QuadTrees such as
deleting a node, or find the nearest neighbour. These are not
supported in this implementation.
The following two diagrams show the spatial relationship of
the QuadTree with the tree structure. The coloured regions
represent objects in the spatial domain. Those that are entirely
within a quad are shown in the tree structure in their smallest
enclosing quad. You can see that the green shape, since it
intersects two of the highest level Quads and does not fit into
either is placed in the root quad. The red and purple shapes
are placed in child nodes at level one since they are the largest
enclosing Quads. The blue shape is at level three along with
the orange shape. The Yellow shape is at level four. This tree is
adaptive in that it does not create quads until insertion is
requested.

http://www.codeproject.com/Articles/30535/A-Simple-QuadTree-Implementation-in-C

6/13

16/8/2014

A Simple QuadTree Implementation in C# - CodeProject

Using the Code


The Qu
adTree class is a generic class. The generic parameter
has a restriction that it must inherit from the I
HasRect
interface which defines a property R
ectangle. Creating a
QuadTree requires an area, the demo application uses the
main form's C
lientRectangle.
Collapse | Copy Code

QuadTree<Item> m_quadTree = new QuadTree<Item>


(this.ClientRectangle);

Inserting items into the Q


uadTree is done on a left mouse
click, querying items in a Qu
adTree is done with a right
mouse drag:
Collapse | Copy Code

private void MainForm_MouseUp(object sender,


MouseEventArgs e)
{
if (m_dragging && e.Button== MouseButtons.Right)
{
m_selectedItems =
m_quadTree.Query(m_selectionRect);
m_dragging = false;
}
else
{
Random rand = new
Random(DateTime.Now.Millisecond);
m_quadTree.Add(new Item(e.Location,
rand.Next(25) + 4)); } Invalidate();
}
}

http://www.codeproject.com/Articles/30535/A-Simple-QuadTree-Implementation-in-C

7/13

16/8/2014

A Simple QuadTree Implementation in C# - CodeProject

Run the demo application, and left click anywhere in the client
rectangle: an object is inserted at the click point with a random
size. Right-click and drag: a selection rectangle is created.
Release the mouse button: the Q
uadTree is queried with the
selection rectangle. The Qu
adTree renderer draws the
QuadTree nodes and the objects in the QuadTree in random
colours. It also draws the selection region and highlights the
selected nodes.

Performance
There are two components of Qu
adTree performance:
insertion and query. Insertion can be very expensive because it
involves several intersection tests per item to be inserted. The
number of tests depends on the size of the region (the root of
the Qu
adTree) and on the minimum Quad size configured.
These two numbers have to be tuned per application. Loading
many items into the Q
uadTree (bulk load, or indexing) tends
to be very CPU intensive. This overhead may not be
acceptable; consider storing the Q
uadTree structure on disk
(not covered in this article).
The Qu
adTree is designed to be faster at querying the spatial
domain than iteration, but the performance of the index
depends on the distribution of objects in the domain. If items
are clustered together, the tree tends to have many items in
one branch which defeats the strategy of being able to cull
large regions, and reduce the number of intersection tests. The
worst case performance happens when all objects are in one
small cluster that is the same size as the smallest Quad; in this
case the performance of the Qu
adTree will be slightly worse
than just iterating through all objects.
If items are uniformly distributed across the spatial domain,
performance is approximately O(n*log n).

Points of Interest
Generic implementation; allows you to use it with any
class that implements I
HasRectinterface.
Colour used to draw the node is stored in an hashtable;
allows the colour of the Quad on screen to be constant
over the life of the Qu
adTree.
In the Q
uadTreeRendererclass, note the anonymous
delegate used to draw the Q
uadTreeNodes; allows the
QuadTree to be tested, and visualized, without adding
http://www.codeproject.com/Articles/30535/A-Simple-QuadTree-Implementation-in-C

8/13

16/8/2014

A Simple QuadTree Implementation in C# - CodeProject

specific code to the class to do so.

References
H. Samet, The Design and Analysis of Spatial Data
Structures, Addison-Wesley, Reading, MA, 1990. ISBN
0-201-50255-0
H. Samet, Applications of Spatial Data Structures:
Computer Graphics, Image Processing, and GIS,
Addison-Wesley, Reading, MA, 1990. ISBN 0-20150300-0.
Mark de Berg, Marc van Kreveld, Mark Overmars,
Otfried Schwarzkopf, Computational Geometry:
Algorithms and Applications, 2nd Edition, SpringerVerlag 2000 ISBN: 3-540-65620-0

History
Initial version with regions and simple Insert and Query
operations, demo application

License
This article, along with any associated source code and files, is
licensed under The Code Project Open License (CPOL)

Share
EMAIL

About the Author

http://www.codeproject.com/Articles/30535/A-Simple-QuadTree-Implementation-in-C

9/13

16/8/2014

A Simple QuadTree Implementation in C# - CodeProject

Michael Coyle
Architect Blue Toque Software
Canada
I've been lead architect in several software companies. I've
worked in the Justice and Public Safety area for the last 7
years, writing facial recognition, arrest and booking software
and emergency management/GIS software. Prior to that I
worked in the games industry with 3D animation.
Currently I'm working on some GIS/mapping software for
outdoor enthusiasts. I intend to spin off portions of this into
the open source community as time permits.
Article
Browse
Follow
on Code Twitter

Google

LinkedIn

Stats
Revisions (2)

Article Top

Alternatives
Comments (45)

Tagged as
.NET2.0

Comments and Discussions


C#2.0
C#3.0
C#
.NET
You must Sign In to use this message board.
Dev
Intermediate
Search Comments
Profile popups Spacing Relaxed
http://www.codeproject.com/Articles/30535/A-Simple-QuadTree-Implementation-in-C

Go
Noise Medium
10/13

16/8/2014

A Simple QuadTree Implementation in C# - CodeProject

Layout Normal

Per page 25

Update

First Prev Next

delete a
item

Member 10665902

My vote
of 5

Lowrenz

1-Mar-14 5:22

Count

Member 10357716

4-Nov-13 4:24

Re:
Count
Re:
Count
Traversing
through
all the
nodes
present in
a
QuadTree
Re:
Traversing
through
all the
nodes
present in
a
QuadTree
Point
variant?
Re:
Point
variant?
Re:
Point

Michael Coyle

Member 10357716

sleekFish

Michael Coyle

Thomas Schmidt

Michael Coyle

Thomas Schmidt

http://www.codeproject.com/Articles/30535/A-Simple-QuadTree-Implementation-in-C

23-Mar-14 21:37

4-Nov-13 6:04

4-Nov-13 7:25

10-Aug-13 22:42

6-Sep-13 7:27

2-Apr-12 21:15

4-Apr-12 11:12

4-Apr-12 11:20

11/13

16/8/2014

A Simple QuadTree Implementation in C# - CodeProject

variant?

Re:
Point
variant?

Michael Coyle

How could I use


this with
geocoordinates?

Clinton Sanchez

Re: How could I


use this with
geocoordinates?

Michael Coyle

4-Apr-12 11:21

29-Feb-12 19:09

1-Mar-12 10:47

My vote
of 5

manoj kumar choubey

19-Feb-12 21:36

Great
article

Harvey Green

25-Sep-11 20:45

thanks
michael

Kiraya

Thank you
for this
great
contribution

George Mamaladze

Re: Thank
you for this
great
contribution
Re: Thank
you for this
great
contribution
Filebased
solution

Michael Coyle

George Mamaladze

walterman

http://www.codeproject.com/Articles/30535/A-Simple-QuadTree-Implementation-in-C

8-Sep-11 22:21

10-Jul-11 9:47

10-Jul-11 10:21

11-Jul-11 11:49

13-Oct-10 11:38

12/13

16/8/2014

A Simple QuadTree Implementation in C# - CodeProject

Re: Filebased
solution
[modified]

13-Oct-10 12:19

Michael Coyle

My vote
of 2

chengiz5

26-Aug-10 5:40

Access C#
dll from
vb.net

ralstogj

9-Sep-09 11:10

Re:
Access
C# dll
from
vb.net
Re:
Access
C# dll
from
vb.net

9-Sep-09 12:50

Michael Coyle

9-Sep-09 12:59

ralstogj

Last Visit: 31-Dec-99 18:00


Aug-14 4:45

Last Update: 15-

General
News
Suggestion
Answer
Joke
Rant
Admin

Refresh

Question

1 2 Next

Bug

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch


threads, Ctrl+Shift+Left/Right to switch pages.
Permalink | Advertise | Privacy | Mobile
Web04 | 2.8.140814.1 | Last Updated 30 Oct 2008

Layout: fixed | fluid

http://www.codeproject.com/Articles/30535/A-Simple-QuadTree-Implementation-in-C

Article Copyright 2008 by Michael Coyle


Everything else Copyright CodeProject, 1999-2014
Terms of Service

13/13

Das könnte Ihnen auch gefallen