Exemplo n.º 1
0
v_data *delaunay_triangulation(double *x, double *y, int n)
{
    v_data *delaunay;
    GtsSurface* s = tri(x, y, n, NULL, 0, 1);
    int i, nedges;
    int* edges;
    estats stats;

    if (!s) return NULL;

    delaunay = N_GNEW(n, v_data);

    for (i = 0; i < n; i++) {
	delaunay[i].ewgts = NULL;
	delaunay[i].nedges = 1;
    }

    stats.n = 0;
    stats.delaunay = delaunay;
    edgeStats (s, &stats);
    nedges = stats.n;
    edges = N_GNEW(2 * nedges + n, int);

    for (i = 0; i < n; i++) {
	delaunay[i].edges = edges;
	edges += delaunay[i].nedges;
	delaunay[i].edges[0] = i;
	delaunay[i].nedges = 1;
    }
    gts_surface_foreach_edge (s, (GtsFunc) add_edge, delaunay);

    gts_object_destroy (GTS_OBJECT (s));

    return delaunay;
}
Exemplo n.º 2
0
/* delaunay_tri:
 * Given n points whose coordinates are in the x[] and y[]
 * arrays, compute a Delaunay triangulation of the points.
 * The number of edges in the triangulation is returned in pnedges.
 * The return value itself is an array e of 2*(*pnedges) integers,
 * with edge i having points whose indices are e[2*i] and e[2*i+1].
 *
 * If the points are collinear, GTS fails with 0 edges.
 * In this case, we sort the points by x coordinates (or y coordinates
 * if the points form a vertical line). We then return a "triangulation"
 * consisting of the n-1 pairs of adjacent points.
 */
int *delaunay_tri(double *x, double *y, int n, int* pnedges)
{
    GtsSurface* s = tri(x, y, n, NULL, 0, 1);
    int nedges;
    int* edges;
    estats stats;
    estate state;

    if (!s) return NULL;

    stats.n = 0;
    stats.delaunay = NULL;
    edgeStats (s, &stats);
    *pnedges = nedges = stats.n;

    if (nedges) {
	edges = N_GNEW(2 * nedges, int);
	state.n = 0;
	state.edges = edges;
	gts_surface_foreach_edge (s, (GtsFunc) addEdge, &state);
    }
    else {
Exemplo n.º 3
0
/**
 * gts_bb_tree_surface_boundary_distance:
 * @tree: a bounding box tree.
 * @s: a #GtsSurface.
 * @distance: a #GtsBBoxDistFunc.
 * @delta: a sampling increment defined as the percentage of the diagonal
 * of the root bounding box of @tree.
 * @range: a #GtsRange to be filled with the results.
 *
 * Calls gts_bb_tree_segment_distance() for each edge boundary of @s.
 * The fields of @range are filled with the minimum, maximum and
 * average distance. The average distance is defined as the sum of the
 * average distances for each boundary edge weighthed by their length
 * and divided by the total length of the boundaries. The standard
 * deviation is defined accordingly. The @n field of @range is filled
 * with the number of sampled points used.  
 */
void gts_bb_tree_surface_boundary_distance (GNode * tree,
					    GtsSurface * s,
					    gdouble (*distance) (GtsPoint *,
								 gpointer),
					    gdouble delta,
					    GtsRange * range)
{
  gpointer data[5];
  gdouble total_length = 0.;

  g_return_if_fail (tree != NULL);
  g_return_if_fail (s != NULL);
  g_return_if_fail (delta > 0. && delta < 1.);
  g_return_if_fail (range != NULL);

  gts_range_init (range);
  delta *= sqrt (gts_bbox_diagonal2 (tree->data));
  data[0] = tree;
  data[1] = &delta;
  data[2] = range;
  data[3] = &total_length;
  data[4] = distance;

  gts_surface_foreach_edge (s, 
			    (GtsFunc) surface_distance_foreach_boundary, 
			    data);

  if (total_length > 0.) {
    if (range->sum2 - range->sum*range->sum/total_length >= 0.)
      range->stddev = sqrt ((range->sum2 - 
			     range->sum*range->sum/total_length)
			    /total_length);
    else
      range->stddev = 0.;
    range->mean = range->sum/total_length;
  }
  else
    range->min = range->max = range->mean = range->stddev = 0.;
}
Exemplo n.º 4
0
Arquivo: optimize.c Projeto: bert/gts
static void surface_optimize (GtsSurface * surface,
                              gdouble max_cost)
{
    GtsEHeap * heap;
    GtsEdge * e;
    gdouble top_cost;

    heap = gts_eheap_new ((GtsKeyFunc) edge_swap_cost, NULL);
    gts_eheap_freeze (heap);
    gts_surface_foreach_edge (surface, (GtsFunc) create_heap_optimize, heap);
    gts_eheap_thaw (heap);

    gts_allow_floating_edges = TRUE;
    while ((e = gts_eheap_remove_top (heap, &top_cost)) &&
            top_cost < max_cost)
        edge_swap (e, surface, heap);
    gts_allow_floating_edges = FALSE;

    if (e) GTS_OBJECT (e)->reserved = NULL;
    gts_eheap_foreach (heap, (GFunc) gts_object_reset_reserved, NULL);

    gts_eheap_destroy (heap);
}
Exemplo n.º 5
0
int main (int argc, char * argv[])
{
  GtsSurface * s;
  guint i;
  GtsFile * fp;
  guint nv = 1, ne = 1, nf = 1;

  if (!setlocale (LC_ALL, "POSIX"))
    g_warning ("cannot set locale to POSIX");

  s = gts_surface_new (gts_surface_class (),
		       gts_face_class (),
		       gts_edge_class (),
		       gts_vertex_class ());
  fp = gts_file_new (stdin);
  if (gts_surface_read (s, fp)) {
    fputs ("gtstoc: file on standard input is not a valid GTS file\n", 
	   stderr);
    fprintf (stderr, "stdin:%d:%d: %s\n", fp->line, fp->pos, fp->error);
    return 1; /* failure */
  }

  printf ("  GtsSurface * surface = gts_surface_new (gts_surface_class (),\n"
	  "                                          gts_face_class (),\n"
	  "                                          gts_edge_class (),\n"
	  "                                          gts_vertex_class ());\n\n");
  gts_surface_foreach_vertex (s, (GtsFunc) write_vertex, &nv);
  printf ("\n");
  gts_surface_foreach_edge (s, (GtsFunc) write_edge, &ne);  
  printf ("\n");
  gts_surface_foreach_face (s, (GtsFunc) write_face, &nf);  
  printf ("  \n");
  for (i = 1; i < nf; i++)
    printf ("  gts_surface_add_face (surface, f%u);\n", i);

  return 0;
}
Exemplo n.º 6
0
void 
pygts_edge_cleanup(GtsSurface *s)
{
  GSList *edges = NULL;
  GSList *i, *ii, *cur, *parents=NULL;
  PygtsEdge *edge;
  GtsEdge *e, *duplicate;

  g_return_if_fail(s != NULL);

  /* build list of edges */
  gts_surface_foreach_edge(s, (GtsFunc)build_list, &edges);

  /* remove degenerate and duplicate edges.
     Note: we could use gts_edges_merge() to remove the duplicates and then
     remove the degenerate edges but it is more efficient to do everything 
     at once (and it's more pedagogical too ...) */

  /* We want to control manually the destruction of edges */
  gts_allow_floating_edges = TRUE;

  i = edges;
  while(i) {
    e = (GtsEdge*)i->data;
    if(GTS_SEGMENT(e)->v1 == GTS_SEGMENT(e)->v2) {
      /* edge is degenerate */
      if( !g_hash_table_lookup(obj_table,GTS_OBJECT(e)) ) {
	/* destroy e */
	gts_object_destroy(GTS_OBJECT(e));
      }
    }
    else {
      if((duplicate = gts_edge_is_duplicate(e))) {

	/* Detach and save any parent triangles */
	if( (edge = PYGTS_EDGE(g_hash_table_lookup(obj_table,GTS_OBJECT(e))))
	    !=NULL ) {
	  ii = e->triangles;
	  while(ii!=NULL) {
	    cur = ii;
	    ii = g_slist_next(ii);
	    if(PYGTS_IS_PARENT_TRIANGLE(cur->data)) {
	      e->triangles = g_slist_remove_link(e->triangles, cur);
	      parents = g_slist_prepend(parents,cur->data);
	      g_slist_free_1(cur);
	    }
	  } 
	}

	/* replace e with its duplicate */
	gts_edge_replace(e, duplicate);

	/* Reattach the parent segments */
	if( edge != NULL ) {
	  ii = parents;
	  while(ii!=NULL) {
	    e->triangles = g_slist_prepend(e->triangles, ii->data);
	    ii = g_slist_next(ii);
	  }
	  g_slist_free(parents);
	  parents = NULL;
	}

	if( !g_hash_table_lookup(obj_table,GTS_OBJECT(e)) ) {
	  /* destroy e */
	  gts_object_destroy(GTS_OBJECT (e));
	}
      }
    }
    i = g_slist_next(i);
  }
  
  /* don't forget to reset to default */
  gts_allow_floating_edges = FALSE;

  /* free list of edges */
  g_slist_free (edges);
}
Exemplo n.º 7
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;
}
Exemplo n.º 8
0
static void
edgeStats (GtsSurface* s, estats* sp)
{
    gts_surface_foreach_edge (s, (GtsFunc) cnt_edge, sp);
}
Exemplo n.º 9
0
Arquivo: optimize.c Projeto: bert/gts
int main (int argc, char * argv[])
{
    GtsSurface * s;
    gboolean verbose = FALSE;
    gdouble threshold;
    int c = 0;
    GtsFile * fp;
    GtsRange angle;

    if (!setlocale (LC_ALL, "POSIX"))
        g_warning ("cannot set locale to POSIX");

    /* parse options using getopt */
    while (c != EOF) {
#ifdef HAVE_GETOPT_LONG
        static struct option long_options[] = {
            {"help", no_argument, NULL, 'h'},
            {"verbose", no_argument, NULL, 'v'},
            { NULL }
        };
        int option_index = 0;
        switch ((c = getopt_long (argc, argv, "hv",
                                  long_options, &option_index))) {
#else /* not HAVE_GETOPT_LONG */
        switch ((c = getopt (argc, argv, "hv"))) {
#endif /* not HAVE_GETOPT_LONG */
        case 'v': /* verbose */
            verbose = TRUE;
            break;
        case 'h': /* help */
            fprintf (stderr,
                     "Usage: optimize [OPTION] THRESHOLD < FILE\n"
                     "\n"
                     "  -v      --verbose  print statistics about the surface\n"
                     "  -h      --help     display this help and exit\n"
                     "\n"
                     "Report bugs to %s\n",
                     GTS_MAINTAINER);
            return 0; /* success */
            break;
        case '?': /* wrong options */
            fprintf (stderr, "Try `optimize --help' for more information.\n");
            return 1; /* failure */
        }
    }

    if (optind >= argc) { /* missing threshold */
        fprintf (stderr,
                 "optimize: missing THRESHOLD\n"
                 "Try `optimize --help' for more information.\n");
        return 1; /* failure */
    }
    threshold = strtod (argv[optind], NULL);

    if (threshold < 0.0) { /* threshold must be positive */
        fprintf (stderr,
                 "optimize: THRESHOLD must be >= 0.0\n"
                 "Try `optimize --help' for more information.\n");
        return 1; /* failure */
    }

    /* read surface in */
    s = gts_surface_new (gts_surface_class (),
                         gts_face_class (),
                         gts_edge_class (),
                         gts_vertex_class ());
    fp = gts_file_new (stdin);
    if (gts_surface_read (s, fp)) {
        fputs ("optimize: file on standard input is not a valid GTS file\n",
               stderr);
        fprintf (stderr, "stdin:%d:%d: %s\n", fp->line, fp->pos, fp->error);
        return 1; /* failure */
    }

    /* if verbose on print stats */
    if (verbose) {
        gts_surface_print_stats (s, stderr);
        gts_range_init (&angle);
        gts_surface_foreach_edge (s, (GtsFunc) angle_stats, &angle);
        gts_range_update (&angle);
        fputs ("#   angle : ", stderr);
        gts_range_print (&angle, stderr);
        fputc ('\n', stderr);
    }

    surface_optimize (s, -threshold);

    /* if verbose on print stats */
    if (verbose) {
        gts_surface_print_stats (s, stderr);
        gts_range_init (&angle);
        gts_surface_foreach_edge (s, (GtsFunc) angle_stats, &angle);
        gts_range_update (&angle);
        fputs ("#   angle : ", stderr);
        gts_range_print (&angle, stderr);
        fputc ('\n', stderr);
    }

    /* write surface */
    gts_surface_write (s, stdout);

    return 0; /* success */
}