fork download
  1. #include <random>
  2. #include <ctime>
  3. #include <algorithm>
  4. #include <cmath>
  5. #include <tuple>
  6. #include <iostream>
  7. #include <iomanip>
  8.  
  9. #define WARM_UP_ENGINE
  10.  
  11. using vector = std::tuple<double,double,double> ;
  12.  
  13. const auto x = [] ( vector v ) { return std::get<0>(v) ; } ;
  14. const auto y = [] ( vector v ) { return std::get<1>(v) ; } ;
  15. const auto z = [] ( vector v ) { return std::get<2>(v) ; } ;
  16.  
  17. double norm( vector v ) { return std::sqrt( x(v)*x(v) + y(v)*y(v) + z(v)*z(v) ) ; }
  18.  
  19. vector random_vector()
  20. {
  21. #ifdef WARM_UP_ENGINE // if high quality pseudo-randomness is criticsl
  22.  
  23. static int sseq[ std::mt19937::state_size ] ;
  24. const static bool once = ( std::srand( std::time(nullptr) ),
  25. std::generate( std::begin(sseq), std::end(sseq), std::rand ),
  26. true ) ;
  27. static std::seed_seq seed_seq( std::begin(sseq), std::end(sseq) ) ;
  28. static std::mt19937 twister(seed_seq) ;
  29.  
  30. #else // no warm up is required, should be adequate for normal use
  31.  
  32. static std::mt19937 twister( std::time(0) ) ;
  33.  
  34. #endif // WARM_UP_ENGINE
  35.  
  36. static std::uniform_real_distribution<double> distr( -1000, 1000 ) ;
  37.  
  38. return vector( distr(twister), distr(twister), distr(twister) ) ;
  39. }
  40.  
  41. vector random_unit_vector()
  42. {
  43. auto v = random_vector() ;
  44. constexpr double epsilon = 0.01 ;
  45. double m = norm(v) ;
  46. if( m > epsilon ) return vector( x(v)/m, y(v)/m, z(v)/m ) ;
  47. else return random_unit_vector() ;
  48. }
  49.  
  50. int main()
  51. {
  52. std::cout << std::fixed << std::setprecision(3) ;
  53.  
  54. for( int i = 0 ; i < 10 ; ++i )
  55. {
  56. auto v = random_unit_vector() ;
  57. std::cout << std::showpos << "(" << x(v) << ',' << y(v) << ',' << z(v)
  58. << ") " ;
  59.  
  60. // move the random unit vector to a random location
  61. static std::mt19937 twister( std::time(0) ) ;
  62. static std::uniform_real_distribution<double> distr( -10, 10 ) ;
  63.  
  64. double x1 = distr(twister), y1 = distr(twister), z1 = distr(twister) ;
  65. double x2 = x1 + x(v), y2 = y1 + y(v), z2 = z1+z(v) ;
  66.  
  67. std::cout << std::showpos << " (" << x1 << ',' << y1 << ',' << z1 << ')'
  68. << " ----> (" << x2 << ',' << y2 << ',' << z2 << ")\n\n" ;
  69. }
  70. }
  71.  
Success #stdin #stdout 0s 2996KB
stdin
Standard input is empty
stdout
(+0.619,+0.744,+0.252)      (+8.559,+4.928,-2.910) ----> (+9.178,+5.672,-2.658)

(-0.967,+0.251,+0.028)      (+8.881,+4.707,-9.726) ----> (+7.913,+4.958,-9.698)

(+0.854,+0.144,+0.499)      (+6.184,+8.535,-4.721) ----> (+7.038,+8.679,-4.222)

(+0.244,+0.944,+0.222)      (+7.568,+7.937,+0.609) ----> (+7.812,+8.881,+0.831)

(+0.598,-0.703,+0.384)      (+0.028,-7.638,-8.365) ----> (+0.626,-8.341,-7.981)

(-0.598,-0.065,-0.799)      (-6.498,+2.183,+4.027) ----> (-7.096,+2.118,+3.228)

(-0.369,-0.005,-0.929)      (-2.873,-5.523,-9.712) ----> (-3.242,-5.528,-10.642)

(-0.693,+0.331,-0.641)      (-8.489,+7.952,-6.425) ----> (-9.181,+8.283,-7.066)

(+0.142,-0.637,-0.758)      (-0.247,+0.709,-5.339) ----> (-0.105,+0.072,-6.097)

(-0.346,+0.929,-0.133)      (-1.630,+8.778,+8.847) ----> (-1.977,+9.706,+8.714)