28 static gboolean triangle_is_hole(GtsTriangle * t)
30 GtsEdge *e1, *e2, *e3;
31 GtsVertex *v1, *v2, *v3;
34 gts_triangle_vertices_edges(t,
NULL, &v1, &v2, &v3, &e1, &e2, &e3);
36 if ((GTS_IS_CONSTRAINT(e1) && GTS_SEGMENT(e1)->v1 != v1) ||
37 (GTS_IS_CONSTRAINT(e2) && GTS_SEGMENT(e2)->v1 != v2) ||
38 (GTS_IS_CONSTRAINT(e3) && GTS_SEGMENT(e3)->v1 != v3))
44 static guint delaunay_remove_holes(GtsSurface * surface)
46 return gts_surface_foreach_face_remove(surface,
47 (GtsFunc) triangle_is_hole,
NULL);
61 GtsVertexClass parent_class;
64 static GVertexClass *g_vertex_class(
void)
66 static GVertexClass *klass =
NULL;
69 GtsObjectClassInfo vertex_info = {
73 (GtsObjectClassInitFunc)
NULL,
74 (GtsObjectInitFunc)
NULL,
78 klass = gts_object_class_new(GTS_OBJECT_CLASS(gts_vertex_class()),
91 GtsFaceClass parent_class;
94 static GFaceClass *g_face_class(
void)
96 static GFaceClass *klass =
NULL;
99 GtsObjectClassInfo face_info = {
103 (GtsObjectClassInitFunc)
NULL,
104 (GtsObjectInitFunc)
NULL,
105 (GtsArgSetFunc)
NULL,
108 klass = gts_object_class_new(GTS_OBJECT_CLASS(gts_face_class()),
119 destroy (GtsVertex* v)
125 GSList * next = i->next;
126 gts_object_destroy (i->data);
129 g_assert (v->segments == NULL);
130 gts_object_destroy(GTS_OBJECT(v));
145 tri(
double *x,
double *y,
int npt,
int *segs,
int nsegs,
int sepArr)
149 GVertex **vertices =
N_GNEW(npt, GVertex *);
150 GtsEdge **edges =
N_GNEW(nsegs, GtsEdge*);
152 GtsVertex *v1, *v2, *v3;
154 GtsVertexClass *vcl = (GtsVertexClass *) g_vertex_class();
155 GtsEdgeClass *ecl = GTS_EDGE_CLASS (gts_constraint_class ());
158 for (i = 0; i < npt; i++) {
159 GVertex *p = (GVertex *) gts_vertex_new(vcl, x[i], y[i], 0);
165 for (i = 0; i < npt; i++) {
166 GVertex *p = (GVertex *) gts_vertex_new(vcl, x[2*i], x[2*i+1], 0);
176 for (i = 0; i < nsegs; i++) {
177 edges[i] = gts_edge_new(ecl,
178 (GtsVertex *) (vertices[ segs[ 2 * i]]),
179 (GtsVertex *) (vertices[ segs[ 2 * i + 1]]));
182 for (i = 0; i < npt; i++)
183 list = g_slist_prepend(list, vertices[i]);
184 t = gts_triangle_enclosing(gts_triangle_class(), list, 100.);
187 gts_triangle_vertices(t, &v1, &v2, &v3);
189 surface = gts_surface_new(gts_surface_class(),
190 (GtsFaceClass *) g_face_class(),
193 gts_surface_add_face(surface, gts_face_new(gts_face_class(),
194 t->e1, t->e2, t->e3));
196 for (i = 0; i < npt; i++) {
197 GtsVertex *v1 = (GtsVertex *) vertices[i];
198 GtsVertex *v = gts_delaunay_add_vertex(surface, v1, NULL);
205 gts_vertex_replace (v1, v);
209 for (i = 0; i < nsegs; i++) {
210 gts_delaunay_add_constraint(surface,GTS_CONSTRAINT(edges[i]));
214 gts_allow_floating_vertices =
TRUE;
215 gts_allow_floating_edges =
TRUE;
224 gts_allow_floating_edges =
FALSE;
225 gts_allow_floating_vertices =
FALSE;
228 delaunay_remove_holes(surface);
240 static void cnt_edge (GtsSegment * e, estats* sp)
244 sp->delaunay[((GVertex*)(e->v1))->idx].nedges++;
245 sp->delaunay[((GVertex*)(e->v2))->idx].nedges++;
250 edgeStats (GtsSurface*
s, estats* sp)
252 gts_surface_foreach_edge (s, (GtsFunc) cnt_edge, sp);
257 int source = ((GVertex*)(e->v1))->idx;
258 int dest = ((GVertex*)(e->v2))->idx;
260 delaunay[source].
edges[delaunay[source].
nedges++] = dest;
261 delaunay[dest].
edges[delaunay[dest].
nedges++] = source;
267 GtsSurface* s =
tri(x, y, n, NULL, 0, 1);
276 for (i = 0; i < n; i++) {
282 stats.delaunay = delaunay;
283 edgeStats (s, &stats);
285 edges =
N_GNEW(2 * nedges + n,
int);
287 for (i = 0; i < n; i++) {
288 delaunay[i].
edges = edges;
289 edges += delaunay[i].
nedges;
290 delaunay[i].
edges[0] = i;
293 gts_surface_foreach_edge (s, (GtsFunc)
add_edge, delaunay);
295 gts_object_destroy (GTS_OBJECT (s));
305 static void addEdge (GtsSegment * e, estate* es)
307 int source = ((GVertex*)(e->v1))->idx;
308 int dest = ((GVertex*)(e->v2))->idx;
310 es->
edges[2*(es->n)] = source;
311 es->edges[2*(es->n)+1] = dest;
318 static double* _vals;
322 vcmp (
int* a,
int* b)
324 double va = _vals[*a];
325 double vb = _vals[*b];
327 if (va < vb)
return -1;
328 else if (va > vb)
return 1;
344 int *
delaunay_tri(
double *x,
double *y,
int n,
int* pnedges)
346 GtsSurface* s =
tri(x, y, n, NULL, 0, 1);
355 stats.delaunay =
NULL;
356 edgeStats (s, &stats);
357 *pnedges = nedges = stats.n;
360 edges =
N_GNEW(2 * nedges,
int);
363 gts_surface_foreach_edge (s, (GtsFunc) addEdge, &state);
370 *pnedges = nedges = n-1;
371 ip = edges =
N_GNEW(2 * nedges,
int);
373 for (i = 0; i < n; i++)
383 for (i = 1; i < n; i++) {
393 gts_object_destroy (GTS_OBJECT (s));
398 static void cntFace (GFace* fp,
int* ip)
415 static void addNeighbor (GFace* f, ninfo* es)
417 es->neigh[es->nneigh] = f->idx;
421 static void addFace (GFace* f, fstate* es)
423 int i, myid = f->idx;
424 int* ip = es->faces + 3*myid;
425 int* neigh = es->neigh + 3*myid;
427 GtsVertex *v1, *v2, *v3;
429 gts_triangle_vertices (&f->v.triangle, &v1, &v2, &v3);
430 *ip++ = ((GVertex*)(v1))->idx;
431 *ip++ = ((GVertex*)(v2))->idx;
432 *ip++ = ((GVertex*)(v3))->idx;
436 gts_face_foreach_neighbor ((GtsFace*)f, 0, (GtsFunc) addNeighbor, &ni);
437 for (i = ni.nneigh; i < 3; i++)
441 static void addTri (GFace* f, fstate* es)
444 int* ip = es->faces + 3*myid;
445 GtsVertex *v1, *v2, *v3;
447 gts_triangle_vertices (&f->v.triangle, &v1, &v2, &v3);
448 *ip++ = ((GVertex*)(v1))->idx;
449 *ip++ = ((GVertex*)(v2))->idx;
450 *ip++ = ((GVertex*)(v3))->idx;
461 mkSurface (
double *x,
double *y,
int n,
int* segs,
int nsegs)
463 GtsSurface* s =
tri(x, y, n, segs, nsegs, 1);
476 stats.delaunay =
NULL;
477 edgeStats (s, &stats);
479 segs =
N_GNEW(2 * nsegs,
int);
483 gts_surface_foreach_edge (s, (GtsFunc) addEdge, &state);
485 gts_surface_foreach_face (s, (GtsFunc) cntFace, &nfaces);
487 faces =
N_GNEW(3 * nfaces,
int);
488 neigh =
N_GNEW(3 * nfaces,
int);
492 gts_surface_foreach_face (s, (GtsFunc) addFace, &statf);
500 gts_object_destroy (GTS_OBJECT (s));
519 if (n <= 2)
return NULL;
521 s =
tri(x, NULL, n, NULL, 0, 0);
524 gts_surface_foreach_face (s, (GtsFunc) cntFace, &nfaces);
525 statf.faces =
N_GNEW(3 * nfaces,
int);
526 gts_surface_foreach_face (s, (GtsFunc) addTri, &statf);
528 gts_object_destroy (GTS_OBJECT (s));
543 #include "triangle.c"
550 struct triangulateio in, mid, vorout;
553 if (n <= 2)
return NULL;
555 in.numberofpoints = n;
556 in.numberofpointattributes = 0;
557 in.pointlist = (REAL *)
N_GNEW(in.numberofpoints * 2, REAL);
559 for (i = 0; i < n; i++){
560 in.pointlist[i*2] = x[i*2];
561 in.pointlist[i*2 + 1] = x[i*2 + 1];
563 in.pointattributelist =
NULL;
564 in.pointmarkerlist =
NULL;
565 in.numberofsegments = 0;
566 in.numberofholes = 0;
567 in.numberofregions = 0;
568 in.regionlist =
NULL;
569 mid.pointlist = (REAL *) NULL;
570 mid.pointattributelist = (REAL *) NULL;
571 mid.pointmarkerlist = (
int *) NULL;
572 mid.trianglelist = (
int *) NULL;
573 mid.triangleattributelist = (REAL *) NULL;
574 mid.neighborlist = (
int *) NULL;
575 mid.segmentlist = (
int *) NULL;
576 mid.segmentmarkerlist = (
int *) NULL;
577 mid.edgelist = (
int *) NULL;
578 mid.edgemarkerlist = (
int *) NULL;
579 vorout.pointlist = (REAL *) NULL;
580 vorout.pointattributelist = (REAL *) NULL;
581 vorout.edgelist = (
int *) NULL;
582 vorout.normlist = (REAL *) NULL;
590 triangulate(
"Qenv", &in, &mid, &vorout);
591 assert (mid.numberofcorners == 3);
593 *tris = mid.numberoftriangles;
596 FREE(in.pointattributelist);
597 FREE(in.pointmarkerlist);
600 FREE(mid.pointattributelist);
601 FREE(mid.pointmarkerlist);
602 FREE(mid.triangleattributelist);
603 FREE(mid.neighborlist);
604 FREE(mid.segmentlist);
605 FREE(mid.segmentmarkerlist);
607 FREE(mid.edgemarkerlist);
608 FREE(vorout.pointlist);
609 FREE(vorout.pointattributelist);
610 FREE(vorout.edgelist);
611 FREE(vorout.normlist);
613 return mid.trianglelist;
620 struct triangulateio in, out;
623 in.pointlist =
N_GNEW(2 * n, REAL);
624 for (i = 0; i < n; i++) {
625 in.pointlist[2 * i] = x[i];
626 in.pointlist[2 * i + 1] = y[i];
629 in.pointattributelist =
NULL;
630 in.pointmarkerlist =
NULL;
631 in.numberofpoints = n;
632 in.numberofpointattributes = 0;
633 in.trianglearealist =
NULL;
634 in.triangleattributelist =
NULL;
635 in.numberoftriangleattributes = 0;
636 in.neighborlist =
NULL;
637 in.segmentlist =
NULL;
638 in.segmentmarkerlist =
NULL;
640 in.numberofholes = 0;
641 in.regionlist =
NULL;
643 in.edgemarkerlist =
NULL;
646 out.pointattributelist =
NULL;
647 out.pointmarkerlist =
NULL;
648 out.numberofpoints = n;
649 out.numberofpointattributes = 0;
650 out.trianglearealist =
NULL;
651 out.triangleattributelist =
NULL;
652 out.numberoftriangleattributes = 0;
653 out.neighborlist =
NULL;
654 out.segmentlist =
NULL;
655 out.segmentmarkerlist =
NULL;
657 out.numberofholes = 0;
658 out.regionlist =
NULL;
660 out.edgemarkerlist =
NULL;
663 triangulate(
"zQNEeB", &in, &out, NULL);
665 *nedges = out.numberofedges;
667 free (in.pointattributelist);
668 free (in.pointmarkerlist);
669 free (in.trianglearealist);
670 free (in.triangleattributelist);
671 free (in.neighborlist);
672 free (in.segmentlist);
673 free (in.segmentmarkerlist);
675 free (in.regionlist);
676 free (in.edgemarkerlist);
678 free (out.pointattributelist);
679 free (out.pointmarkerlist);
680 free (out.trianglearealist);
681 free (out.triangleattributelist);
682 free (out.neighborlist);
683 free (out.segmentlist);
684 free (out.segmentmarkerlist);
686 free (out.regionlist);
687 free (out.edgemarkerlist);
702 edges =
N_GNEW(2 * nedges + n,
int);
704 for (i = 0; i < n; i++) {
709 for (i = 0; i < 2 * nedges; i++)
710 delaunay[edgelist[i]].nedges++;
712 for (i = 0; i < n; i++) {
713 delaunay[i].
edges = edges;
714 edges += delaunay[i].
nedges;
715 delaunay[i].
edges[0] = i;
718 for (i = 0; i < nedges; i++) {
719 source = edgelist[2 * i];
720 dest = edgelist[2 * i + 1];
721 delaunay[source].
edges[delaunay[source].
nedges++] = dest;
722 delaunay[dest].
edges[delaunay[dest].
nedges++] = source;
730 mkSurface (
double *x,
double *y,
int n,
int* segs,
int nsegs)
732 agerr (
AGERR,
"mkSurface not yet implemented using Triangle library\n");
739 agerr (
AGERR,
"freeSurface not yet implemented using Triangle library\n");
743 static char* err =
"Graphviz built without any triangulation library\n";
751 agerr(
AGERR,
"delaunay_triangulation: %s\n", err);
760 mkSurface (
double *x,
double *y,
int n,
int* segs,
int nsegs)
775 for (i = 1; i < graph[source].
nedges; i++) {
776 if (graph[source].edges[i] == dest) {
777 graph[source].
edges[i] =
788 double dist_ij, dist_ik, dist_jk, x_i, y_i, x_j, y_j;
789 int j, k, neighbor_j, neighbor_k;
793 int *edges =
N_GNEW(4,
int);
796 delaunay[0].
edges = edges;
798 delaunay[0].
edges[0] = 0;
799 delaunay[0].
edges[1] = 1;
800 delaunay[1].
edges = edges + 2;
803 delaunay[1].
edges[0] = 1;
804 delaunay[1].
edges[1] = 0;
807 int *edges =
N_GNEW(1,
int);
810 delaunay[0].
edges = edges;
812 delaunay[0].
edges[0] = 0;
818 if (accurate_computation) {
819 for (i = 0; i < n; i++) {
822 for (j = 1; j < delaunay[i].
nedges;) {
823 neighbor_j = delaunay[i].
edges[j];
824 if (neighbor_j < i) {
831 (x_j - x_i) * (x_j - x_i) + (y_j - y_i) * (y_j - y_i);
833 for (k = 0; k < n && !removed; k++) {
835 (x[k] - x_i) * (x[k] - x_i) + (y[k] -
837 if (dist_ik < dist_ij) {
839 (x[k] - x_j) * (x[k] - x_j) + (y[k] -
842 if (dist_jk < dist_ij) {
844 delaunay[i].
edges[j] =
858 for (i = 0; i < n; i++) {
861 for (j = 1; j < delaunay[i].
nedges;) {
862 neighbor_j = delaunay[i].
edges[j];
866 (x_j - x_i) * (x_j - x_i) + (y_j - y_i) * (y_j - y_i);
870 for (k = 1; k < delaunay[i].
nedges && !removed; k++) {
871 neighbor_k = delaunay[i].
edges[k];
873 (x[neighbor_k] - x_i) * (x[neighbor_k] - x_i) +
874 (y[neighbor_k] - y_i) * (y[neighbor_k] - y_i);
875 if (dist_ik < dist_ij) {
877 (x[neighbor_k] - x_j) * (x[neighbor_k] - x_j) +
878 (y[neighbor_k] - y_j) * (y[neighbor_k] - y_j);
879 if (dist_jk < dist_ij) {
881 delaunay[i].
edges[j] =
900 if (graph[0].edges != NULL)
901 free(graph[0].edges);
902 if (graph[0].ewgts != NULL)
903 free(graph[0].ewgts);
911 if (graph[0].edges != NULL)
912 free(graph[0].edges);
913 if (graph[0].ewgts != NULL)
914 free(graph[0].ewgts);
916 if (graph[0].styles != NULL)
917 free(graph[0].styles);
920 if (graph[0].edists != NULL)
921 free(graph[0].edists);
v_data * delaunay_triangulation(double *x, double *y, int n)
int agerr(agerrlevel_t level, const char *fmt,...)
void add_edge(edgelist *list, Agedge_t *e)
void remove_edge(edgelist *list, Agedge_t *e)
int(* qsort_cmpf)(const void *, const void *)
int * delaunay_tri(double *x, double *y, int n, int *nedges)
Agraph_t * graph(char *name)
int * get_triangles(double *x, int n, int *tris)
void freeSurface(surface_t *s)
void freeGraphData(vtx_data *graph)
surface_t * mkSurface(double *x, double *y, int n, int *segs, int nsegs)
void freeGraph(v_data *graph)
v_data * UG_graph(double *x, double *y, int n, int accurate_computation)