-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathclosestpoint.c
73 lines (64 loc) · 1.92 KB
/
closestpoint.c
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
//
// Created by Once on 2019/11/28.
//
#include "closestpoint.h"
#include <stdlib.h>
#include <math.h>
static double distance(Point *a, Point *b){
return sqrt((a->x - b->x) * (a->x - b->x) + (a->y - b->y) * (a->y - b->y));
}
static double min(double a, double b){
if(a > b)
return a;
else
return b;
}
static int compare_x(const void *a, const void *b){
Point *_a = (Point*)a;
Point *_b = (Point*)b;
return _a->x > _b->x;
}
static int compare_y(const void *a, const void *b){
Point *_a = (Point*)a;
Point *_b = (Point*)b;
return _a->y > _b->y;
}
static double _shortest_distance(Point points[], int left, int right){
if(left == right)
return INT_MAX;
if(left + 1 == right)
return distance(&points[left], &points[right]);
if(left + 2 == right)
return min(min(distance(&points[left], &points[left + 1]), distance(&points[left], &points[right])),
distance(&points[left + 1], &points[right]));
int center = (left + right) / 2;
double c = points[center].x;
double dl = _shortest_distance(points, left, center);
double dr = _shortest_distance(points, center + 1, right);
double m = min(dl, dr);
Point Q[right - left + 1];
int n = 0;
for (int k = left; k <= right; ++k) {
if(fabs(points[k].x - c) < m)
Q[n] = points[k], n++;
}
qsort(Q, n, sizeof(Point), compare_y);
// O(n)
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
if(Q[j].y - Q[i].y > m)
break;
if(distance(&Q[i], &Q[j]) < m)
m = distance(&Q[i], &Q[j]);
}
}
return m;
}
double find_shortest_distance(Point points[], int n){
if(points == NULL || n < 2){
perror("null point exception or n is too small");
return -1;
}
qsort(points, n, sizeof(Point), compare_x);
return _shortest_distance(points, 0, n - 1);
}