static void nnpi_getneighbours(nnpi* nn, point* p, int nt, int* tids, int* n, int** nids) { delaunay* d = nn->d; istack* neighbours = istack_create(); indexedpoint* v = NULL; int i; for (i = 0; i < nt; ++i) { triangle* t = &d->triangles[tids[i]]; istack_push(neighbours, t->vids[0]); istack_push(neighbours, t->vids[1]); istack_push(neighbours, t->vids[2]); } qsort(neighbours->v, neighbours->n, sizeof(int), compare_int); v = malloc(sizeof(indexedpoint) * neighbours->n); v[0].p = &d->points[neighbours->v[0]]; v[0].i = neighbours->v[0]; *n = 1; for (i = 1; i < neighbours->n; ++i) { if (neighbours->v[i] == neighbours->v[i - 1]) continue; v[*n].p = &d->points[neighbours->v[i]]; v[*n].i = neighbours->v[i]; (*n)++; } /* * I assume that if there is exactly one tricircle the point belongs to, * then number of natural neighbours *n = 3, and they are already sorted * in the right way in triangulation process. */ if (*n > 3) { v[0].p0 = NULL; v[0].p1 = NULL; for (i = 1; i < *n; ++i) { v[i].p0 = p; v[i].p1 = v[0].p; } qsort(&v[1], *n - 1, sizeof(indexedpoint), compare_indexedpoints); } (*nids) = malloc(*n * sizeof(int)); for (i = 0; i < *n; ++i) (*nids)[i] = v[i].i; istack_destroy(neighbours); free(v); }
int main(int argc, char *argv[]) { istack st; int i; int val; istack_init(&st); for (i = 0; i < 32; i++) { istack_push(&st, i); istack_top(&st, &val); printf("%d ", val); } istack_destroy(&st); printf("\n"); return 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; }