-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathKDTree.java
113 lines (99 loc) · 3.27 KB
/
KDTree.java
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
package bearmaps;
import java.util.List;
public class KDTree implements PointSet{
private final PointComparatorNS NScomp = new PointComparatorNS();
private final PointComparatorEW EScomp = new PointComparatorEW();
private TreeNode root;
private class TreeNode{
Point pos;
TreeNode Left = null;
TreeNode Right = null;
public TreeNode(Point p){
pos = p;
}
public double distance(Point p){
return Point.distance(pos, p);
}
}
public KDTree(List<Point> points){
Boolean boo = false;
root = helpInsert(points.get(0), boo, root);
for (int i = 1; i<points.size();i++){
helpInsert(points.get(i), boo, root);
}
}
private TreeNode helpInsert(Point p, boolean depth, TreeNode current){
if(current == null){
return new TreeNode(p);
}
if(current.pos.equals(p)){
return current;
}
int child;
if(depth){
child = NScomp.compare(current.pos, p);
if(0 < child){
current.Left = helpInsert(p, !depth, current.Left);
}else{
current.Right= helpInsert(p, !depth, current.Right);
}
}else{
child = EScomp.compare(current.pos, p);
if(child > 0){
current.Left= helpInsert(p,!depth, current.Left);
}else{
current.Right= helpInsert(p,!depth, current.Right);
}
}
return current;
}
@Override
public Point nearest(double x, double y){
Point look = new Point(x, y);
TreeNode start = new TreeNode(root.pos);
Point p = nearhelp(root, look, start, false);
return p;
}
private Point nearhelp(TreeNode current, Point look4, TreeNode best, boolean boo){
if(current == null){
return best.pos;
}
TreeNode goodside;
TreeNode badside;
if(current.distance(look4) < best.distance(look4)){
best = new TreeNode(current.pos);
}
if(boo){
if(NScomp.compare(look4, current.pos) < 0){
goodside = current.Left;
badside = current.Right;
}
else {
goodside = current.Right;
badside = current.Left;
}
}
else{
if(EScomp.compare(look4, current.pos) < 0){
goodside = current.Left;
badside = current.Right;
}
else {
goodside = current.Right;
badside = current.Left;
}
}
best.pos = nearhelp(goodside, look4, best, !boo);
if(boo) {
if (Math.pow(look4.getY() - current.pos.getY(), 2) < Point.distance(best.pos, look4)) {
best.pos = nearhelp(badside, look4, best, !boo);
}
}
else{
if (Math.pow(look4.getX() - current.pos.getX(), 2) < Point.distance(best.pos, look4)) {
best.pos = nearhelp(badside, look4, best, !boo);
}
}
return best.pos;
}
}