Skip to content

Commit b7c7b3e

Browse files
committed
improved kd-tree implementation
1 parent 2df79a3 commit b7c7b3e

File tree

3 files changed

+34
-23
lines changed

3 files changed

+34
-23
lines changed

kdtree.go

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,24 @@ package sketchy
33
import "github.com/tdewolff/canvas"
44

55
type KDTree struct {
6-
point Point
6+
point *Point
77
region Rect
88
left *KDTree
99
right *KDTree
1010
}
1111

12-
func NewKDTree(p Point, r Rect) *KDTree {
12+
func NewKDTree(r Rect) *KDTree {
1313
return &KDTree{
14-
point: p,
14+
point: nil,
15+
region: r,
16+
left: nil,
17+
right: nil,
18+
}
19+
}
20+
21+
func NewKDTreeWithPoint(p Point, r Rect) *KDTree {
22+
return &KDTree{
23+
point: &p,
1524
region: r,
1625
left: nil,
1726
right: nil,
@@ -29,8 +38,8 @@ func (k *KDTree) Insert(p Point) {
2938
func (k *KDTree) Query(r Rect) []Point {
3039
var results []Point
3140
if k.IsLeaf() {
32-
if r.ContainsPoint(k.point) {
33-
results = append(results, k.point)
41+
if r.ContainsPoint(*k.point) {
42+
results = append(results, *k.point)
3443
}
3544
return results
3645
}
@@ -77,11 +86,16 @@ func (k *KDTree) DrawWithPoints(s float64, ctx *canvas.Context) {
7786
}
7887

7988
func (k *KDTree) Clear() {
89+
k.point = nil
8090
k.left = nil
8191
k.right = nil
8292
}
8393

8494
func (k *KDTree) insert(p Point, d int) {
95+
if k.point == nil {
96+
k.point = &p
97+
return
98+
}
8599
if d%2 == 0 { // compare x value
86100
if p.X < k.point.X {
87101
if k.left == nil {
@@ -91,7 +105,7 @@ func (k *KDTree) insert(p Point, d int) {
91105
W: k.point.X - k.region.X,
92106
H: k.region.H,
93107
}
94-
k.left = NewKDTree(p, rect)
108+
k.left = NewKDTreeWithPoint(p, rect)
95109
} else {
96110
k.left.insert(p, d+1)
97111
}
@@ -103,7 +117,7 @@ func (k *KDTree) insert(p Point, d int) {
103117
W: k.region.W - (k.point.X - k.region.X),
104118
H: k.region.H,
105119
}
106-
k.right = NewKDTree(p, rect)
120+
k.right = NewKDTreeWithPoint(p, rect)
107121
} else {
108122
k.right.insert(p, d+1)
109123
}
@@ -117,7 +131,7 @@ func (k *KDTree) insert(p Point, d int) {
117131
W: k.region.W,
118132
H: k.point.Y - k.region.Y,
119133
}
120-
k.left = NewKDTree(p, rect)
134+
k.left = NewKDTreeWithPoint(p, rect)
121135
} else {
122136
k.left.insert(p, d+1)
123137
}
@@ -129,7 +143,7 @@ func (k *KDTree) insert(p Point, d int) {
129143
W: k.region.W,
130144
H: k.region.H - (k.point.Y - k.region.Y),
131145
}
132-
k.right = NewKDTree(p, rect)
146+
k.right = NewKDTreeWithPoint(p, rect)
133147
} else {
134148
k.right.insert(p, d+1)
135149
}
@@ -139,7 +153,7 @@ func (k *KDTree) insert(p Point, d int) {
139153

140154
func (k *KDTree) reportSubtree() []Point {
141155
var results []Point
142-
results = append(results, k.point)
156+
results = append(results, *k.point)
143157
if k.left != nil {
144158
results = append(results, k.left.reportSubtree()...)
145159
}
@@ -150,6 +164,9 @@ func (k *KDTree) reportSubtree() []Point {
150164
}
151165

152166
func (k *KDTree) draw(ctx *canvas.Context, depth int, pointSize float64) {
167+
if k.point == nil {
168+
return
169+
}
153170
if depth%2 == 0 {
154171
ctx.MoveTo(k.point.X, k.region.Y)
155172
ctx.LineTo(k.point.X, k.region.Y+k.region.H)

kdtree_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88

99
func TestKDTree_Insert(t *testing.T) {
1010
assert := assert.New(t)
11-
tree := NewKDTree(Point{X: 50, Y: 50}, Rect{X: 0, Y: 0, W: 100, H: 100})
11+
tree := NewKDTreeWithPoint(Point{X: 50, Y: 50}, Rect{X: 0, Y: 0, W: 100, H: 100})
1212
assert.Equal(1, tree.Size())
1313
}
1414

@@ -25,9 +25,9 @@ func BenchmarkKDTree_Insert(b *testing.B) {
2525
}
2626
b.ResetTimer()
2727
for i := 0; i < b.N; i++ {
28-
tree := NewKDTree(points[0], Rect{X: 0, Y: 0, W: w, H: h})
29-
for j := 1; j < len(points); j++ {
30-
tree.Insert(points[j])
28+
tree := NewKDTree(Rect{X: 0, Y: 0, W: w, H: h})
29+
for _, p := range points {
30+
tree.Insert(p)
3131
}
3232
}
3333
}

visual_tests/kdtree_mouse/kdtree_mouse.go

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,12 @@ package main
22

33
import (
44
"flag"
5+
"github.com/aldernero/sketchy"
6+
"github.com/hajimehoshi/ebiten/v2"
57
"github.com/hajimehoshi/ebiten/v2/inpututil"
68
"github.com/tdewolff/canvas"
79
"image/color"
810
"log"
9-
"math/rand"
10-
11-
"github.com/aldernero/sketchy"
12-
"github.com/hajimehoshi/ebiten/v2"
1311
)
1412

1513
var kdtree *sketchy.KDTree
@@ -62,17 +60,13 @@ func main() {
6260
s.Init()
6361
w := s.Width()
6462
h := s.Height()
65-
point := sketchy.Point{
66-
X: sketchy.Map(0, 1, 0.4*w, 0.6*w, rand.Float64()),
67-
Y: sketchy.Map(0, 1, 0.4*h, 0.6*h, rand.Float64()),
68-
}
6963
rect := sketchy.Rect{
7064
X: 0,
7165
Y: 0,
7266
W: w,
7367
H: h,
7468
}
75-
kdtree = sketchy.NewKDTree(point, rect)
69+
kdtree = sketchy.NewKDTree(rect)
7670
ebiten.SetWindowSize(int(s.ControlWidth+s.SketchWidth), int(s.SketchHeight))
7771
ebiten.SetWindowTitle("Sketchy - " + s.Title)
7872
ebiten.SetWindowResizable(false)

0 commit comments

Comments
 (0)