Exemplo n.º 1
0
/* Builds Natural Neighbours array interpolator. This includes calculation of
 * weights used in nnai_interpolate().
 *
 * @param d Delaunay triangulation
 * @return Natural Neighbours interpolation
 */
nnai* nnai_build(delaunay* d, long n, double* x, double* y)
{
    nnai* nn = (nnai *)malloc(sizeof(nnai));
    nnpi* nnpi = nnpi_create(d);
    int* vertices;
    double* weights;
    int i;

    if (n <= 0)
        nn_quit("nnai_create(): n = %d\n", n);

    nn->d = d;
    nn->n = n;
    nn->x = (double *)malloc(n * sizeof(double));
    memcpy(nn->x, x, n * sizeof(double));
    nn->y = (double *)malloc(n * sizeof(double));
    memcpy(nn->y, y, n * sizeof(double));
    nn->weights = (nn_weights *)malloc(n * sizeof(nn_weights));

    for (i = 0; i < n; ++i) {
        nn_weights* w = &nn->weights[i];
        point p;

        p.x = x[i];
        p.y = y[i];

        nnpi_reset(nnpi);
        nnpi_set_point(nnpi, &p);
        nnpi_calculate_weights(nnpi);
        nnpi_normalize_weights(nnpi);

        vertices = nnpi_get_vertices(nnpi);
        weights = nnpi_get_weights(nnpi);

        w->nvertices = nnpi_get_nvertices(nnpi);
        w->vertices = (int *)malloc(w->nvertices * sizeof(int));
        memcpy(w->vertices, vertices, w->nvertices * sizeof(int));
        w->weights = (double *)malloc(w->nvertices * sizeof(double));
        memcpy(w->weights, weights, w->nvertices * sizeof(double));
    }

    nnpi_destroy(nnpi);

    return nn;
}
Exemplo n.º 2
0
/* Finds Natural Neighbours-interpolated value in a point.
 *
 * @param nnhpi NN point hashing interpolator
 * @param p Point to be interpolated (p->x, p->y -- input; p->z -- output)
 */
void nnhpi_interpolate(nnhpi* nnhpi, point* p)
{
    nnpi* nnpi = nnhpi->nnpi;
    delaunay* d = nnpi->d;
    hashtable* ht_weights = nnhpi->ht_weights;
    nn_weights* weights;
    int i;

    if (ht_find(ht_weights, p) != NULL) {
        weights = ht_find(ht_weights, p);
        if (nn_verbose)
            fprintf(stderr, "  <hashtable>\n");
    } else {
        nnpi_calculate_weights(nnpi, p);

        weights = malloc(sizeof(nn_weights));
        weights->vertices = malloc(sizeof(int) * nnpi->nvertices);
        weights->weights = malloc(sizeof(double) * nnpi->nvertices);

        weights->nvertices = nnpi->nvertices;

        for (i = 0; i < nnpi->nvertices; ++i) {
            weights->vertices[i] = nnpi->vertices[i];
            weights->weights[i] = nnpi->weights[i];
        }

        ht_insert(ht_weights, p, weights);

        if (nn_verbose) {
            if (nn_test_vertice == -1) {
                if (nnpi->n == 0)
                    fprintf(stderr, "weights:\n");
                fprintf(stderr, "  %d: {", nnpi->n);

                for (i = 0; i < nnpi->nvertices; ++i) {
                    fprintf(stderr, "(%d,%.5g)", nnpi->vertices[i], nnpi->weights[i]);

                    if (i < nnpi->nvertices - 1)
                        fprintf(stderr, ", ");
                }
                fprintf(stderr, "}\n");
            } else {
                double w = 0.0;

                if (nnpi->n == 0)
                    fprintf(stderr, "weights for vertex %d:\n", nn_test_vertice);
                for (i = 0; i < nnpi->nvertices; ++i) {
                    if (nnpi->vertices[i] == nn_test_vertice) {
                        w = nnpi->weights[i];

                        break;
                    }
                }
                fprintf(stderr, "%15.7g %15.7g %15.7g\n", p->x, p->y, w);
            }
        }

        nnpi->n++;
    }

    nnhpi->n++;

    if (weights->nvertices == 0) {
        p->z = NaN;
        return;
    }

    p->z = 0.0;
    for (i = 0; i < weights->nvertices; ++i) {
        if (weights->weights[i] < nnpi->wmin) {
            p->z = NaN;
            return;
        }
        p->z += d->points[weights->vertices[i]].z * weights->weights[i];
    }
}
Exemplo n.º 3
0
/* Performs Natural Neighbours interpolation in a point.
 *
 * @param nn NN interpolation
 * @param p Point to be interpolated (p->x, p->y -- input; p->z -- output)
 */
void nnpi_interpolate_point(nnpi* nn, point* p)
{
    delaunay* d = nn->d;
    int i;

    nnpi_calculate_weights(nn, p);

    if (nn_verbose) {
        if (nn_test_vertice == -1) {
            indexedvalue* ivs = NULL;

            if (nn->nvertices > 0) {
                ivs = malloc(nn->nvertices * sizeof(indexedvalue));

                for (i = 0; i < nn->nvertices; ++i) {
                    ivs[i].i = nn->vertices[i];
                    ivs[i].v = &nn->weights[i];
                }

                qsort(ivs, nn->nvertices, sizeof(indexedvalue), cmp_iv);
            }

            if (nn->n == 0)
                fprintf(stderr, "weights:\n");
            fprintf(stderr, "  %d: (%.10g, %10g)\n", nn->n, p->x, p->y);
            fprintf(stderr, "  %4s %15s %15s %15s %15s\n", "id", "x", "y", "z", "w");
            for (i = 0; i < nn->nvertices; ++i) {
                int ii = ivs[i].i;
                point* pp = &d->points[ii];

                fprintf(stderr, "  %5d %15.10g %15.10g %15.10g %15f\n", ii, pp->x, pp->y, pp->z, *ivs[i].v);
            }

            if (nn->nvertices > 0)
                free(ivs);
        } else {
            double w = 0.0;

            if (nn->n == 0)
                fprintf(stderr, "weight of vertex %d:\n", nn_test_vertice);
            for (i = 0; i < nn->nvertices; ++i) {
                if (nn->vertices[i] == nn_test_vertice) {
                    w = nn->weights[i];
                    break;
                }
            }
            fprintf(stderr, "  (%.10g, %.10g): %.7g\n", p->x, p->y, w);
        }
    }

    nn->n++;

    if (nn->nvertices == 0) {
        p->z = NaN;
        return;
    }

    p->z = 0.0;
    for (i = 0; i < nn->nvertices; ++i) {
        double weight = nn->weights[i];

        if (weight < nn->wmin) {
            p->z = NaN;
            return;
        }
        p->z += d->points[nn->vertices[i]].z * weight;
    }
}