#ifndef ISEA_STATIC #define ISEA_STATIC #endif struct hex { int iso; int x, y, z; }; /* y *must* be positive down as the xy /iso conversion assumes this */ ISEA_STATIC int hex_xy(struct hex *h) { if (!h->iso) return 1; if (h->x >= 0) { h->y = -h->y - (h->x+1)/2; } else { /* need to round toward -inf, not toward zero, so x-1 */ h->y = -h->y - h->x/2; } h->iso = 0; return 1; } ISEA_STATIC int hex_iso(struct hex *h) { if (h->iso) return 1; if (h->x >= 0) { h->y = (-h->y - (h->x+1)/2); } else { /* need to round toward -inf, not toward zero, so x-1 */ h->y = (-h->y - (h->x)/2); } h->z = -h->x - h->y; h->iso = 1; return 1; } ISEA_STATIC int hexbin2(int horizontal, double width, double x, double y, int *i, int *j) { double z, rx, ry, rz; double abs_dx, abs_dy, abs_dz; int ix, iy, iz, s; struct hex h; x = x / cos(30 * M_PI / 180.0); /* rotated X coord */ y = y - x / 2.0; /* adjustment for rotated X */ /* adjust for actual hexwidth */ x /= width; y /= width; z = -x - y; ix = rx = floor(x + 0.5); iy = ry = floor(y + 0.5); iz = rz = floor(z + 0.5); s = ix + iy + iz; if (s) { abs_dx = fabs(rx - x); abs_dy = fabs(ry - y); abs_dz = fabs(rz - z); if (abs_dx >= abs_dy && abs_dx >= abs_dz) { ix -= s; } else if (abs_dy >= abs_dx && abs_dy >= abs_dz) { iy -= s; } else { iz -= s; } } h.x = ix; h.y = iy; h.z = iz; h.iso = 1; hex_xy(&h); *i = h.x; *j = h.y; return ix * 100 + iy; }