/* 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; }
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; }