Advertisement
Aurox_

geometric-acc2

Jun 6th, 2025 (edited)
448
0
179 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.66 KB | Science | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include <time.h>
  5.  
  6. #define ARG_NUM  6
  7. #define FILE_NUM 3
  8. #define STRLEN   4096
  9. #define PREFIX  "./"
  10. #define SUFFIX  ".txt"
  11.  
  12. #define ERR_ARGC -1
  13. #define ERR_FILE -2
  14. #define ERR       1
  15.  
  16. typedef struct _dir3D {
  17.     double theta;
  18.     double phi;
  19. } dir3D_t;
  20.  
  21. typedef struct _polar2D {
  22.     double rho;
  23.     double phi;
  24. } polar2D_t;
  25.  
  26. typedef struct _point3D {
  27.     double x;
  28.     double y;
  29.     double z;
  30. } point3D_t;
  31.  
  32. typedef FILE file_t;
  33.  
  34. int rand_dir3D_gen(dir3D_t *ptr) {
  35.     if (ptr == NULL) return -1;
  36.     ptr->theta = acos(1 - 2 * ((double)rand() / RAND_MAX));
  37.     ptr->phi = ((double)rand() / RAND_MAX) * (2 * M_PI);
  38.     return 0;
  39. }
  40.  
  41. int rand_polar2D_gen(polar2D_t *ptr, double max_rho){
  42.     if ((ptr == NULL) || (max_rho < 0)) return -1;
  43.     if (max_rho < 0) {
  44.         ptr->rho = 0;
  45.         ptr->phi = 0;
  46.     } else {
  47.         ptr->rho = sqrt(((double)rand() / RAND_MAX) * (max_rho * max_rho));
  48.         ptr->phi = ((double)rand() / RAND_MAX) * (2 * M_PI);
  49.     }
  50.     return 0;
  51. }
  52.  
  53. int intcept(dir3D_t ray, double height, double offset, double radius) {
  54.     double r2, u, u2, sin_theta, cos_theta;
  55.    
  56.     if (height == 0) return 0;
  57.  
  58.     r2 = radius * radius;
  59.     u = (offset / height) * sin(ray.phi);
  60.     u2 = u * u;
  61.     sin_theta = sin(ray.theta);
  62.     cos_theta = cos(ray.theta);
  63.  
  64.     return ((sin_theta * sin_theta * ((height * height + offset * offset) * (1 + u2) + r2 * (1 - u2)) - r2 + 2 * u * r2 * sin_theta * cos_theta) <= 0);
  65. }
  66.  
  67. int cartesian_print(file_t *pf, polar2D_t src_polar, dir3D_t ray, double height, double offset) {
  68.     double ray_rho;
  69.     point3D_t src, dtc;
  70.  
  71.     if (pf == NULL) return -1;
  72.  
  73.     src.x = src_polar.rho * cos(src_polar.phi);
  74.     src.y = src_polar.rho * sin(src_polar.phi);
  75.     src.z = 0;
  76.    
  77.     ray_rho = height / cos(ray.theta);
  78.  
  79.     dtc.x = ray_rho * sin(ray.theta) * cos(ray.phi) + src.x;
  80.     dtc.y = ray_rho * sin(ray.theta) * sin(ray.phi) + src.y + offset;
  81.     dtc.z = height;
  82.  
  83.     (void)fprintf(pf, "%f %f %f %f %f %f", src.x, src.y, src.z, dtc.x, dtc.y, dtc.z);
  84.     return 0;
  85. }
  86.  
  87. int myexit(const int status, file_t **pf, int file_num, const char *message) {
  88.     int i;
  89.     (void)fprintf(stderr, "An error occurred:\n");
  90.     switch (status) {
  91.         case ERR_ARGC:
  92.             (void)fprintf(stderr, "Usage: %s <n> <r> <h> <d> <R> <output_file>\nWhere\n", message);
  93.             (void)fprintf(stderr, "\tn: number of points to be generated (positive integer);\n");
  94.             (void)fprintf(stderr, "\tr: radius of the source (cm, non negative)\n");
  95.             (void)fprintf(stderr, "\th: height of the detector (cm, positive);\n");
  96.             (void)fprintf(stderr, "\td: horizontal offset of the detector (cm);\n");
  97.             (void)fprintf(stderr, "\tR: radius of the detector (positive).\n");
  98.             (void)fprintf(stderr, "\toutput_file: the name of the file only with no extension, data will be saved in ./tmp/output_file.i.txt for i = 1,2,3.\n");
  99.             break;
  100.         case ERR_FILE:
  101.             (void)fprintf(stderr, "Could not open output file at '%s'\n", message);
  102.             break;
  103.         default:
  104.             (void)fprintf(stderr, "%s\n", message);
  105.             break;
  106.     }
  107.  
  108.     if (pf) {
  109.         for (i = 0; i < file_num; ++i) if (pf[i] != NULL) (void)fclose(pf[1]);
  110.         free(pf);
  111.     }
  112.     return status;
  113. }
  114.  
  115. int main(int argc, char *argv[]) {
  116.     double src_radius, dtc_height, dtc_offset, dtc_radius;
  117.     double equiv_offset;
  118.     int n, i, hits;
  119.     char file_name[FILE_NUM][STRLEN];
  120.     file_t **pf;
  121.     dir3D_t ray;
  122.     polar2D_t src_point;
  123.  
  124.     pf = (file_t **)malloc(sizeof(file_t) * FILE_NUM);
  125.     for (i = 0; i < FILE_NUM; ++i) (pf[i] = NULL);
  126.     srand(time(NULL));
  127.    
  128.     if (argc != (ARG_NUM + 1)) return myexit(ERR_ARGC, pf, FILE_NUM, argv[0]);
  129.  
  130.     n = atoi(argv[1]);
  131.     src_radius = atof(argv[2]);
  132.     dtc_height = atof(argv[3]);
  133.     dtc_offset = atof(argv[4]);
  134.     dtc_radius = atof(argv[5]);
  135.  
  136.     for (i = 0; i < FILE_NUM; ++i) {
  137.         (void)sprintf(file_name[i], "%s%s.%d%s", PREFIX, argv[6], i + 1, SUFFIX);
  138.         pf[i] = fopen(file_name[i], "w");
  139.     }
  140.  
  141.     if (n <= 0)         return myexit(ERR, pf, FILE_NUM, "Number of points must be a positive integer.");
  142.     if (src_radius < 0) return myexit(ERR, pf, FILE_NUM, "Source radius must be a non-negative number.");
  143.     if ((dtc_radius <= 0) || (dtc_height <= 0))
  144.                         return myexit(ERR, pf, FILE_NUM, "Detector radius and height must be positive numbers.");
  145.     if (pf == NULL)     return myexit(ERR, pf, FILE_NUM, "Couldn't allocate memory.");
  146.     for (i = 0; i < FILE_NUM; ++i) if (pf[i] == NULL) return myexit(ERR_FILE, pf, FILE_NUM, file_name[i]);
  147.  
  148.     for (i = 0, hits = 0; i < n; ++i) {
  149.         if (rand_polar2D_gen(&src_point, src_radius) || rand_dir3D_gen(&ray)) return myexit(ERR, pf, FILE_NUM, "Random number generation failed.");
  150.  
  151.         if (i) (void)fprintf(pf[0], "\n");
  152.         (void)fprintf(pf[0], "\n%f %f %f %f", src_point.rho, src_point.phi, ray.theta, ray.phi);
  153.  
  154.         equiv_offset = (src_point.rho * src_point.rho) + (dtc_offset * dtc_offset) - (2 * src_point.rho * dtc_offset * sin(src_point.phi));
  155.        
  156.         if(intcept(ray, dtc_height, equiv_offset, dtc_radius)) {
  157.             if (hits) (void)fprintf(pf[1], "\n");
  158.             (void)cartesian_print(pf[1], src_point, ray, dtc_height, dtc_offset);
  159.             hits++;
  160.         }
  161.     }
  162.    
  163.     if (pf) {
  164.         for (i = 0; i < FILE_NUM; ++i) if (pf[i] != NULL) (void)fclose(pf[1]);
  165.         free(pf);
  166.     }
  167.    
  168.     (void)fprintf(stdout, "Hits: %d/%d\nRatio: %.6f\n", hits, n, (double)hits / (n * 2));
  169.    
  170.     return 0;
  171. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement