diff options
| author | Kristian Evers <kristianevers@gmail.com> | 2018-05-06 17:43:26 +0300 |
|---|---|---|
| committer | Kristian Evers <kristianevers@gmail.com> | 2018-05-08 09:16:07 +0200 |
| commit | 58cbb9fe4f89b9febd780f7bdcfa4c2bb74a723e (patch) | |
| tree | dec50c945b01d09c5cf94d0665a6996e2d34ae5d /src/PJ_isea.c | |
| parent | 8fef2126f1c9fa17b79e6669f4457c299c0e33bf (diff) | |
| download | PROJ-58cbb9fe4f89b9febd780f7bdcfa4c2bb74a723e.tar.gz PROJ-58cbb9fe4f89b9febd780f7bdcfa4c2bb74a723e.zip | |
Replace int typecasts with calls to lround to avoid bad conversions on NaN input. Added test to check for those cases.
Diffstat (limited to 'src/PJ_isea.c')
| -rw-r--r-- | src/PJ_isea.c | 52 |
1 files changed, 27 insertions, 25 deletions
diff --git a/src/PJ_isea.c b/src/PJ_isea.c index 3e941c77..14aec843 100644 --- a/src/PJ_isea.c +++ b/src/PJ_isea.c @@ -2,12 +2,18 @@ * This code was entirely written by Nathan Wagner * and is in the public domain. */ +#define PJ_LIB__ +#include <errno.h> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <float.h> +#include "proj.h" +#include "projects.h" +#include "proj_math.h" + #ifndef M_PI # define M_PI 3.14159265358979323846 #endif @@ -59,7 +65,7 @@ ISEA_STATIC void hexbin2(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; + long ix, iy, iz, s; struct hex h; x = x / cos(30 * M_PI / 180.0); /* rotated X coord */ @@ -72,11 +78,11 @@ void hexbin2(double width, double x, double y, int *i, int *j) { z = -x - y; rx = floor(x + 0.5); - ix = (int)rx; + ix = lround(rx); ry = floor(y + 0.5); - iy = (int)ry; + iy = lround(ry); rz = floor(z + 0.5); - iz = (int)rz; + iz = lround(rz); s = ix + iy + iz; @@ -707,7 +713,7 @@ isea_dddi_ap3odd(struct isea_dgg *g, int quad, struct isea_pt *pt, struct isea_p double hexwidth; double sidelength; /* in hexes */ int d, i; - int maxcoord; + long maxcoord; struct hex h; /* This is the number of hexes from apex to base of a triangle */ @@ -719,7 +725,7 @@ isea_dddi_ap3odd(struct isea_dgg *g, int quad, struct isea_pt *pt, struct isea_p /* TODO I think sidelength is always x.5, so * (int)sidelength * 2 + 1 might be just as good */ - maxcoord = (int) (sidelength * 2.0 + 0.5); + maxcoord = lround((sidelength * 2.0 + 0.5)); v = *pt; hexbin2(hexwidth, v.x, v.y, &h.x, &h.y); @@ -783,7 +789,7 @@ int isea_dddi(struct isea_dgg *g, int quad, struct isea_pt *pt, struct isea_pt *di) { struct isea_pt v; double hexwidth; - int sidelength; /* in hexes */ + long sidelength; /* in hexes */ struct hex h; if (g->aperture == 3 && g->resolution % 2 != 0) { @@ -791,7 +797,7 @@ isea_dddi(struct isea_dgg *g, int quad, struct isea_pt *pt, struct isea_pt *di) } /* todo might want to do this as an iterated loop */ if (g->aperture >0) { - sidelength = (int) (pow(g->aperture, g->resolution / 2.0) + 0.5); + sidelength = lround((pow(g->aperture, g->resolution / 2.0) + 0.5)); } else { sidelength = g->resolution; } @@ -866,29 +872,29 @@ int isea_ptdi(struct isea_dgg *g, int tri, struct isea_pt *pt, /* q2di to seqnum */ ISEA_STATIC int isea_disn(struct isea_dgg *g, int quad, struct isea_pt *di) { - int sidelength; - int sn, height; - int hexes; + long sidelength; + long sn, height; + long hexes; if (quad == 0) { g->serial = 1; return g->serial; } /* hexes in a quad */ - hexes = (int) (pow(g->aperture, g->resolution) + 0.5); + hexes = lround((pow(g->aperture, g->resolution) + 0.5)); if (quad == 11) { g->serial = 1 + 10 * hexes + 1; return g->serial; } if (g->aperture == 3 && g->resolution % 2 == 1) { - height = (int) (pow(g->aperture, (g->resolution - 1) / 2.0)); + height = lround((pow(g->aperture, (g->resolution - 1) / 2.0))); sn = ((int) di->x) * height; sn += ((int) di->y) / height; sn += (quad - 1) * hexes; sn += 2; } else { - sidelength = (int) (pow(g->aperture, g->resolution / 2.0) + 0.5); - sn = (int) ((quad - 1) * hexes + sidelength * di->x + di->y + 2); + sidelength = lround((pow(g->aperture, g->resolution / 2.0) + 0.5)); + sn = lround(((quad - 1) * hexes + sidelength * di->x + di->y + 2)); } g->serial = sn; @@ -905,8 +911,8 @@ int isea_hex(struct isea_dgg *g, int tri, struct isea_pt *pt, struct isea_pt *hex) { struct isea_pt v; #ifdef FIXME - int sidelength; - int d, i, x, y; + long sidelength; + long d, i, x, y; #endif int quad; @@ -917,12 +923,12 @@ int isea_hex(struct isea_dgg *g, int tri, return 1; #ifdef FIXME - d = (int)v.x; - i = (int)v.y; + d = lround(v.x); + i = lround(v.y); /* Aperture 3 odd resolutions */ if (g->aperture == 3 && g->resolution % 2 != 0) { - int offset = (int)(pow(3.0, g->resolution - 1) + 0.5); + long offset = lround((pow(3.0, g->resolution - 1) + 0.5)); d += offset * ((g->quad-1) % 5); i += offset * ((g->quad-1) % 5); @@ -946,7 +952,7 @@ int isea_hex(struct isea_dgg *g, int tri, } /* aperture 3 even resolutions and aperture 4 */ - sidelength = (int) (pow(g->aperture, g->resolution / 2.0) + 0.5); + sidelength = lround((pow(g->aperture, g->resolution / 2.0) + 0.5)); if (g->quad == 0) { hex->x = 0; hex->y = sidelength; @@ -1016,10 +1022,6 @@ isea_forward(struct isea_dgg *g, struct isea_geo *in) * Proj 4 integration code follows */ -#define PJ_LIB__ -#include <errno.h> -#include "proj.h" -#include "projects.h" PROJ_HEAD(isea, "Icosahedral Snyder Equal Area") "\n\tSph"; |
