public class Point {
private double x;
private double y;
}
public class ClosestPoint {
public static void main(String[] args) {
List<Point> points = new ArrayList<>();
getData(points, 8);
System.out.println(points);
Point p1 = new Point();
Point p2 = new Point();
System.out.println(ClosestDistance(points, p1, p2));
System.out.println(p1 + "" + p2);
}
public static double ClosestDistance(List<Point> points, Point P1, Point P2) {
List<Point> X = new ArrayList<>();
List<Point> Y = new ArrayList<>();
for (Point point : points) {
X.add(point);
Y.add(point);
}
Collections.sort(X, (p1, p2) -> p1.getX() - p2.getX() < 0 ? -1 : 1);
Collections.sort(Y, (p1, p2) -> p1.getY() - p2.getY() < 0 ? -1 : 1);
return getClosestPointPair(X, Y, P1, P2);
}
public static double getClosestPointPair(List<Point> X, List<Point> Y, Point p1, Point p2) {
double minLeft, minRight, minDistance = 0;
Point pl1 = new Point();
Point pl2 = new Point();
Point pr1 = new Point();
Point pr2 = new Point();
if (X.size() <= 3) {
double res = ClosestLowThree(X, pl1, pl2);
p1.setX(pl1.getX());
p1.setY(pl1.getY());
p2.setX(pl2.getX());
p2.setY(pl2.getY());
return res;
}
List<Point> pl = new ArrayList<>();
List<Point> pr = new ArrayList<>();
int mid = X.size() / 2;
for (int i = 0; i < mid; i++)
pl.add(X.get(i));
for (int j = mid; j < X.size(); j++)
pr.add(X.get(j));
List<List<Point>> list = YTwo(pl, pr, Y);
List<Point> YL = list.get(0);
List<Point> YR = list.get(1);
minLeft = getClosestPointPair(pl, YL, pl1, pl2);
minRight = getClosestPointPair(pr, YR, pr1, pr2);
if (minLeft < minRight) {
p1.setX(pl1.getX());
p1.setY(pl1.getY());
p2.setX(pl2.getX());
p2.setY(pl2.getY());
} else {
p1.setX(pr1.getX());
p1.setY(pr1.getY());
p2.setX(pr2.getX());
p2.setY(pr2.getY());
}
minDistance = Math.min(minLeft, minRight);
List<Point> Y1 = new ArrayList<>();
for (int i = 0; i < Y.size(); i++) {
if (Math.abs(Y.get(i).getX() - mid) < minDistance)
Y1.add(Y.get(i));
}
for (int i = 0; i < Y1.size(); i++)
for (int j = i + 1; j <= i + 7 && j < Y1.size(); j++) {
double distance = distance(Y1.get(i), Y1.get(j));
if (distance < minDistance) {
minDistance = distance;
p1.setX(Y1.get(i).getX());
p1.setY(Y1.get(i).getY());
p2.setX(Y1.get(j).getX());
p2.setY(Y1.get(j).getY());
}
}
return minDistance;
}
public static List<List<Point>> YTwo(List<Point> Pl, List<Point> Pr, List<Point> Y) {
List<Point> YL = new ArrayList<>();
List<Point> YR = new ArrayList<>();
for (int i = 0; i < Y.size(); i++) {
if (Pl.contains(Y.get(i)))
YL.add(Y.get(i));
else
YR.add(Y.get(i));
}
List<List<Point>> res = new ArrayList<>();
res.add(YL);
res.add(YR);
return res;
}
public static double distance(Point p1, Point p2) {
return Math.sqrt((p1.getX() - p2.getX()) * (p1.getX() - p2.getX()) + (p1.getY() - p2.getY()) * (p1.getY() - p2.getY()));
}
public static double ClosestLowThree(List<Point> list, Point p1, Point p2) {
if (list.size() == 0)
return 0.0;
double minAns = Double.MAX_VALUE;
for (int i = 0; i < list.size(); i++)
for (int j = i + 1; j < list.size(); j++) {
double distance = distance(list.get(i), list.get(j));
if (distance < minAns) {
minAns = distance;
p1.setX(list.get(i).getX());
p1.setY(list.get(i).getY());
p2.setX(list.get(j).getX());
p2.setY(list.get(j).getY());
}
}
return minAns;
}
public static void getData(List<Point> points, int l) {
BufferedReader bufferedReader = null;
try {
InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(new File("F:\java\leetcode\src\algorithm\project2\data.txt")));
bufferedReader = new BufferedReader(inputStreamReader);
String line = null;
int i = 0;
while ((line = bufferedReader.readLine()) != null) {
if (i == l)
break;
if (null != line) {
String[] strings = line.split("\s+");
Point p = new Point();
for (int k = 0; k < 2; k++) {
if (k == 0)
p.setX(Double.valueOf(strings[k]));
else
p.setY(Double.valueOf(strings[k]));
}
points.add(p);
i++;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}