示例#1
0
文件: nnpi.c 项目: epicsdeb/sdds
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;
}