gts: delaunay三角形網の作成

基本的なdelaunay三角形網の作成方法は、
サンプルコードのdelaunay.cを見るとわかります。
このサンプルファイルにはいろいろなオプションがあって、
それらの処理が混ざっているのでわかりにくいですが、
抜粋すると大体以下のようなコードでできます。

以下のコードは、delaunay.cを元に抜粋・一部書き換えを行ったものです。
各頂点がXYZの順に並んでいるCSV形式を読み込みます。

   1: 
   2: #include "gts.h"
   3: #include <stdlib.h>
   4: 
   5: int main( int argc, char *argv[] )
   6: {
   7: 	FILE *pfText;
   8: 	GPtrArray *vertices;
   9: 	double dX, dY, dZ;
  10: 	GSList *list = NULL;
  11: 	GtsTriangle *t;
  12: 	guint i;
  13: 	GtsSurface *surface;
  14: 	GtsVertex *v1, *v2, *v3;
  15: 
  16: 	if ( fopen_s( &pfText, argv[1], "rt" ) )
  17: 	{
  18: 	  exit( 1 );
  19: 	}
  20: 
  21: 	// 頂点配列の作成
  22: 	vertices = g_ptr_array_new();
  23: 
  24: 	// ファイルからデータを読み込んで頂点配列に追加
  25: 	while ( fscanf_s( pfText, "%lf,%lf,%lfn", &dX, &dY, &dZ ) == 3 )
  26: 	{
  27: 	  g_ptr_array_add( vertices,
  28: 	    gts_vertex_new( gts_vertex_class (), dX, dY, dZ ) );
  29: 	}
  30: 
  31: 	// 頂点配列をリストにコピー
  32: 	for ( i = 0; i < vertices->len; i++ )
  33: 	  list = g_slist_prepend( list, g_ptr_array_index( vertices, i ) );
  34: 
  35: 	// 全頂点を確実に包含する三角形を作成
  36: 	t = gts_triangle_enclosing( gts_triangle_class(), list, 100. );
  37: 	g_slist_free( list );
  38: 	gts_triangle_vertices( t, &v1, &v2, &v3 );
  39: 
  40: 	// 包含三角形からGtsSurfaceを作成
  41: 	surface = gts_surface_new( gts_surface_class(),
  42: 	  gts_face_class(),
  43: 	  gts_edge_class(),
  44: 	  gts_vertex_class() );
  45: 
  46: 	gts_surface_add_face( surface, gts_face_new( gts_face_class(),
  47: 					       t->e1, t->e2, t->e3) );
  48: 
  49: 	// 包含三角形にファイルの頂点を1つずつ追加
  50: 	// 追加された頂点と包含三角形は常にdelaunay分割になっている
  51: 	for ( i = 0; i < vertices->len; i++ )
  52: 	{
  53: 	  GtsVertex * vi = (GtsVertex *)g_ptr_array_index (vertices, i);
  54: 	  GtsVertex * v = gts_delaunay_add_vertex (surface, vi, NULL);
  55: 
  56: 	  g_assert (v != vi);
  57: 	  if (v != NULL)
  58: 	  {
  59: 	    gts_vertex_replace (vi, v);
  60: 	  }
  61: 	}
  62: 
  63: 	// 読み込んだ頂点配列を開放
  64: 	g_ptr_array_free( vertices, TRUE );
  65: 
  66: 	// 包含三角形の頂点だけを削除
  67: 	gts_allow_floating_vertices = TRUE;
  68: 	gts_object_destroy (GTS_OBJECT (v1));
  69: 	gts_object_destroy (GTS_OBJECT (v2));
  70: 	gts_object_destroy (GTS_OBJECT (v3));
  71: 	gts_allow_floating_vertices = FALSE;
  72: 
  73: 	// 三角形網を書き出し
  74: 	gts_surface_write (surface, "test.gts");
  75: 
  76: 	gts_object_destroy( GTS_OBJECT( surface ) );
  77: 
  78: 	fclose( pfText );
  79: 
  80: 	return 0;
  81: }

67行目のgts_allow_floating_verticesは、
デフォルトのFALSEでは、例えば線分を削除するときにその線分を構成する2つの頂点も
削除するという動作をします。これをTRUEにすると、線分オブジェクトのみを削除し、
頂点は削除しません。
この場合はどっちでも良いような気がしますが、、、。
実際処理結果は正しくできているように見えます。

74行目gts_surface_write()関数は、オリジナルはファイルポインタを受け取る形式なので、
DLLにすると使えません。
なので、ここではファイル名を受け取る形式に書き換えたものを使用しています。

実行結果

実行結果
アーカイブ