-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathClosestPoint.java
145 lines (120 loc) · 3.17 KB
/
ClosestPoint.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*************************************************************************
* Name: Uros Slana
* Email: urossla(at)gmail.com
*
* Compilation: javac ClosestPoint.java
* Dependencies: Point.java, KdTree.java, KdNode.java
*
* Description: Finds the closest points from a specified set of points
*
* % java ClosestPoint set_of_points.txt set_of_querry_points.txt
* 0.4 0.5
* 0.5 0.3
* 0.34 0.56
* ...
*************************************************************************/
import java.io.File;
import java.util.Scanner;
import java.util.LinkedList;
import java.io.FileNotFoundException;
public class ClosestPoint {
KdTree kdtree;
public ClosestPoint(Iterable<Point> points) {
kdtree = new KdTree();
for (Point p: points) {
kdtree.insert(p);
}
}
public Point nearestPoint(Point p) {
return nearestPoint(p, kdtree.root(), 1, Double.POSITIVE_INFINITY);
}
private Point nearestPoint(Point p, KdNode cur, int depth, double min) {
if (cur == null) {
return null;
}
KdNode up; //go to other side where point p is
KdNode down; //go to side where point p is
Point champ; //point which is closest to p
Point other; //maybe another point is closer than champ
double dist;
double perpendicularDist;
//split vertical
if (depth%2 == 1) {
perpendicularDist = Math.abs(cur.p.x - p.x);
if (p.x < cur.p.x) {
down = cur.lb;
up = cur.rt;
}
else {
down = cur.rt;
up = cur.lb;
}
}
//split horizontal
else {
perpendicularDist = Math.abs(cur.p.y - p.y);
if (p.y < cur.p.y) {
down = cur.lb;
up = cur.rt;
}
else {
down = cur.rt;
up = cur.lb;
}
}
dist = p.distanceTo(cur.p);
if (dist < min) {
min = dist;
champ = cur.p;
}
else {
champ = null;
}
other = nearestPoint(p, down, depth+1, min);
if (other != null && other.distanceTo(p) < min) {
min = other.distanceTo(p);
champ = other;
}
if (perpendicularDist < min) {
other = nearestPoint(p, up, depth+1, min);
if (other != null && other.distanceTo(p) < min) {
min = other.distanceTo(p);
champ = other;
}
}
return champ;
}
public static void main(String[] args) {
if (args.length < 2) {
System.out.println("Incorrect usage.");
return;
}
Scanner scanPoint;
Scanner scanClosest;
ClosestPoint closest;
File points = new File(args[0]);
File querryPoints = new File(args[1]);
LinkedList<Point> p = new LinkedList<Point>();
LinkedList<Point> closestP = new LinkedList<Point>();
try {
scanPoint = new Scanner(points);
scanClosest = new Scanner(querryPoints);
while(scanPoint.hasNextDouble()) {
double x = scanPoint.nextDouble();
double y = scanPoint.nextDouble();
p.add(new Point(x, y));
}
while(scanClosest.hasNextDouble()) {
double x = scanClosest.nextDouble();
double y = scanClosest.nextDouble();
closestP.add(new Point(x, y));
}
}catch (FileNotFoundException e1) {
e1.printStackTrace();
}
closest = new ClosestPoint(p);
for (Point fClosest: closestP) {
System.out.println("For point " + fClosest + " the closest one is: " + closest.nearestPoint(fClosest));
}
}
}