Пример #1
0
static void add_constraint (GtsConstraint * c, GtsSurface * s)
{
  g_assert (gts_delaunay_add_constraint (s, c) == NULL);
}
Пример #2
0
static GtsSurface * cartesian_grid_triangulate_holes (CartesianGrid * grid,
						      GtsSurface * s)
{
  GtsVertex * v1, * v2, * v3, * v4;
  GtsEdge * e1, * e2, * e3, * e4, * e5;
  gdouble w, h;
  GtsSurface * box;
  GSList * constraints = NULL, * vertices = NULL, * i;
  gpointer data[2];

  g_return_val_if_fail (grid != NULL, NULL);
  g_return_val_if_fail (s != NULL, NULL);

  /* build enclosing box */
  w = grid->xmax - grid->xmin;
  h = grid->ymax - grid->ymin;
  v1 = gts_vertex_new (s->vertex_class, grid->xmin - w, grid->ymin - h, 0.);
  v2 = gts_vertex_new (s->vertex_class, grid->xmax + w, grid->ymin - h, 0.);
  v3 = gts_vertex_new (s->vertex_class, grid->xmax + w, grid->ymax + h, 0.);
  v4 = gts_vertex_new (s->vertex_class, grid->xmin - w, grid->ymax + h, 0.);

  e1 = gts_edge_new (s->edge_class, v1, v2);
  e2 = gts_edge_new (s->edge_class, v2, v3);
  e3 = gts_edge_new (s->edge_class, v3, v4);
  e4 = gts_edge_new (s->edge_class, v4, v1);
  e5 = gts_edge_new (s->edge_class, v1, v3);

  box = gts_surface_new (GTS_SURFACE_CLASS (GTS_OBJECT (s)->klass), 
			 s->face_class, 
			 s->edge_class, 
			 s->vertex_class);
  gts_surface_add_face (box, gts_face_new (s->face_class, e1, e2, e5));
  gts_surface_add_face (box, gts_face_new (s->face_class, e3, e4, e5));

  /* build vertex and constraint list from the boundaries of the input
     surface s */
  data[0] = s;
  data[1] = &constraints;
  gts_surface_foreach_edge (s, (GtsFunc) build_constraint_list, data);
  vertices = gts_vertices_from_segments (constraints);

  /* triangulate holes */
  i = vertices;
  while (i) {
    g_assert (!gts_delaunay_add_vertex (box, i->data, NULL));
    i = i->next;
  }
  g_slist_free (vertices);

  i = constraints;
  while (i) {
    g_assert (!gts_delaunay_add_constraint (box, i->data));
    i = i->next;
  }

  /* destroy corners of the enclosing box */
  gts_allow_floating_vertices = TRUE;
  gts_object_destroy (GTS_OBJECT (v1));
  gts_object_destroy (GTS_OBJECT (v2));
  gts_object_destroy (GTS_OBJECT (v3));
  gts_object_destroy (GTS_OBJECT (v4));
  gts_allow_floating_vertices = FALSE;

  /* remove parts of the mesh which are not holes */
  i = constraints;
  while (i) {
    edge_mark_as_hole (i->data, box);
    i = i->next;
  }
  g_slist_free (constraints);

  /* remove marked and duplicate faces */
  gts_surface_foreach_face_remove (box, (GtsFunc) face_is_marked, NULL);

  /* box now contains only the triangulated holes. */
  return box;
}
Пример #3
0
/* tri:
 * Main entry point to using GTS for triangulation.
 * Input is npt points with x and y coordinates stored either separately
 * in x[] and y[] (sepArr != 0) or consecutively in x[] (sepArr == 0).
 * Optionally, the input can include nsegs line segments, whose endpoint
 * indices are supplied in segs[2*i] and segs[2*i+1] yielding a constrained
 * triangulation.
 *
 * The return value is the corresponding gts surface, which can be queries for
 * the triangles and line segments composing the triangulation.
 */
static GtsSurface*
tri(double *x, double *y, int npt, int *segs, int nsegs, int sepArr)
{
    int i;
    GtsSurface *surface;
    GVertex **vertices = N_GNEW(npt, GVertex *);
    GtsEdge **edges = N_GNEW(nsegs, GtsEdge*);
    GSList *list = NULL;
    GtsVertex *v1, *v2, *v3;
    GtsTriangle *t;
    GtsVertexClass *vcl = (GtsVertexClass *) g_vertex_class();
    GtsEdgeClass *ecl = GTS_EDGE_CLASS (gts_constraint_class ());

    if (sepArr) {
	for (i = 0; i < npt; i++) {
	    GVertex *p = (GVertex *) gts_vertex_new(vcl, x[i], y[i], 0);
	    p->idx = i;
	    vertices[i] = p;
	}
    }
    else {
	for (i = 0; i < npt; i++) {
	    GVertex *p = (GVertex *) gts_vertex_new(vcl, x[2*i], x[2*i+1], 0);
	    p->idx = i;
	    vertices[i] = p;
	}
    }

    /* N.B. Edges need to be created here, presumably before the
     * the vertices are added to the face. In particular, they cannot
     * be added created and added vi gts_delaunay_add_constraint() below.
     */
    for (i = 0; i < nsegs; i++) {
	edges[i] = gts_edge_new(ecl,
		 (GtsVertex *) (vertices[ segs[ 2 * i]]),
		 (GtsVertex *) (vertices[ segs[ 2 * i + 1]]));
    }

    for (i = 0; i < npt; i++)
	list = g_slist_prepend(list, vertices[i]);
    t = gts_triangle_enclosing(gts_triangle_class(), list, 100.);
    g_slist_free(list);

    gts_triangle_vertices(t, &v1, &v2, &v3);

    surface = gts_surface_new(gts_surface_class(),
				  (GtsFaceClass *) g_face_class(),
				  gts_edge_class(),
				  gts_vertex_class());
    gts_surface_add_face(surface, gts_face_new(gts_face_class(),
					       t->e1, t->e2, t->e3));

    for (i = 0; i < npt; i++) {
	GtsVertex *v1 = (GtsVertex *) vertices[i];
	GtsVertex *v = gts_delaunay_add_vertex(surface, v1, NULL);

	/* if v != NULL, it is a previously added pt with the same
	 * coordinates as v1, in which case we replace v1 with v
	 */
	if (v) {
	    /* agerr (AGWARN, "Duplicate point %d %d\n", i, ((GVertex*)v)->idx); */
	    gts_vertex_replace (v1, v);
	}
    }

    for (i = 0; i < nsegs; i++) {
	gts_delaunay_add_constraint(surface,GTS_CONSTRAINT(edges[i]));
    }

    /* destroy enclosing triangle */
    gts_allow_floating_vertices = TRUE;
    gts_allow_floating_edges = TRUE;
/*
    gts_object_destroy(GTS_OBJECT(v1));
    gts_object_destroy(GTS_OBJECT(v2));
    gts_object_destroy(GTS_OBJECT(v3));
*/
    destroy(v1);
    destroy(v2);
    destroy(v3);
    gts_allow_floating_edges = FALSE;
    gts_allow_floating_vertices = FALSE;

    if (nsegs)
	delaunay_remove_holes(surface);

    free (edges);
    free(vertices);
    return surface;
}