Advertisement
Guest User

grid.c

a guest
Dec 18th, 2014
289
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.04 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <errno.h>
  4. #include "grid.h"
  5.  
  6. /*
  7.  * This file is in public domain.
  8. */
  9.  
  10. static unsigned long  field_evaluations = 0UL;
  11.  
  12. static double field(void *unused, double x, double y, double z)
  13. {
  14.     field_evaluations++;
  15.     return x*x*x + y*y*y + z*z*z + x + y - 0.125 * (x*y + x*z + y*z + x*y*z);
  16. }
  17.  
  18. static void check_edge(FILE *out, const double s,
  19.                        const double x0, const double y0, const double z0, const double s0,
  20.                        const double x1, const double y1, const double z1, const double s1)
  21. {
  22.     if (s0 < s && s < s1) {
  23.         const double p = (s - s0) / (s1 - s0);
  24.         fprintf(out, "%.5f %.5f %.5f\n", x0 + p*(x1-x0), y0 + p*(y1-y0), z0 + p*(z1-z0));
  25.     } else
  26.     if (s0 > s && s > s1) {
  27.         const double p = (s - s1) / (s0 - s1);
  28.         fprintf(out, "%.5f %.5f %.5f\n", x1 + p*(x0-x1), y1 + p*(y0-y1), z1 + p*(z0-z1));
  29.     } else
  30.     if (s0 == s && s1 != s) {
  31.         fprintf(out, "%.5f %.5f %.5f\n", x0, y0, z0);
  32.     } else
  33.     if (s0 != s && s1 == s) {
  34.         fprintf(out, "%.5f %.5f %.5f\n", x1, y1, z1);
  35.     }
  36. }
  37.  
  38. static unsigned long  cells_checked = 0UL;
  39.  
  40. static int check_cell(void *out, struct grid *g, int x, int y, int z, double c, double sample[2][2][2])
  41. {
  42.     const double x0 = g->xorigin + (double)x * g->xunit,
  43.                  y0 = g->yorigin + (double)y * g->yunit,
  44.                  z0 = g->zorigin + (double)z * g->zunit;
  45.     const double x1 = x0 + g->xunit,
  46.                  y1 = y0 + g->yunit,
  47.                  z1 = z0 + g->zunit;
  48.  
  49.     cells_checked++;
  50.  
  51. #ifdef CELL_EDGE_INTERSECTIONS
  52.  
  53.     /* These are the 12 possible intersections at the cell edges,
  54.      * in case you intend to use them for e.g. polygons.
  55.     */
  56.  
  57.     check_edge(out, c, x0, y0, z0, sample[0][0][0], x1, y0, z0, sample[1][0][0]);
  58.     check_edge(out, c, x0, y0, z0, sample[0][0][0], x0, y1, z0, sample[0][1][0]);
  59.     check_edge(out, c, x0, y0, z0, sample[0][0][0], x0, y0, z1, sample[0][0][1]);
  60.  
  61.     check_edge(out, c, x1, y0, z0, sample[1][0][0], x1, y1, z0, sample[1][1][0]);
  62.     check_edge(out, c, x1, y0, z0, sample[1][0][0], x1, y0, z1, sample[1][0][1]);
  63.  
  64.     check_edge(out, c, x0, y1, z0, sample[0][1][0], x1, y1, z0, sample[1][1][0]);
  65.     check_edge(out, c, x0, y1, z0, sample[0][1][0], x0, y1, z1, sample[0][1][1]);
  66.  
  67.     check_edge(out, c, x0, y0, z1, sample[0][0][1], x1, y0, z1, sample[1][0][1]);
  68.     check_edge(out, c, x0, y0, z1, sample[0][0][1], x0, y1, z1, sample[0][1][1]);
  69.  
  70.     check_edge(out, c, x1, y1, z0, sample[1][1][0], x1, y1, z1, sample[1][1][1]);
  71.     check_edge(out, c, x1, y0, z1, sample[1][0][1], x1, y1, z1, sample[1][1][1]);
  72.     check_edge(out, c, x0, y1, z1, sample[0][1][1], x1, y1, z1, sample[1][1][1]);
  73.  
  74. #else
  75.  
  76.     /* These are not (all) valid edges, but if you are just visualizing the
  77.      * approximate isosurface as a point cloud, these give a slightly better
  78.      * distributed point set. */
  79.  
  80.     check_edge(out, c, x0, y0, z0, sample[0][0][0], x1, y0, z0, sample[1][0][0]);
  81.     check_edge(out, c, x0, y0, z0, sample[0][0][0], x0, y1, z0, sample[0][1][0]);
  82.     check_edge(out, c, x0, y0, z0, sample[0][0][0], x0, y0, z1, sample[0][0][1]);
  83.     check_edge(out, c, x0, y0, z0, sample[0][0][0], x0, y1, z1, sample[0][1][1]);
  84.     check_edge(out, c, x0, y0, z0, sample[0][0][0], x1, y0, z1, sample[1][0][1]);
  85.     check_edge(out, c, x0, y0, z0, sample[0][0][0], x1, y1, z0, sample[1][1][0]);
  86.     check_edge(out, c, x0, y0, z0, sample[0][0][0], x1, y1, z1, sample[1][1][1]);
  87.  
  88. #endif
  89.  
  90.     return 0;
  91. }
  92.  
  93.  
  94.  
  95. int main(int argc, char *argv[])
  96. {
  97.     struct grid *g;
  98.     double min, max, level;
  99.     int n, result;
  100.     char dummy;
  101.  
  102.     if (argc != 5 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
  103.         fprintf(stderr, "\n");
  104.         fprintf(stderr, "Usage: %s [ -h | --help ]\n", argv[0]);
  105.         fprintf(stderr, "       %s N MIN MAX LEVEL\n", argv[0]);
  106.         fprintf(stderr, "\n");
  107.         return EXIT_FAILURE;
  108.     }
  109.  
  110.     if (sscanf(argv[1], " %d %c", &n, &dummy) != 1 || n < 1) {
  111.         fprintf(stderr, "%s: Invalid N.\n", argv[1]);
  112.         return EXIT_FAILURE;
  113.     }
  114.     if (sscanf(argv[2], " %lf %c", &min, &dummy) != 1) {
  115.         fprintf(stderr, "%s: Invalid minimum.\n", argv[2]);
  116.         return EXIT_FAILURE;
  117.     }
  118.     if (sscanf(argv[3], " %lf %c", &max, &dummy) != 1 || max <= min) {
  119.         fprintf(stderr, "%s: Invalid maximum.\n", argv[3]);
  120.         return EXIT_FAILURE;
  121.     }
  122.     if (sscanf(argv[4], " %lf %c", &level, &dummy) != 1) {
  123.         fprintf(stderr, "%s: Invalid level.\n", argv[4]);
  124.         return EXIT_FAILURE;
  125.     }
  126.  
  127.     g = grid_new(n+1, n+1, n+1, min, min, min, max, max, max, NULL, field);
  128.     if (g == NULL) {
  129.         fprintf(stderr, "Cannot construct grid: %s.\n", strerror(errno));
  130.         return EXIT_FAILURE;
  131.     }
  132.     if (level < g->minimum_sample || level > g->maximum_sample) {
  133.         fprintf(stderr, "%s: Level is outside the field (%g to %g).\n", argv[4], g->minimum_sample, g->maximum_sample);
  134.         return EXIT_FAILURE;
  135.     }
  136.  
  137.     fprintf(stderr, "Grid initialized using %lu samples,\n", field_evaluations);
  138.     fprintf(stderr, "field (%.3f, %.3f, %.3f) - (%.3f, %.3f, %.3f).\n",
  139.                     g->xorigin, g->yorigin, g->zorigin,
  140.                     g->xorigin + (double)(g->xsize - 1) * g->xunit,
  141.                     g->yorigin + (double)(g->ysize - 1) * g->yunit,
  142.                     g->zorigin + (double)(g->zsize - 1) * g->zunit);
  143.  
  144.     result = grid_isosurface(g, level, stdout, check_cell);
  145.     if (result != 0) {
  146.         fprintf(stderr, "Failed to locate isosurface [%d]: %s.\n", result, strerror(errno));
  147.         return EXIT_FAILURE;
  148.     }
  149.  
  150.     fprintf(stderr, "Isosurface passed through %lu cells (%.5f%%).\n", cells_checked, 100.0 * (double)cells_checked / (double)(g->xsize - 1) / (double)(g->ysize - 1) / (double)(g->zsize - 1));
  151.     fprintf(stderr, "Initialization and isosurface required %lu samples (%.5f%%) total.\n", field_evaluations, 100.0 * (double)field_evaluations / (double)g->size);
  152.  
  153.     g = grid_free(g);
  154.  
  155.     return EXIT_SUCCESS;
  156. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement