SaveText.Ru

Без имени
  1. /*
  2. -------------------------------------------------------------------------
  3. sphere.c
  4. -------------------------------------------------------------------------
  5. This program will generate a given number of points uniformly distributed
  6. on the surface of a sphere. The number of points is given on the command
  7. line as the first parameter.  Thus `sphere 100' will generate 100 points
  8. on the surface of a sphere, and output them to stdout.
  9.         A number of different command-line flags are provided to set the
  10. radius of the sphere, control the output format, or generate points on
  11. an ellipsoid.  The definition of the flags is printed if the program is
  12. run without arguments: `sphere'.
  13.         The idea behind the algorithm is that for a sphere of radius r, the
  14. area of a zone of width h is always 2*pi*r*h, regardless of where the sphere
  15. is sliced.  The implication is that the z-coordinates of random points on a
  16. sphere are uniformly distributed, so that x and y can always be generated by
  17. a given z and a given angle.
  18.         The default output is integers, rounded from the floating point
  19. computation.  The rounding implies that some points will fall outside
  20. the sphere, and some inside.  If all are required to be inside, then
  21. the calls to irint() should be removed.  
  22.         The flags -a, -b, -c are used to set ellipsoid axis lengths.  
  23. Note that the points are not uniformly distributed on the ellipsoid: they
  24. are uniformly distributed on the sphere and that is scaled to an ellipsoid.
  25.         random() is used to generate random numbers, seeded with time().
  26. How to compile:
  27.         gcc -o sphere sphere.c -lm
  28.  
  29. Reference: J. O'Rourke, Computational Geometry Column 31,
  30. Internat. J. Comput. Geom. Appl. 7(?) ?--? (1997);
  31. also in SIGACT News, 28(?):?--? (1997), Issue ?.
  32.  
  33. Written by Joseph O'Rourke and Min Xu, June 1997.
  34. Used in the textbook, "Computational Geometry in C."
  35. Questions to [email protected]
  36. --------------------------------------------------------------------
  37. This code is Copyright 1997 by Joseph O'Rourke.  It may be freely
  38. redistributed in its entirety provided that this copyright notice is
  39. not removed.
  40. --------------------------------------------------------------------
  41. */
  42. #include <stdio.h>
  43. #include <math.h>
  44. #include <string.h>
  45.  
  46. /* MAX_INT is the range of random(): 2^{31}-1 */
  47. #define MAX_INT   2147483647          
  48. #define TRUE      1
  49. #define FALSE     0
  50.  
  51. void print_instruct( void )
  52. {
  53.   printf ( "Please enter your input according to the following format:n" );
  54.   printf ( "tsphere [number of points] [-flag letter][parameter value]n" );
  55.   printf ( "tt (no space between flag letter and parameter value!)n" );
  56.   printf ( "Available flags are:n" );
  57.   printf ( "t-r[parameter] t set radius of the sphere (default: 100)n" );
  58.   printf ( "t-f            t set output to floating point format (default: integer)n");
  59.   printf ( "t-a[parameter] t ellipsoid x-axis length (default: sphere radius)n");
  60.   printf ( "t-b[parameter] t ellipsoid y-axis length (default: sphere radius)n");
  61.   printf ( "t-c[parameter] t ellipsoid z-axis length (default: sphere radius)n");
  62. }
  63.  
  64. void TestFlags (int argc, char *argv[],
  65.         int *r1, int *r2, int *r3, int *r, int *float_pt)
  66. {
  67.  
  68.   int i = 2;
  69.  
  70.   /* Test for flags */
  71.   while ( i < argc ) {
  72.  
  73.     /* Test for radius flag */
  74.     if ( strncmp ( argv[i], "-r", 2 ) == 0 ) {
  75.       if ( sscanf( &argv[i][2], "%d", r ) != 1 )
  76.         printf ( "No space between flag name and parameter, please!n" ),
  77.         exit (1);
  78.       else if (*r == 0 )
  79.         printf ( "Invalid radius flagn" ),
  80.         exit (1);
  81.       else
  82.         *r1 = *r2 = *r3 = *r;
  83.     }
  84.    
  85.     /* Test whether user wants floating point output */
  86.     if ( strncmp ( argv[i], "-f", 2 ) == 0 )
  87.       *float_pt = TRUE;
  88.  
  89.     /* Test for ellipsoid radius if any */
  90.     if ( strncmp ( argv[i], "-a", 2 ) == 0 )
  91.       if ( sscanf ( &argv[i][2], "%d", r1 ) != 1 )
  92.         printf ( "No space between flag name and parameter, please!n" ),
  93.         exit (1);
  94.     if ( strncmp ( argv[i], "-b", 2 ) == 0 )
  95.       if ( sscanf ( &argv[i][2], "%d", r2 ) != 1 )
  96.         printf ( "No space between flag name and parameter, please!n" ),
  97.         exit (1);
  98.     if ( strncmp ( argv[i], "-c", 2 ) == 0 )
  99.       if ( sscanf ( &argv[i][2], "%d", r3 ) != 1 )
  100.         printf ( "No space between flag name and parameter, please!n" ),
  101.         exit (1);
  102.  
  103.     i++;
  104.   }
  105.  
  106.   if ( *r1 == 0 || *r2 == 0 || *r3 == 0 )
  107.     printf ( "Invalid ellipsoid radiusn" ),
  108.     exit (1);
  109. }
  110.  
  111. main( argc, argv )
  112. int argc;
  113. char *argv[];
  114. {
  115.   int n;                /* number of points */
  116.   double x, y, z, w, t;
  117.   double R = 100.0;     /* default radius */
  118.   int r;                /* true radius */
  119.   int r1, r2, r3;       /* ellipsoid axis lengths */
  120.   int float_pt = FALSE;
  121.  
  122.   srandom( (int) time((long *) 0 ) );
  123.   if ( argc < 2 )
  124.     print_instruct(),
  125.     exit (1);
  126.  
  127.   r = R;
  128.   r1 = r2 = r3 = r;
  129.   TestFlags ( argc, argv, &r1, &r2, &r3, &r, &float_pt );
  130.  
  131.   n = atoi( argv[1] );
  132.  
  133.   while (n--) {
  134.     /* Generate a random point on a sphere of radius 1. */
  135.     /* the sphere is sliced at z, and a random point at angle t
  136.        generated on the circle of intersection. */
  137.     z = 2.0 * (double) random() / MAX_INT - 1.0;
  138.     t = 2.0 * M_PI * (double) random() / MAX_INT;
  139.     w = sqrt( 1 - z*z );
  140.     x = w * cos( t );
  141.     y = w * sin( t );
  142.    
  143.     if ( float_pt == FALSE )
  144.       printf ( "%6d  %6d  %6dn",
  145.                 irint( r1 * x ),
  146.                 irint( r2 * y ),
  147.                 irint( r3 * z ) );
  148.     else
  149.       printf ( "%6f  %6f  %6fn", r1 * x, r2 * y, r3 * z );
  150.   }
  151. }
  152.  

Share with your friends:

Print