| |
| #include "delaunator.h" |
| #include <cstdio> |
| #include <limits> |
| |
| using namespace std; |
| |
| namespace { |
| const double max_double = numeric_limits<double>::max(); |
| double dist( |
| const double &ax, |
| const double &ay, |
| const double &bx, |
| const double &by |
| ) { |
| const double dx = ax - bx; |
| const double dy = ay - by; |
| return dx * dx + dy * dy; |
| } |
| double circumradius( |
| const double &ax, |
| const double &ay, |
| const double &bx, |
| const double &by, |
| const double &cx, |
| const double &cy |
| ) { |
| const double dx = bx - ax; |
| const double dy = by - ay; |
| const double ex = cx - ax; |
| const double ey = cy - ay; |
| |
| const double bl = dx * dx + dy * dy; |
| const double cl = ex * ex + ey * ey; |
| const double d = dx * ey - dy * ex; |
| |
| const double x = (ey * bl - dy * cl) * 0.5 / d; |
| const double y = (dx * cl - ex * bl) * 0.5 / d; |
| |
| return (bl && cl && d && (x * x + y * y)) || max_double; |
| } |
| } |
| |
| Delaunator::Delaunator(const vector<double> &coords) { |
| const long int n = coords.size() >> 1; |
| double max_x = -1 * max_double; |
| double max_y = -1 * max_double; |
| double min_x = max_double; |
| double min_y = max_double; |
| unsigned int ids[n]; |
| for (long int i = 0; i < n; i++) { |
| const double x = coords[2 * i]; |
| const double y = coords[2 * i + 1]; |
| // printf("%f %f", x, y); |
| |
| if (x < min_x) min_x = x; |
| if (y < min_y) min_y = y; |
| if (x > max_x) max_x = x; |
| if (y > max_y) max_y = y; |
| ids[i] = i; |
| } |
| const double cx = (min_x + max_x) / 2; |
| const double cy = (min_y + max_y) / 2; |
| double min_dist = max_double; |
| unsigned long int i0; |
| unsigned long int i1; |
| unsigned long int i2; |
| |
| // pick a seed point close to the centroid |
| for (unsigned long int i = 0; i < n; i++) { |
| const double d = dist(cx, cy, coords[2 * i], coords[2 * i + 1]); |
| if (d < min_dist) { |
| i0 = i; |
| min_dist = d; |
| } |
| } |
| |
| min_dist = max_double; |
| |
| // find the point closest to the seed |
| for (unsigned long int i = 0; i < n; i++) { |
| if (i == i0) continue; |
| const double d = dist(coords[2 * i0], coords[2 * i0 + 1], coords[2 * i], coords[2 * i + 1]); |
| if (d < min_dist && d > 0) |
| { |
| i1 = i; |
| min_dist = d; |
| } |
| } |
| // printf("min_dist=%f i1=%lu", min_dist, i1); |
| }; |