/* Divides a subgrid in two. * @param sg The subgrid to divide * @param subgrid1 Output subgrid 1 * @param subgrid2 Output subgrid 2 * @param gx Array of x cell corner coordinates * @param gy Array of y cell corner coordinates */ static void subgrid_divide(subgrid* sg, subgrid** sg1, subgrid** sg2) { poly* pl1 = NULL; poly* pl2 = NULL; gridmap* gm = sg->gmap; int index; if ((sg->maxi <= sg->mini + 1) && (sg->maxj <= sg->minj + 1)) { *sg1 = *sg2 = NULL; return; } if (sg->maxi - sg->mini > sg->maxj - sg->minj) { /* * divide "vertically" */ index = (sg->mini + sg->maxi) / 2; cut_boundary(sg->bound, gm->gx, gm->gy, 0, index, sg->minj, sg->maxj, &pl1, &pl2); } else { /* * divide "horizontally" */ index = (sg->minj + sg->maxj) / 2; cut_boundary(sg->bound, gm->gx, gm->gy, 1, index, sg->mini, sg->maxi, &pl1, &pl2); } if (pl1 == NULL || pl2 == NULL) gu_quit("dividesubgrid(): could not cut the boundary\n"); *sg1 = subgrid_create(gm, pl1, sg->mini, sg->maxi, sg->minj, sg->maxj); *sg2 = subgrid_create(gm, pl2, sg->mini, sg->maxi, sg->minj, sg->maxj); }
FILE* gu_fopen(const char* path, const char* mode) { FILE* f = NULL; f = fopen(path, mode); if (f == NULL) gu_quit("%s: could not open for \"%s\" : %s\n", path, mode, strerror(errno)); return f; }
/* Allocates n1xn2 matrix of something. Note that it will be accessed as * [n2][n1]. * @param n1 Number of columns * @param n2 Number of rows * @param unitsize Size of one matrix element in bytes * @return Matrix */ void* gu_alloc2d(int n1, int n2, size_t unitsize) { size_t size; char* p; char** pp; int i; if (n1 <= 0 || n2 <= 0) gu_quit("alloc2d(): invalid size (n1 = %d, n2 = %d)\n", n1, n2); size = n1 * n2; if ((p = calloc(size, unitsize)) == NULL) gu_quit("gu_alloc2d(): %s\n", strerror(errno)); size = n2 * sizeof(void*); if ((pp = malloc(size)) == NULL) gu_quit("gu_alloc2d(): %s\n", strerror(errno)); for (i = 0; i < n2; i++) pp[i] = &p[i * n1 * unitsize]; return pp; }
gridmap* gridmap_build(int nce1, int nce2, double** gx, double** gy, int type) { gridmap* gm = malloc(sizeof(gridmap)); gm->type = type; if (gm->type == GRIDMAP_TYPE_BINARY) gm->map = gridbmap_build(nce1, nce2, gx, gy); else if (gm->type == GRIDMAP_TYPE_KDTREE) gm->map = gridkmap_build(nce1, nce2, gx, gy); else gu_quit("grid map type = %d: unknown type", type); gm->sign = 0; return gm; }
/** Appends a point to the tail of a polyline. * @param pl Polyline * @param x X coordinate * @param y Y coordinate */ void poly_addpoint(poly* pl, double x, double y) { if (isnan(x) || isnan(y)) gu_quit("poly_addpoint(): NaN detected"); if (pl->n == pl->nallocated) { pl->x = realloc(pl->x, pl->nallocated * sizeof(double) * 2); pl->y = realloc(pl->y, pl->nallocated * sizeof(double) * 2); pl->nallocated *= 2; } pl->x[pl->n] = x; pl->y[pl->n] = y; pl->n++; extent_update(&pl->e, x, y); }
gridmap* gridmap_build2(gridnodes* gn) { gridmap* gm = malloc(sizeof(gridmap)); int nce1 = gridnodes_getnce1(gn); int nce2 = gridnodes_getnce2(gn); double** gx = gridnodes_getx(gn); double** gy = gridnodes_gety(gn); int type = gridnodes_getmaptype(gn); gm->type = type; if (gm->type == GRIDMAP_TYPE_BINARY) gm->map = gridbmap_build(nce1, nce2, gx, gy); else if (gm->type == GRIDMAP_TYPE_KDTREE) gm->map = gridkmap_build(nce1, nce2, gx, gy); else gu_quit("grid map type = %d: unknown type", type); gm->sign = 0; return gm; }
/* Creates a subgrid. * @param gm Grid map * @param pl Boundary polygon for the subgrid * @param mini Minimal i index within the subgrid * @param maxi Maximal i index within the subgrid * @param minj Minimal j index within the subgrid * @param maxj Maximal j index within the subgrid * @return Subgrid */ static subgrid* subgrid_create(gridmap* gm, poly* pl, int i1, int i2, int j1, int j2) { subgrid* l = malloc(sizeof(subgrid)); double** gx = gm->gx; double** gy = gm->gy; int n = pl->n; double x, y; int i = i1; /* to eliminate warning */ int j, ii; l->bound = pl; l->gmap = gm; l->mini = INT_MAX; l->maxi = INT_MIN; l->minj = INT_MAX; l->maxj = INT_MIN; l->half1 = NULL; l->half2 = NULL; if (n == 0) return l; x = pl->x[0]; y = pl->y[0]; for (j = j1; j <= j2; ++j) for (i = i1; i <= i2; ++i) if (x == gx[j][i] && y == gy[j][i]) goto aftersearch; aftersearch: if (j > j2) gu_quit("subgrid_create(): boundary vertex not in the grid\n"); l->mini = i; l->maxi = i; l->minj = j; l->maxj = j; for (ii = 1; ii < n; ++ii) { x = pl->x[ii]; y = pl->y[ii]; if (i > i1 && x == gx[j][i - 1] && y == gy[j][i - 1]) i--; else if (i < i2 && x == gx[j][i + 1] && y == gy[j][i + 1]) i++; else if (j > j1 && x == gx[j - 1][i] && y == gy[j - 1][i]) j--; else if (j < j2 && x == gx[j + 1][i] && y == gy[j + 1][i]) j++; else if (x == gx[j][i] && y == gy[j][i]) continue; else gu_quit("subgrid_create(): boundary vertex not in the grid\n"); if (l->mini > i) l->mini = i; if (l->maxi < i) l->maxi = i; if (l->minj > j) l->minj = j; if (l->maxj < j) l->maxj = j; } return l; }