intersections.cpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. // intersections.cpp
  2. //
  3. // Copyright (c) 2018
  4. // Justinas V. Daugmaudis
  5. //
  6. // Distributed under the Boost Software License, Version 1.0. (See
  7. // accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //[intersections
  10. /*`
  11. For the source of this example see
  12. [@boost://libs/random/example/intersections.cpp intersections.cpp].
  13. This example demonstrates generating quasi-randomly distributed chord
  14. entry and exit points on an S[sup 2] sphere.
  15. First we include the headers we need for __niederreiter_base2
  16. and __uniform_01 distribution.
  17. */
  18. #include <boost/random/niederreiter_base2.hpp>
  19. #include <boost/random/uniform_01.hpp>
  20. #include <boost/math/constants/constants.hpp>
  21. #include <boost/tuple/tuple.hpp>
  22. /*`
  23. We use 4-dimensional __niederreiter_base2 as a source of randomness.
  24. */
  25. boost::random::niederreiter_base2 gen(4);
  26. int main()
  27. {
  28. typedef boost::tuple<double, double, double> point_t;
  29. const std::size_t n_points = 100; // we will generate 100 points
  30. std::vector<point_t> points;
  31. points.reserve(n_points);
  32. /*<< __niederreiter_base2 produces integers in the range [0, 2[sup 64]-1].
  33. However, we want numbers in the range [0, 1). The distribution
  34. __uniform_01 performs this transformation.
  35. >>*/
  36. boost::random::uniform_01<double> dist;
  37. for (std::size_t i = 0; i != n_points; ++i)
  38. {
  39. /*`
  40. Using formula from J. Rovira et al., "Point sampling with uniformly distributed lines", 2005
  41. to compute uniformly distributed chord entry and exit points on the surface of a sphere.
  42. */
  43. double cos_theta = 1 - 2 * dist(gen);
  44. double sin_theta = std::sqrt(1 - cos_theta * cos_theta);
  45. double phi = boost::math::constants::two_pi<double>() * dist(gen);
  46. double sin_phi = std::sin(phi), cos_phi = std::cos(phi);
  47. point_t point_on_sphere(sin_theta*sin_phi, cos_theta, sin_theta*cos_phi);
  48. /*`
  49. Here we assume that our sphere is a unit sphere at origin. If your sphere was
  50. different then now would be the time to scale and translate the `point_on_sphere`.
  51. */
  52. points.push_back(point_on_sphere);
  53. }
  54. /*`
  55. Vector `points` now holds generated 3D points on a sphere.
  56. */
  57. return 0;
  58. }
  59. //]