Random.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. //
  2. // Random.h
  3. // cocos2d_libs
  4. //
  5. // Created by 徐俊杰 on 2020/5/25.
  6. //
  7. #ifndef Random_h
  8. #define Random_h
  9. #include "rparticle/Math/Random/rand.h"
  10. //#include "Runtime/Math/Vector2.h"
  11. //#include "Runtime/Math/Quaternion.h"
  12. #include "rparticle/Math/FloatConversion.h"
  13. NS_RRP_BEGIN
  14. inline float RangedRandom (Rand& r, float min, float max)
  15. {
  16. float t = r.GetFloat ();
  17. t = min * t + (1.0F - t) * max;
  18. return t;
  19. }
  20. inline float Random01 (Rand& r)
  21. {
  22. return r.GetFloat ();
  23. }
  24. inline int RangedRandom (Rand& r, int min, int max)
  25. {
  26. int dif;
  27. if (min < max)
  28. {
  29. dif = max - min;
  30. int t = r.Get () % dif;
  31. t += min;
  32. return t;
  33. }
  34. else if (min > max)
  35. {
  36. dif = min - max;
  37. int t = r.Get () % dif;
  38. t = min - t;
  39. return t;
  40. }
  41. else
  42. {
  43. return min;
  44. }
  45. }
  46. inline Vector3f RandomUnitVector (Rand& rand)
  47. {
  48. float z = RangedRandom (rand, -1.0f, 1.0f);
  49. float a = RangedRandom (rand, 0.0f, 2.0F * kPI);
  50. float r = sqrt (1.0f - z*z);
  51. float x = r * cos (a);
  52. float y = r * sin (a);
  53. return Vector3f (x, y, z);
  54. }
  55. inline Vector2f RandomUnitVector2 (Rand& rand)
  56. {
  57. float a = RangedRandom (rand, 0.0f, 2.0F * kPI);
  58. float x = cos (a);
  59. float y = sin (a);
  60. return Vector2f (x, y);
  61. }
  62. inline Quaternionf RandomQuaternion (Rand& rand)
  63. {
  64. Quaternionf q;
  65. q.x = RangedRandom (rand, -1.0f, 1.0f);
  66. q.y = RangedRandom (rand, -1.0f, 1.0f);
  67. q.z = RangedRandom (rand, -1.0f, 1.0f);
  68. q.w = RangedRandom (rand, -1.0f, 1.0f);
  69. q = NormalizeSafe (q);
  70. if (Dot (q, Quaternionf::identity ()) < 0.0f)
  71. return -q;
  72. else
  73. return q;
  74. }
  75. inline Quaternionf RandomQuaternionUniformDistribution (Rand& rand)
  76. {
  77. const float two_pi = 2.0F * kPI;
  78. // Employs Hopf fibration to uniformly distribute quaternions
  79. float u1 = RangedRandom( rand, 0.0f, 1.0f );
  80. float theta = RangedRandom( rand, 0.0f, two_pi );
  81. float rho = RangedRandom( rand, 0.0f, two_pi );
  82. float i = sqrt( 1.0f - u1 );
  83. float j = sqrt( u1 );
  84. // We do not need to normalize the generated quaternion, because the probability density corresponds to the Haar measure.
  85. // This means that a random rotation is obtained by picking a point at random on S^3, and forming the unit quaternion.
  86. Quaternionf q( i * sin(theta), i * cos(theta), j * sin(rho), j * cos(rho) );
  87. if (Dot (q, Quaternionf::identity ()) < 0.0f)
  88. return -q;
  89. else
  90. return q;
  91. }
  92. inline Vector3f RandomPointInsideCube (Rand& r, const Vector3f& extents)
  93. {
  94. return Vector3f ( RangedRandom (r, -extents.x, extents.x),
  95. RangedRandom (r, -extents.y, extents.y),
  96. RangedRandom (r, -extents.z, extents.z));
  97. }
  98. inline Vector3f RandomPointBetweenCubes (Rand& r, const Vector3f& min, const Vector3f& max)
  99. {
  100. Vector3f v;
  101. int i;
  102. for (i=0;i<3;i++)
  103. {
  104. float x = r.GetFloat () * 2.0F - 1.0F;
  105. if (x > 0.0f)
  106. v[i] = min[i] + x * (max[i] - min[i]);
  107. else
  108. v[i] = -min[i] + x * (max[i] - min[i]);
  109. }
  110. return v;
  111. }
  112. inline Vector3f RandomPointInsideUnitSphere (Rand& r)
  113. {
  114. Vector3f v = RandomUnitVector (r);
  115. v *= pow (Random01 (r), 1.0F / 3.0F);
  116. return v;
  117. }
  118. inline Vector3f RandomPointInsideEllipsoid (Rand& r, const Vector3f& extents)
  119. {
  120. return ScaleVec3 (RandomPointInsideUnitSphere (r), extents);
  121. }
  122. inline Vector3f RandomPointBetweenSphere (Rand& r, float minRadius, float maxRadius)
  123. {
  124. Vector3f v = RandomUnitVector (r);
  125. // As the volume of the sphere increases (x^3) over an interval we have to increase range as well with x^(1/3)
  126. float range = pow (RangedRandom (r, 0.0F, 1.0F), 1.0F / 3.0F);
  127. return v * (minRadius + (maxRadius - minRadius) * range);
  128. }
  129. inline Vector2f RandomPointInsideUnitCircle (Rand& r)
  130. {
  131. Vector2f v = RandomUnitVector2 (r);
  132. // As the volume of the sphere increases (x^3) over an interval we have to increase range as well with x^(1/3)
  133. v *= pow (RangedRandom (r, 0.0F, 1.0F), 1.0F / 2.0F);
  134. return v;
  135. }
  136. inline Vector3f RandomPointBetweenEllipsoid (Rand& r, const Vector3f& maxExtents, float minRange)
  137. {
  138. Vector3f v = ScaleVec3 (RandomUnitVector (r), maxExtents);
  139. // As the volume of the sphere increases (x^3) over an interval we have to increase range as well with x^(1/3)
  140. float range = pow (RangedRandom (r, minRange, 1.0F), 1.0F / 3.0F);
  141. return v * range;
  142. }
  143. /// Builds a random Barycentric coordinate which can be used to generate random points on a triangle:
  144. /// Vector3f point = v0 * barycentric.x + v1 * barycentric.y + v2 * barycentric.z;
  145. inline Vector3f RandomBarycentricCoord (Rand& rand)
  146. {
  147. // Was told that this leads to bad distribution because of the 1.0F - s
  148. // float s = gRand.GetFloat ();
  149. // float t = RangedRandom (gRand, 0.0F, 1.0F - s);
  150. // float r = (1.0F - s - t);
  151. // Vector3f positionOnMesh = r * vertices[face.v1] + s * vertices[face.v2] + t * vertices[face.v3];
  152. // return positionOnMesh;
  153. float u = rand.GetFloat ();
  154. float v = rand.GetFloat ();
  155. if (u + v > 1.0F)
  156. {
  157. u = 1.0F - u;
  158. v = 1.0F - v;
  159. }
  160. float w = 1.0F - u - v;
  161. return Vector3f (u, v, w);
  162. }
  163. NS_RRP_END
  164. #endif /* Random_h */