示例#1
0
/* Finds all tricircles specified point belongs to.
 *
 * @param d Delaunay triangulation
 * @param p Point to be mapped
 * @param n Pointer to the number of tricircles within `d' containing `p'
 *          (output)
 * @param out Pointer to an array of indices of the corresponding triangles 
 *            [n] (output)
 *
 * There is a standard search procedure involving search through triangle
 * neighbours (not through vertex neighbours). It must be a bit faster due to
 * the smaller number of triangle neighbours (3 per triangle) but may fail
 * for a point outside convex hall.
 *
 * We may wish to modify this procedure in future: first check if the point
 * is inside the convex hall, and depending on that use one of the two
 * search algorithms. It not 100% clear though whether this will lead to a
 * substantial speed gains because of the check on convex hall involved.
 */
void delaunay_circles_find(delaunay* d, point* p, int* n, int** out)
{
    /*
     * This flag was introduced as a hack to handle some degenerate cases. It 
     * is set to 1 only if the triangle associated with the first circle is
     * already known to contain the point. In this case the circle is assumed 
     * to contain the point without a check. In my practice this turned
     * useful in some cases when point p coincided with one of the vertices
     * of a thin triangle. 
     */
    int contains = 0;
    int i;

    if (d->t_in == NULL) {
        d->t_in = istack_create();
        d->t_out = istack_create();
    }

    /*
     * if there are only a few data points, do linear search
     */
    if (d->ntriangles <= N_SEARCH_TURNON) {
        istack_reset(d->t_out);

        for (i = 0; i < d->ntriangles; ++i) {
            if (circle_contains(&d->circles[i], p)) {
                istack_push(d->t_out, i);
            }
        }

        *n = d->t_out->n;
        *out = d->t_out->v;

        return;
    }
    /*
     * otherwise, do a more complicated stuff
     */

    /*
     * It is important to have a reasonable seed here. If the last search
     * was successful -- start with the last found tricircle, otherwhile (i) 
     * try to find a triangle containing p; if fails then (ii) check
     * tricircles from the last search; if fails then (iii) make linear
     * search through all tricircles 
     */
    if (d->first_id < 0 || !circle_contains(&d->circles[d->first_id], p)) {
        /*
         * if any triangle contains p -- start with this triangle 
         */
        d->first_id = delaunay_xytoi(d, p, d->first_id);
        contains = (d->first_id >= 0);

        /*
         * if no triangle contains p, there still is a chance that it is
         * inside some of circumcircles 
         */
        if (d->first_id < 0) {
            int nn = d->t_out->n;
            int tid = -1;

            /*
             * first check results of the last search 
             */
            for (i = 0; i < nn; ++i) {
                tid = d->t_out->v[i];
                if (circle_contains(&d->circles[tid], p))
                    break;
            }
            /*
             * if unsuccessful, search through all circles 
             */
            if (tid < 0 || i == nn) {
                double nt = d->ntriangles;

                for (tid = 0; tid < nt; ++tid) {
                    if (circle_contains(&d->circles[tid], p))
                        break;
                }
                if (tid == nt) {
                    istack_reset(d->t_out);
                    *n = 0;
                    *out = NULL;
                    return;     /* failed */
                }
            }
            d->first_id = tid;
        }
    }

    istack_reset(d->t_in);
    istack_reset(d->t_out);

    istack_push(d->t_in, d->first_id);
    d->flags[d->first_id] = 1;

    /*
     * main cycle 
     */
    while (d->t_in->n > 0) {
        int tid = istack_pop(d->t_in);
        triangle* t = &d->triangles[tid];

        if (contains || circle_contains(&d->circles[tid], p)) {
            istack_push(d->t_out, tid);
            for (i = 0; i < 3; ++i) {
                int vid = t->vids[i];
                int nt = d->n_point_triangles[vid];
                int j;

                for (j = 0; j < nt; ++j) {
                    int ntid = d->point_triangles[vid][j];

                    if (d->flags[ntid] == 0) {
                        istack_push(d->t_in, ntid);
                        d->flags[ntid] = 1;
                    }
                }
            }
        }
        contains = 0;
    }

    *n = d->t_out->n;
    *out = d->t_out->v;
}
示例#2
0
int main() {

    char c;
    int i, k = 0, t = 1;

    double x, y;

    FILE *fp = stdin;

    double r[MAX][6];
    char type[MAX];

    while ((c = fgetc(fp)) != '*') {
        if (c == 'r') {
            for (i = 0; i < 4; i++) {
                fscanf(fp, "%lf", &r[k][i]);
            }
            type[k++] = c;
        } else if (c == 'c') {
            for (i = 0; i < 3; i++) {
                fscanf(fp, "%lf", &r[k][i]);
            }
            type[k++] = c;
        } else if (c == 't') {
            for (i = 0; i < 6; i++) {
                fscanf(fp, "%lf", &r[k][i]);
            }
            type[k++] = c;
        }

        fgetc(fp);
    }
    bool seen;
    while (fscanf(fp, "%lf %lf", &x, &y) == 2 && (x != 9999.9 || y != 9999.9)) {
        seen = false;
        for (i = 0; i < k; i++) {
            if (type[i] == 'r') {
                if (x > r[i][0] && x < r[i][2] && y < r[i][1] && y > r[i][3]) {
                    printf("Point %i is contained in figure %i\n", t, (i + 1));
                    seen = true;
                }
            } else if (type[i] == 'c') {
                if (circle_contains(r[i][0], r[i][1], x, y, r[i][2]) ) {
                    printf("Point %i is contained in figure %i\n", t, (i + 1));
                    seen = true;
                }
            } else if (type[i] == 't') {
                if (triangle_contains(r[i][0], r[i][1], r[i][2], r[i][3], r[i][4], r[i][5], x, y) ) {
                    printf("Point %i is contained in figure %i\n", t, (i + 1));
                    seen = true;
                }
            }
        }
        if (!seen) {
            printf("Point %i is not contained in any figure\n", t);
        }
        t++;
    }

    fclose(fp);

    return 0;
}