blob: e3d37fea6af5c4dcf4147c0f940e52e96d4ffdd5 [file] [log] [blame]
#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);
};