Files
2026-01-23 17:03:45 +08:00

140 lines
3.0 KiB
C

#include <string.h>
#include "triangulate.h"
#include <sys/time.h>
static int initialise(n)
int n;
{
register int i;
for (i = 1; i <= n; i++)
seg[i].is_inserted = FALSE;
generate_random_ordering(n);
return 0;
}
/* Input specified as contours.
* Outer contour must be anti-clockwise.
* All inner contours must be clockwise.
*
* Every contour is specified by giving all its points in order. No
* point shoud be repeated. i.e. if the outer contour is a square,
* only the four distinct endpoints shopudl be specified in order.
*
* ncontours: #contours
* cntr: An array describing the number of points in each
* contour. Thus, cntr[i] = #points in the i'th contour.
* vertices: Input array of vertices. Vertices for each contour
* immediately follow those for previous one. Array location
* vertices[0] must NOT be used (i.e. i/p starts from
* vertices[1] instead. The output triangles are
* specified w.r.t. the indices of these vertices.
* triangles: Output array to hold triangles.
*
* Enough space must be allocated for all the arrays before calling
* this routine
*/
int triangulate_polygon(ncontours, cntr, vertices, triangles)
int ncontours;
int cntr[];
double (*vertices)[2];
int (*triangles)[3];
{
register int i;
int nmonpoly, ccount, npoints, genus;
int n;
memset((void *)seg, 0, sizeof(seg));
ccount = 0;
i = 1;
while (ccount < ncontours)
{
int j;
int first, last;
npoints = cntr[ccount];
first = i;
last = first + npoints - 1;
for (j = 0; j < npoints; j++, i++)
{
seg[i].v0.x = vertices[i][0];
seg[i].v0.y = vertices[i][1];
if (i == last)
{
seg[i].next = first;
seg[i].prev = i-1;
seg[i-1].v1 = seg[i].v0;
}
else if (i == first)
{
seg[i].next = i+1;
seg[i].prev = last;
seg[last].v1 = seg[i].v0;
}
else
{
seg[i].prev = i-1;
seg[i].next = i+1;
seg[i-1].v1 = seg[i].v0;
}
seg[i].is_inserted = FALSE;
}
ccount++;
}
genus = ncontours - 1;
n = i-1;
initialise(n);
construct_trapezoids(n);
nmonpoly = monotonate_trapezoids(n);
triangulate_monotone_polygons(n, nmonpoly, triangles);
return 0;
}
/* This function returns TRUE or FALSE depending upon whether the
* vertex is inside the polygon or not. The polygon must already have
* been triangulated before this routine is called.
* This routine will always detect all the points belonging to the
* set (polygon-area - polygon-boundary). The return value for points
* on the boundary is not consistent!!!
*/
int is_point_inside_polygon(vertex)
double vertex[2];
{
point_t v;
int trnum, rseg;
trap_t *t;
v.x = vertex[0];
v.y = vertex[1];
trnum = locate_endpoint(&v, &v, 1);
t = &tr[trnum];
if (t->state == ST_INVALID)
return FALSE;
if ((t->lseg <= 0) || (t->rseg <= 0))
return FALSE;
rseg = t->rseg;
return _greater_than_equal_to(&seg[rseg].v1, &seg[rseg].v0);
}