#include <random> #include <ctime> #include <algorithm> #include <cmath> #include <tuple> #include <iostream> #include <iomanip> #define WARM_UP_ENGINE using vector = std::tuple<double,double,double> ; const auto x = [] ( vector v ) { return std::get<0>(v) ; } ; const auto y = [] ( vector v ) { return std::get<1>(v) ; } ; const auto z = [] ( vector v ) { return std::get<2>(v) ; } ; double norm( vector v ) { return std::sqrt( x(v)*x(v) + y(v)*y(v) + z(v)*z(v) ) ; } vector random_vector() { #ifdef WARM_UP_ENGINE // if high quality pseudo-randomness is criticsl static int sseq[ std::mt19937::state_size ] ; const static bool once = ( std::srand( std::time(nullptr) ), std::generate( std::begin(sseq), std::end(sseq), std::rand ), true ) ; static std::seed_seq seed_seq( std::begin(sseq), std::end(sseq) ) ; static std::mt19937 twister(seed_seq) ; #else // no warm up is required, should be adequate for normal use static std::mt19937 twister( std::time(0) ) ; #endif // WARM_UP_ENGINE static std::uniform_real_distribution<double> distr( -1000, 1000 ) ; return vector( distr(twister), distr(twister), distr(twister) ) ; } vector random_unit_vector() { auto v = random_vector() ; constexpr double epsilon = 0.01 ; double m = norm(v) ; if( m > epsilon ) return vector( x(v)/m, y(v)/m, z(v)/m ) ; else return random_unit_vector() ; } int main() { std::cout << std::fixed << std::setprecision(3) ; for( int i = 0 ; i < 10 ; ++i ) { auto v = random_unit_vector() ; std::cout << std::showpos << "(" << x(v) << ',' << y(v) << ',' << z(v) << ") " ; // move the random unit vector to a random location static std::mt19937 twister( std::time(0) ) ; static std::uniform_real_distribution<double> distr( -10, 10 ) ; double x1 = distr(twister), y1 = distr(twister), z1 = distr(twister) ; double x2 = x1 + x(v), y2 = y1 + y(v), z2 = z1+z(v) ; std::cout << std::showpos << " (" << x1 << ',' << y1 << ',' << z1 << ')' << " ----> (" << x2 << ',' << y2 << ',' << z2 << ")\n\n" ; } }
Standard input is empty
(+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)