示例#1
0
文件: bbtree.c 项目: ClavinSBU/gts
/**
 * gts_bb_tree_triangle_distance:
 * @tree: a bounding box tree.
 * @t: a #GtsTriangle.
 * @distance: a #GtsBBoxDistFunc.
 * @delta: spatial scale of the sampling to be used.
 * @range: a #GtsRange to be filled with the results.
 * 
 * Given a triangle @t, points are sampled regularly on its surface
 * using @delta as increment. The distance from each of these points
 * to the closest object of @tree is computed using @distance and the
 * gts_bb_tree_point_distance() function. The fields of @range are
 * filled with the number of points sampled, the minimum, average and
 * maximum value and the standard deviation.  
 */
void gts_bb_tree_triangle_distance (GNode * tree,
				    GtsTriangle * t,
				    GtsBBoxDistFunc distance,
				    gdouble delta,
				    GtsRange * range)
{
  GtsPoint * p1, * p2, * p3, * p;
  GtsVector p1p2, p1p3;
  gdouble l1, t1, dt1;
  guint i, n1;

  g_return_if_fail (tree != NULL);
  g_return_if_fail (t != NULL);
  g_return_if_fail (distance != NULL);
  g_return_if_fail (delta > 0.);
  g_return_if_fail (range != NULL);

  gts_triangle_vertices (t, 
			 (GtsVertex **) &p1, 
			 (GtsVertex **) &p2, 
			 (GtsVertex **) &p3);

  gts_vector_init (p1p2, p1, p2);
  gts_vector_init (p1p3, p1, p3);
  gts_range_init (range);
  p = GTS_POINT (gts_object_new (GTS_OBJECT_CLASS (gts_point_class ())));

  l1 = sqrt (gts_vector_scalar (p1p2, p1p2));
  n1 = l1/delta + 1;
  dt1 = 1.0/(gdouble) n1;
  t1 = 0.0;
  for (i = 0; i <= n1; i++, t1 += dt1) {
    gdouble t2 = 1. - t1;
    gdouble x = t2*p1p3[0];
    gdouble y = t2*p1p3[1];
    gdouble z = t2*p1p3[2];
    gdouble l2 = sqrt (x*x + y*y + z*z);
    guint j, n2 = (guint) (l2/delta + 1);
    gdouble dt2 = t2/(gdouble) n2;

    x = t2*p1->x + t1*p2->x;
    y = t2*p1->y + t1*p2->y;
    z = t2*p1->z + t1*p2->z;
    
    t2 = 0.0;
    for (j = 0; j <= n2; j++, t2 += dt2) {
      p->x = x + t2*p1p3[0];
      p->y = y + t2*p1p3[1];
      p->z = z + t2*p1p3[2];

      gts_range_add_value (range,
		    gts_bb_tree_point_distance (tree, p, distance, NULL));
    }
  }

  gts_object_destroy (GTS_OBJECT (p));
  gts_range_update (range);
}
示例#2
0
文件: happrox.c 项目: ClavinSBU/gts
static GtsSurface * happrox_list (GSList * points,
				  gboolean keep_enclosing,
				  gboolean closed,
				  CostFunc cost_func,
				  gpointer cost_data,
				  GtsStopFunc stop_func,
				  gpointer stop_data)
{
  GtsSurface * s = gts_surface_new (gts_surface_class (),
				    GTS_FACE_CLASS (list_face_class ()),
				    gts_edge_class (),
				    gts_vertex_class ());
  GtsTriangle * t;
  GtsVertex * w1, * w2, * w3;
  GtsListFace * f;

  /* creates enclosing triangle */
  t = gts_triangle_enclosing (gts_triangle_class (), points, 10.);
  gts_triangle_vertices (t, &w1, &w2, &w3);
  GTS_POINT (w1)->z = GTS_POINT (w2)->z = GTS_POINT (w3)->z = 
    keep_enclosing ? -10. : -1e30;

  f = GTS_LIST_FACE (gts_face_new (s->face_class, t->e1, t->e2, t->e3));
  gts_surface_add_face (s, GTS_FACE (f));
  f->points = points;

  /* refine surface */
  surface_hf_refine (s, cost_func, cost_data, stop_func, stop_data);

  /* destroy unused vertices */
  gts_surface_foreach_face (s, (GtsFunc) destroy_unused, NULL);
  
  /* destroy enclosing triangle */
  if (!keep_enclosing) {
    gts_allow_floating_vertices = TRUE;
    gts_object_destroy (GTS_OBJECT (w1));
    gts_object_destroy (GTS_OBJECT (w2));
    gts_object_destroy (GTS_OBJECT (w3));
    gts_allow_floating_vertices = FALSE;
  }
  else if (closed) {
    GSList * l = gts_surface_boundary (s);
    GtsFace * f;

    g_assert (g_slist_length (l) == 3);
    f = gts_face_new (s->face_class, l->data, l->next->data, l->next->next->data);
    gts_surface_add_face (s, f);
    if (!gts_face_is_compatible (f, s))
      gts_triangle_revert (GTS_TRIANGLE (f));
    g_slist_free (l);
    gts_object_destroy (GTS_OBJECT (t));
  }
  else
    gts_object_destroy (GTS_OBJECT (t));

  return s;
}
示例#3
0
文件: gts2stl.c 项目: Gilles86/afni
static void write_face (GtsTriangle * t)
{
  GtsVertex * v1, * v2, * v3;
  GtsVector n;

  gts_triangle_vertices (t, &v1, &v2, &v3);
  gts_triangle_normal (t, &n[0], &n[1], &n[2]);
  gts_vector_normalize (n);
  printf ("facet normal %g %g %g\nouter loop\n", n[0], n[1], n[2]);
  printf ("vertex %g %g %g\n", 
	  GTS_POINT (v1)->x, GTS_POINT (v1)->y, GTS_POINT (v1)->z);
  printf ("vertex %g %g %g\n", 
	  GTS_POINT (v2)->x, GTS_POINT (v2)->y, GTS_POINT (v2)->z);
  printf ("vertex %g %g %g\n", 
	  GTS_POINT (v3)->x, GTS_POINT (v3)->y, GTS_POINT (v3)->z);
  puts ("endloop\nendfacet");
}
示例#4
0
static void face_load (GtsTriangle * t, gpointer * data)
{
  int *FaceSetList = (int *)data[0];
  int *n = (int *)data[1];
  GtsVertex * v1, * v2, * v3;
  gts_triangle_vertices (t, &v1, &v2, &v3);
  FaceSetList[*n*3] = (int)GPOINTER_TO_UINT (GTS_OBJECT (v1)->reserved);
  FaceSetList[*n*3+1] =(int) GPOINTER_TO_UINT (GTS_OBJECT (v2)->reserved);
  FaceSetList[*n*3+2] = (int)GPOINTER_TO_UINT (GTS_OBJECT (v3)->reserved);
  if (debug) {
    fprintf (stderr, "Triangle %d: %d %d %d\n", 
               *n, FaceSetList[*n*3], 
                   FaceSetList[*n*3+1], 
                   FaceSetList[*n*3+2]); 
  }
  GTS_OBJECT (t)->reserved = GUINT_TO_POINTER ((*((guint *) data[1]))++);
  *n++; /* does not work, but trick above does */
}
示例#5
0
	void _gts_face_to_stl(GtsTriangle* t,_gts_face_to_stl_data* data){
		GtsVertex* v[3];
		Vector3r n;
		gts_triangle_vertices(t,&v[0],&v[1],&v[2]);
		if(data->clipCell && data->scene->isPeriodic){
			for(short ax:{0,1,2}){
				Vector3r p(GTS_POINT(v[ax])->x,GTS_POINT(v[ax])->y,GTS_POINT(v[ax])->z);
				if(!data->scene->cell->isCanonical(p)) return;
			}
		}
		gts_triangle_normal(t,&n[0],&n[1],&n[2]);
		n.normalize();
		std::ofstream& stl(data->stl);
		stl<<"  facet normal "<<n[0]<<" "<<n[1]<<" "<<n[2]<<"\n";
		stl<<"    outer loop\n";
		for(GtsVertex* _v: v){
			stl<<"      vertex "<<GTS_POINT(_v)->x<<" "<<GTS_POINT(_v)->y<<" "<<GTS_POINT(_v)->z<<"\n";
		}
		stl<<"    endloop\n";
		stl<<"  endfacet\n";
		data->numTri+=3;
	}
示例#6
0
文件: triangle.c 项目: finetjul/gts
/**
 * gts_triangle_circumcircle_center:
 * @t: a #GtsTriangle.
 * @point_class: a #GtsPointClass.
 *
 * Returns: a new #GtsPoint, center of the circumscribing circle of @t or
 * %NULL if the circumscribing circle is not defined.
 */
GtsPoint * gts_triangle_circumcircle_center (GtsTriangle * t,
        GtsPointClass * point_class)
{
    GtsVertex * v1, * v2, * v3;
    gdouble xa, ya, xb, yb, xc, yc;
    gdouble xd, yd, xe, ye;
    gdouble xad, yad, xae, yae;
    gdouble det;

    g_return_val_if_fail (t != NULL, NULL);
    g_return_val_if_fail (point_class != NULL, NULL);

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

    xa = GTS_POINT (v1)->x;
    ya = GTS_POINT (v1)->y;
    xb = GTS_POINT (v2)->x;
    yb = GTS_POINT (v2)->y;
    xc = GTS_POINT (v3)->x;
    yc = GTS_POINT (v3)->y;
    xd = (xa + xb)/2.;
    yd = (ya + yb)/2.;
    xe = (xa + xc)/2.;
    ye = (ya + yc)/2.;
    xad = xd - xa;
    yad = yd - ya;
    xae = xe - xa;
    yae = ye - ya;
    det = xad*yae - xae*yad;
    if (det == 0.)
        return NULL;
    return gts_point_new (point_class,
                          (yae*yad*(yd - ye) + xad*yae*xd - xae*yad*xe)/det,
                          -(xae*xad*(xd - xe) + yad*xae*yd - yae*xad*ye)/det,
                          0.);
}
示例#7
0
文件: happrox.c 项目: ClavinSBU/gts
static GtsSurface * happrox (gray ** g, gint width, gint height,
			     CostFunc cost_func,
			     gpointer cost_data,
			     GtsStopFunc stop_func,
			     gpointer stop_data)
{
  GtsSurface * s = gts_surface_new (gts_surface_class (),
				    GTS_FACE_CLASS (list_face_class ()),
				    gts_edge_class (),
				    gts_vertex_class ());
  GtsVertex * v1 = gts_vertex_new (s->vertex_class, 0., 0., g[0][0]);
  GtsVertex * v2 = gts_vertex_new (s->vertex_class, 
				   0., height - 1, g[height - 1][0]);
  GtsVertex * v3 = gts_vertex_new (s->vertex_class,
				   width - 1, 0., g[0][width - 1]);
  GtsVertex * v4 = gts_vertex_new (s->vertex_class,
				   width - 1, height - 1, 
				   g[height - 1][width - 1]);
  guint i, j;
  GSList * corners = NULL;
  GtsTriangle * t;
  GtsVertex * w1, * w2, * w3;
  GtsListFace * f;

  /* creates enclosing triangle */
  corners = g_slist_prepend (corners, v1);
  corners = g_slist_prepend (corners, v2);
  corners = g_slist_prepend (corners, v3);
  corners = g_slist_prepend (corners, v4);
  t = gts_triangle_enclosing (gts_triangle_class (), corners, 100.);
  g_slist_free (corners);
  gts_triangle_vertices (t, &w1, &w2, &w3);

  f = GTS_LIST_FACE (gts_face_new (s->face_class, t->e1, t->e2, t->e3));
  gts_surface_add_face (s, GTS_FACE (f));

  /* add PGM vertices (corners excepted) to point list of f */
  for (i = 1; i < width - 1; i++) {
    for (j = 1; j < height - 1; j++)
      prepend (f, g, i, j);
    prepend (f, g, i, 0);
    prepend (f, g, i, height - 1);
  }
  for (j = 1; j < height - 1; j++) {
    prepend (f, g, 0, j);
    prepend (f, g, width - 1, j);
  }
  pgm_freearray (g, height);

  /* add four corners to initial triangulation */
  g_assert (gts_delaunay_add_vertex_to_face (s, v1, GTS_FACE (f)) == NULL);
  f = GTS_LIST_FACE (gts_point_locate (GTS_POINT (v2), s, NULL));
  g_assert (gts_delaunay_add_vertex_to_face (s, v2, GTS_FACE (f)) == NULL);
  f = GTS_LIST_FACE (gts_point_locate (GTS_POINT (v3), s, NULL));
  g_assert (gts_delaunay_add_vertex_to_face (s, v3, GTS_FACE (f)) == NULL);
  f = GTS_LIST_FACE (gts_point_locate (GTS_POINT (v4), s, NULL));
  g_assert (gts_delaunay_add_vertex_to_face (s, v4, GTS_FACE (f)) == NULL);

  /* refine surface */
  surface_hf_refine (s, cost_func, cost_data, stop_func, stop_data);

  /* destroy unused vertices */
  gts_surface_foreach_face (s, (GtsFunc) destroy_unused, NULL);
  
  /* destroy enclosing triangle */
  gts_allow_floating_vertices = TRUE;
  gts_object_destroy (GTS_OBJECT (w1));
  gts_object_destroy (GTS_OBJECT (w2));
  gts_object_destroy (GTS_OBJECT (w3));
  gts_allow_floating_vertices = FALSE;

  return s;
}
示例#8
0
文件: cartesian.c 项目: ClavinSBU/gts
int main (int argc, char * argv[])
{
  guint i, j, nx, ny;
  gdouble cosa, sina;
  GtsSurface * surface;
  GSList * l, * vertices = NULL;
  GtsTriangle * t;
  GtsVertex * v1, * v2, * v3;
  GTimer * timer;

  if (argc != 4) {
    fprintf (stderr, "usage: cartesian nx ny angle\n");
    return 0;
  }

  nx = strtol (argv[1], NULL, 0);
  ny = strtol (argv[2], NULL, 0);
  cosa = cos (strtod (argv[3], NULL));
  sina = sin (strtod (argv[3], NULL));

  timer = g_timer_new ();
  g_timer_start (timer);
  for (i = 0; i < nx; i++) {
    gdouble x = (gdouble) i/(gdouble) (nx - 1); 
    for (j = 0; j < ny; j++) {
      gdouble y = (gdouble) j/(gdouble) (nx - 1); 
      vertices = g_slist_prepend (vertices, 
		     gts_vertex_new (gts_vertex_class (),
				     cosa*x - sina*y, sina*x + cosa*y, 0.));
    }
  }

  t = gts_triangle_enclosing (gts_triangle_class (), vertices, 100.);
  gts_triangle_vertices (t, &v1, &v2, &v3);
  surface = gts_surface_new (gts_surface_class (),
			     gts_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));
  g_timer_stop (timer);
  fprintf (stderr, "Input: %g s\n", g_timer_elapsed (timer, NULL));
  g_timer_reset (timer);

  g_timer_start (timer);
  l = vertices;
  while (l) {
    g_assert (gts_delaunay_add_vertex (surface, l->data, NULL) == NULL);
    l = l->next;
  }

  gts_allow_floating_vertices = TRUE;
  gts_object_destroy (GTS_OBJECT (v1));
  gts_object_destroy (GTS_OBJECT (v2));
  gts_object_destroy (GTS_OBJECT (v3));
  gts_allow_floating_vertices = FALSE;
  g_timer_stop (timer);

  fprintf (stderr, "Triangulation: %g s speed: %.0f vertex/s\n", 
	   g_timer_elapsed (timer, NULL),
	   g_slist_length (vertices)/g_timer_elapsed (timer, NULL));
  g_timer_reset (timer);

  g_timer_start (timer);
  gts_surface_write (surface, stdout);
  g_timer_stop (timer);

  fprintf (stderr, "Output: %g s\n", g_timer_elapsed (timer, NULL));

  if (gts_delaunay_check (surface)) {
    fprintf (stderr, "WARNING: surface is not Delaunay\n");
    return 0;
  }

  return 1;
}
示例#9
0
文件: delaunay.c 项目: Gilles86/afni
int main (int argc, char * argv[])
{
  GPtrArray * vertices;
  GtsFifo * edges;
  guint i, line;
  GtsTriangle * t;
  GtsVertex * v1, * v2, * v3;
  GtsSurface * surface;
  gboolean keep_hull = TRUE;
  gboolean verbose = FALSE;
  gboolean add_constraints = TRUE;
  gboolean remove_holes = FALSE;
  gboolean check_delaunay = FALSE;
  gboolean conform = FALSE;
  gboolean refine = FALSE;
  gboolean split_constraints = FALSE;
  gboolean randomize = FALSE;
  gboolean remove_duplicates = FALSE;
  gint steiner_max = -1;
  gdouble quality = 0., area = G_MAXDOUBLE;
  int c = 0, status = 0;
  const char * fname = NULL;
  GTimer * timer;

  /* parse options using getopt */
  while (c != EOF) {
#ifdef HAVE_GETOPT_LONG
    static struct option long_options[] = {
      {"duplicates", no_argument, NULL, 'd'},
      {"help", no_argument, NULL, 'h'},
      {"verbose", no_argument, NULL, 'v'},
      {"randomize", no_argument, NULL, 'r'},
      {"hull", no_argument, NULL, 'b'},
      {"noconst", no_argument, NULL, 'e'},
      {"holes", no_argument, NULL, 'H'},
      {"split", no_argument, NULL, 'S'},
      {"check", no_argument, NULL, 'c'},
      {"files", required_argument, NULL, 'f'},
      {"conform", no_argument, NULL, 'o'},
      {"steiner", required_argument, NULL, 's'},
      {"quality", required_argument, NULL, 'q'},
      {"area", required_argument, NULL, 'a'}
    };
    int option_index = 0;
    switch ((c = getopt_long (argc, argv, "hvbecf:os:q:a:HSrd",
			      long_options, &option_index))) {
#else /* not HAVE_GETOPT_LONG */
    switch ((c = getopt (argc, argv, "hvbecf:os:q:a:HSrd"))) {
#endif /* not HAVE_GETOPT_LONG */
    case 'd': /* duplicates */
      remove_duplicates = TRUE;
      break;
    case 'b': /* do not keep convex hull */
      keep_hull = FALSE;
      break;
    case 'e': /* do not add constrained edges */
      add_constraints = FALSE;
      break;
    case 'H': /* remove holes */
      remove_holes = TRUE;
      break;
    case 'S': /* split constraints */
      split_constraints = TRUE;
      break;
    case 'r': /* randomize */
      randomize = TRUE;
      break;
    case 'c': /* check Delaunay property */
      check_delaunay = TRUE;
      break;
    case 'f': /* generates files */
      fname = optarg;
      break;      
    case 'v': /* verbose */
      verbose = TRUE;
      break;
    case 'o': /* conform */
      conform = TRUE;
      break;
    case 's': /* steiner */
      steiner_max = atoi (optarg);
      break;
    case 'q': /* quality */
      conform = TRUE;
      refine = TRUE;
      quality = atof (optarg);
      break;
    case 'a': /* area */
      conform = TRUE;
      refine = TRUE;
      area = atof (optarg);
      break;
    case 'h': /* help */
      fprintf (stderr,
             "Usage: delaunay [OPTION] < file.gts\n"
	     "Construct the constrained Delaunay triangulation of the input\n"
	     "\n"
	     "  -b       --hull         do not keep convex hull\n"
	     "  -e       --noconst      do not add constrained edges\n"
	     "  -S       --split        split constraints (experimental)\n"
	     "  -H       --holes        remove holes from the triangulation\n"
	     "  -d       --duplicates   remove duplicate vertices\n"
	     "  -r       --randomize    shuffle input vertex list\n"
	     "  -c       --check        check Delaunay property\n"
	     "  -f FNAME --files=FNAME  generate evolution files\n"
	     "  -o       --conform      generate conforming triangulation\n"
	     "  -s N     --steiner=N    maximum number of Steiner points for\n"
	     "                          conforming triangulation (default is no limit)\n"
	     "  -q Q     --quality=Q    Set the minimum acceptable face quality\n"
	     "  -a A     --area=A       Set the maximum acceptable face area\n"
	     "  -v       --verbose      print statistics about the triangulation\n"
	     "  -h       --help         display this help and exit\n"
	     "\n"
	     "Reports bugs to %s\n",
	     GTS_MAINTAINER);
      return 0; /* success */
      break;
    case '?': /* wrong options */
      fprintf (stderr, "Try `delaunay --help' for more information.\n");
      return 1; /* failure */
    }
  }

  /* read file => two lists: vertices and constraints */

  edges = gts_fifo_new ();
  vertices = g_ptr_array_new ();
  if (add_constraints) /* the edge class is a GtsConstraintClass */
    line = read_list (vertices, edges, 
		      GTS_EDGE_CLASS (gts_constraint_class ()),
		      stdin);
  else /* the edge class is a "normal" edge: GtsEdgeClass */
    line = read_list (vertices, edges, 
		      gts_edge_class (), 
		      stdin);

  if (line > 0) {
    fprintf (stderr, "delaunay: error in input file at line %u\n", line);
    return 1;
  }

  timer = g_timer_new ();
  g_timer_start (timer);

  if (randomize)
    shuffle_array (vertices);

  /* create triangle enclosing all the vertices */
  {
    GSList * list = NULL;
    for (i = 0; i < vertices->len; i++)
      list = g_slist_prepend (list, g_ptr_array_index (vertices, i));
    t = gts_triangle_enclosing (gts_triangle_class (), list, 100.);
    g_slist_free (list);
  }
  gts_triangle_vertices (t, &v1, &v2, &v3);

  /* create surface with one face: the enclosing triangle */
  surface = gts_surface_new (gts_surface_class (),
			     gts_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));

  /* add vertices */
  for (i = 0; i < vertices->len; i++) {
    GtsVertex * v1 = g_ptr_array_index (vertices, i);
    GtsVertex * v = gts_delaunay_add_vertex (surface, v1, NULL);

    g_assert (v != v1);
    if (v != NULL) {
      if (!remove_duplicates) {
	fprintf (stderr, "delaunay: duplicate vertex (%g,%g) in input file\n",
		 GTS_POINT (v)->x, GTS_POINT (v)->y);
	return 1; /* Failure */
      }
      else
	gts_vertex_replace (v1, v);
    }
    if (fname) {
      static guint nf = 1;
      char s[80];
      FILE * fp;

      g_snprintf (s, 80, "%s.%u", fname, nf++);
      fp = fopen (s, "wt");
      gts_surface_write_oogl (surface, fp);
      fclose (fp);

      if (check_delaunay && gts_delaunay_check (surface)) {
	fprintf (stderr, "delaunay: triangulation is not Delaunay\n");
	return 1;
      }
    }
  }
  g_ptr_array_free (vertices, TRUE);

  /* add remaining constraints */
  if (add_constraints)
    gts_fifo_foreach (edges, (GtsFunc) add_constraint, surface);

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

  if (!keep_hull)
    gts_delaunay_remove_hull (surface);

  if (remove_holes)
    delaunay_remove_holes (surface);

  if (split_constraints) {
    gpointer data[2];

    data[0] = surface;
    data[1] = edges;
    gts_fifo_foreach (edges, (GtsFunc) split_constraint, data);
  }

  if (conform) {
    guint encroached_number = 
      gts_delaunay_conform (surface, 
			    steiner_max,
			    (GtsEncroachFunc) gts_vertex_encroaches_edge,
			    NULL);
    if (encroached_number == 0 && refine) {
      guint unrefined_number;
      gpointer data[2];
      
      data[0] = &quality;
      data[1] = &area;
      unrefined_number = 
	gts_delaunay_refine (surface, 
			     steiner_max,
			     (GtsEncroachFunc) gts_vertex_encroaches_edge,
			     NULL,
			     (GtsKeyFunc) triangle_cost,
			     data);
      if (verbose && unrefined_number > 0)
	fprintf (stderr, 
		 "delaunay: ran out of Steiner points (max: %d) during refinement\n"
		 "%d unrefined faces left\n",
		 steiner_max, unrefined_number);
    }
    else if (verbose && encroached_number > 0)
      fprintf (stderr, 
	       "delaunay: ran out of Steiner points (max: %d) during conforming\n"
	       "Delaunay triangulation: %d encroached constraints left\n",
	       steiner_max, encroached_number);
  }
  g_timer_stop (timer);

  if (verbose) {
    gts_surface_print_stats (surface, stderr);
    fprintf (stderr, "# Triangulation time: %g s speed: %.0f vertex/s\n", 
	  g_timer_elapsed (timer, NULL),
	  gts_surface_vertex_number (surface)/g_timer_elapsed (timer, NULL));
  }

  if (check_delaunay && gts_delaunay_check (surface)) {
    fprintf (stderr, "delaunay: triangulation is not Delaunay\n");
    status = 1; /* failure */
  }

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

  return status;
}
示例#10
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;
}