-
Notifications
You must be signed in to change notification settings - Fork 0
/
QuadTree.cs
121 lines (100 loc) · 3.4 KB
/
QuadTree.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
using System;
using System.Collections.Generic;
using Avalonia;
using Avalonia.Media;
namespace AvaloniaQuadTree
{
public class QuadTree
{
public QuadTree(Rect bounds, int capacity)
{
mBounds = bounds;
mCapacity = capacity;
mPoints = new List<Point>();
mBrush = new SolidColorBrush(Colors.White);
/*new SolidColorBrush(Color.FromRgb(
(byte)mRandom.Next(0, 255),
(byte)mRandom.Next(0, 255),
(byte)mRandom.Next(0, 255)));*/
}
public bool Insert(Point point)
{
if (!mBounds.Contains(point))
return false;
if (mPoints.Count < mCapacity - 1)
{
mPoints.Add(point);
return true;
}
if (!mIsDivided)
{
Subdivide();
}
if (mNorthEast.Insert(point))
return true;
if (mNorthWest.Insert(point))
return true;
if (mSouthEast.Insert(point))
return true;
if (mSouthWest.Insert(point))
return true;
return false;
}
public List<Point> Query(Rect range)
{
List<Point> result = new List<Point>();
if (!mBounds.Intersects(range))
return result;
foreach (Point p in mPoints)
{
if (range.Contains(p))
result.Add(p);
}
if (mIsDivided)
{
result.AddRange(mNorthEast.Query(range));
result.AddRange(mNorthWest.Query(range));
result.AddRange(mSouthEast.Query(range));
result.AddRange(mSouthWest.Query(range));
}
return result;
}
void Subdivide()
{
Rect nw = new Rect(mBounds.X, mBounds.Y, mBounds.Width / 2, mBounds.Height / 2);
Rect ne = new Rect(mBounds.X + mBounds.Width / 2, mBounds.Y, mBounds.Width / 2, mBounds.Height / 2);
Rect sw = new Rect(mBounds.X, mBounds.Y + mBounds.Height / 2, mBounds.Width / 2, mBounds.Height / 2);
Rect se = new Rect(mBounds.X + mBounds.Width / 2, mBounds.Y + mBounds.Height / 2, mBounds.Width / 2, mBounds.Height / 2);
mNorthWest = new QuadTree(nw, mCapacity);
mNorthEast = new QuadTree(ne, mCapacity);
mSouthWest = new QuadTree(sw, mCapacity);
mSouthEast = new QuadTree(se, mCapacity);
mIsDivided = true;
}
internal void Render(DrawingContext context)
{
context.DrawRectangle(null, new Pen(mBrush, 0.5), mBounds);
if (mIsDivided)
{
mNorthWest.Render(context);
mNorthEast.Render(context);
mSouthWest.Render(context);
mSouthEast.Render(context);
}
foreach (Point p in mPoints)
{
context.FillRectangle(mBrush, new Rect(p.X - 2, p.Y - 2, 4, 4));
}
}
Rect mBounds;
int mCapacity;
List<Point> mPoints = new List<Point>();
bool mIsDivided;
QuadTree mNorthWest;
QuadTree mNorthEast;
QuadTree mSouthWest;
QuadTree mSouthEast;
Brush mBrush;
static Random mRandom = new Random();
}
}