static int _nnpi_calculate_weights(nnpi* nn, point* p) { int* tids = NULL; int i; delaunay_circles_find(nn->d, p, &nn->ncircles, &tids); if (nn->ncircles == 0) return 1; /* * The algorithms of calculating weights for Sibson and non-Sibsonian * interpolations are quite different; in the first case, the weights are * calculated by processing Delaunay triangles whose tricircles contain * the interpolated point; in the second case, they are calculated by * processing triplets of natural neighbours by moving clockwise or * counterclockwise around the interpolated point. */ if (nn_rule == SIBSON) { for (i = 0; i < nn->ncircles; ++i) nnpi_triangle_process(nn, p, tids[i]); if (nn->bad != NULL) { int nentries = ht_getnentries(nn->bad); if (nentries > 0) { ht_process(nn->bad, free); return 0; } } return 1; } else if (nn_rule == NON_SIBSONIAN) { int nneigh = 0; int* nids = NULL; int status; nnpi_getneighbours(nn, p, nn->ncircles, tids, &nneigh, &nids); status = nnpi_neighbours_process(nn, p, nneigh, nids); free(nids); return status; } else nn_quit("programming error"); return 0; }
static int _nnpi_calculate_weights(nnpi* nn, point* p) { int* tids = NULL; int i; delaunay_circles_find(nn->d, p, &nn->ncircles, &tids); if (nn->ncircles == 0) return 1; /* * The algorithms of calculating weights for Sibson and non-Sibsonian * interpolations are quite different; in the first case, the weights are * calculated by processing Delaunay triangles whose tricircles contain * the interpolated point; in the second case, they are calculated by * processing triplets of natural neighbours by moving clockwise or * counterclockwise around the interpolated point. */ if (nn_rule == SIBSON) { for (i = 0; i < nn->ncircles; ++i) nnpi_triangle_process(nn, p, tids[i]); if (nn->bad != NULL) { if (ht_getnentries(nn->bad) != 0) { /* * The idea behind this hack is that if the "infinite circle" * hash table has not been cleared at the end of the weight * calculation process for a point, then this is caused by * misbehavior of some in-circle tests due to the numeric * round-up in cases when the interpolation point is close to * one of the data points. The code below effectively replaces * the interpolated value by the data value in the closest * point after detecting a non-cleared hash table. */ int vid_closest = -1; double dist_closest = DBL_MAX; for (i = 0; i < nn->nvertices; ++i) { point* pp = &nn->d->points[nn->vertices[i]]; double dist = hypot(p->x - pp->x, p->y - pp->y); if (dist < dist_closest) { vid_closest = nn->vertices[i]; dist_closest = dist; } } nnpi_add_weight(nn, vid_closest, BIGNUMBER); } } return 1; } else if (nn_rule == NON_SIBSONIAN) { int nneigh = 0; int* nids = NULL; int status; nnpi_getneighbours(nn, p, nn->ncircles, tids, &nneigh, &nids); status = nnpi_neighbours_process(nn, p, nneigh, nids); free(nids); return status; } else nn_quit("programming error"); return 0; }