int main (int argc, char * argv[]) { GtsSurface * s; GtsBBox * bbox; gdouble delta; GtsPoint * p1, * p2, * p3; guint nt; GtsRange cluster_stats; GtsClusterGrid * cluster_grid; if (argc != 2) { fprintf (stderr, "usage: oocs DELTA < infile > outfile\n"); return 1; } s = gts_surface_new (gts_surface_class (), gts_face_class (), gts_edge_class (), gts_vertex_class ()); bbox = gts_bbox_new (gts_bbox_class (), s, 0., 0., 0., 0., 0., 0.); scanf ("%u", &nt); scanf ("%lf %lf %lf", &bbox->x1, &bbox->y1, &bbox->z1); scanf ("%lf %lf %lf", &bbox->x2, &bbox->y2, &bbox->z2); delta = atof (argv[1])*sqrt (gts_bbox_diagonal2 (bbox)); cluster_grid = gts_cluster_grid_new (gts_cluster_grid_class (), gts_cluster_class (), s, bbox, delta); p1 = gts_point_new (gts_point_class (), 0., 0., 0.); p2 = gts_point_new (gts_point_class (), 0., 0., 0.); p3 = gts_point_new (gts_point_class (), 0., 0., 0.); while (scanf ("%lf %lf %lf", &p1->x, &p1->y, &p1->z) == 3 && scanf ("%lf %lf %lf", &p2->x, &p2->y, &p2->z) == 3 && scanf ("%lf %lf %lf", &p3->x, &p3->y, &p3->z) == 3) gts_cluster_grid_add_triangle (cluster_grid, p1, p2, p3, NULL); cluster_stats = gts_cluster_grid_update (cluster_grid); gts_object_destroy (GTS_OBJECT (p1)); gts_object_destroy (GTS_OBJECT (p2)); gts_object_destroy (GTS_OBJECT (p3)); gts_object_destroy (GTS_OBJECT (cluster_grid)); fprintf (stderr, "Initial number of triangles: %u\n", nt); fprintf (stderr, "%d clusters of size: min: %g avg: %.1f|%.1f max: %g\n", cluster_stats.n, cluster_stats.min, cluster_stats.mean, cluster_stats.stddev, cluster_stats.max); gts_surface_print_stats (s, stderr); gts_surface_write (s, stdout); return 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] = δ 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.; }
/** * gts_bb_tree_surface_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_triangle_distance() for each face 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 triangle weighthed by their area and divided by * the total area of the surface. 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_distance (GNode * tree, GtsSurface * s, GtsBBoxDistFunc distance, gdouble delta, GtsRange * range) { gpointer data[5]; gdouble total_area = 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] = δ data[2] = range; data[3] = &total_area; data[4] = distance; gts_surface_foreach_face (s, (GtsFunc) surface_distance_foreach_triangle, data); if (total_area > 0.) { if (range->sum2 - range->sum*range->sum/total_area >= 0.) range->stddev = sqrt ((range->sum2 - range->sum*range->sum/total_area) /total_area); else range->stddev = 0.; range->mean = range->sum/total_area; } else range->min = range->max = range->mean = range->stddev = 0.; }