gtc_random.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. ///////////////////////////////////////////////////////////////////////////////////
  2. /// OpenGL Mathematics (glm.g-truc.net)
  3. ///
  4. /// Copyright (c) 2005 - 2015 G-Truc Creation (www.g-truc.net)
  5. /// Permission is hereby granted, free of charge, to any person obtaining a copy
  6. /// of this software and associated documentation files (the "Software"), to deal
  7. /// in the Software without restriction, including without limitation the rights
  8. /// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. /// copies of the Software, and to permit persons to whom the Software is
  10. /// furnished to do so, subject to the following conditions:
  11. ///
  12. /// The above copyright notice and this permission notice shall be included in
  13. /// all copies or substantial portions of the Software.
  14. ///
  15. /// Restrictions:
  16. /// By making use of the Software for military purposes, you choose to make
  17. /// a Bunny unhappy.
  18. ///
  19. /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. /// THE SOFTWARE.
  26. ///
  27. /// @file test/gtc/gtc_random.cpp
  28. /// @date 2011-09-19 / 2014-11-25
  29. /// @author Christophe Riccio
  30. ///////////////////////////////////////////////////////////////////////////////////
  31. #include <glm/gtc/random.hpp>
  32. #include <glm/gtc/epsilon.hpp>
  33. #if(GLM_LANG & GLM_LANG_CXX0X_FLAG)
  34. # include <array>
  35. #endif
  36. int test_linearRand()
  37. {
  38. int Error = 0;
  39. glm::int32 const Min = 16;
  40. glm::int32 const Max = 32;
  41. {
  42. glm::u8vec2 AMin(std::numeric_limits<glm::u8>::max());
  43. glm::u8vec2 AMax(std::numeric_limits<glm::u8>::min());
  44. {
  45. for(std::size_t i = 0; i < 100000; ++i)
  46. {
  47. glm::u8vec2 A = glm::linearRand(glm::u8vec2(Min), glm::u8vec2(Max));
  48. AMin = glm::min(AMin, A);
  49. AMax = glm::max(AMax, A);
  50. if(!glm::all(glm::lessThanEqual(A, glm::u8vec2(Max))))
  51. ++Error;
  52. if(!glm::all(glm::greaterThanEqual(A, glm::u8vec2(Min))))
  53. ++Error;
  54. assert(!Error);
  55. }
  56. Error += glm::all(glm::equal(AMin, glm::u8vec2(Min))) ? 0 : 1;
  57. Error += glm::all(glm::equal(AMax, glm::u8vec2(Max))) ? 0 : 1;
  58. assert(!Error);
  59. }
  60. glm::u16vec2 BMin(std::numeric_limits<glm::u16>::max());
  61. glm::u16vec2 BMax(std::numeric_limits<glm::u16>::min());
  62. {
  63. for(std::size_t i = 0; i < 100000; ++i)
  64. {
  65. glm::u16vec2 B = glm::linearRand(glm::u16vec2(Min), glm::u16vec2(Max));
  66. BMin = glm::min(BMin, B);
  67. BMax = glm::max(BMax, B);
  68. if(!glm::all(glm::lessThanEqual(B, glm::u16vec2(Max))))
  69. ++Error;
  70. if(!glm::all(glm::greaterThanEqual(B, glm::u16vec2(Min))))
  71. ++Error;
  72. assert(!Error);
  73. }
  74. Error += glm::all(glm::equal(BMin, glm::u16vec2(Min))) ? 0 : 1;
  75. Error += glm::all(glm::equal(BMax, glm::u16vec2(Max))) ? 0 : 1;
  76. assert(!Error);
  77. }
  78. glm::u32vec2 CMin(std::numeric_limits<glm::u32>::max());
  79. glm::u32vec2 CMax(std::numeric_limits<glm::u32>::min());
  80. {
  81. for(std::size_t i = 0; i < 100000; ++i)
  82. {
  83. glm::u32vec2 C = glm::linearRand(glm::u32vec2(Min), glm::u32vec2(Max));
  84. CMin = glm::min(CMin, C);
  85. CMax = glm::max(CMax, C);
  86. if(!glm::all(glm::lessThanEqual(C, glm::u32vec2(Max))))
  87. ++Error;
  88. if(!glm::all(glm::greaterThanEqual(C, glm::u32vec2(Min))))
  89. ++Error;
  90. assert(!Error);
  91. }
  92. Error += glm::all(glm::equal(CMin, glm::u32vec2(Min))) ? 0 : 1;
  93. Error += glm::all(glm::equal(CMax, glm::u32vec2(Max))) ? 0 : 1;
  94. assert(!Error);
  95. }
  96. glm::u64vec2 DMin(std::numeric_limits<glm::u64>::max());
  97. glm::u64vec2 DMax(std::numeric_limits<glm::u64>::min());
  98. {
  99. for(std::size_t i = 0; i < 100000; ++i)
  100. {
  101. glm::u64vec2 D = glm::linearRand(glm::u64vec2(Min), glm::u64vec2(Max));
  102. DMin = glm::min(DMin, D);
  103. DMax = glm::max(DMax, D);
  104. if(!glm::all(glm::lessThanEqual(D, glm::u64vec2(Max))))
  105. ++Error;
  106. if(!glm::all(glm::greaterThanEqual(D, glm::u64vec2(Min))))
  107. ++Error;
  108. assert(!Error);
  109. }
  110. Error += glm::all(glm::equal(DMin, glm::u64vec2(Min))) ? 0 : 1;
  111. Error += glm::all(glm::equal(DMax, glm::u64vec2(Max))) ? 0 : 1;
  112. assert(!Error);
  113. }
  114. }
  115. {
  116. glm::i8vec2 AMin(std::numeric_limits<glm::i8>::max());
  117. glm::i8vec2 AMax(std::numeric_limits<glm::i8>::min());
  118. {
  119. for(std::size_t i = 0; i < 100000; ++i)
  120. {
  121. glm::i8vec2 A = glm::linearRand(glm::i8vec2(Min), glm::i8vec2(Max));
  122. AMin = glm::min(AMin, A);
  123. AMax = glm::max(AMax, A);
  124. if(!glm::all(glm::lessThanEqual(A, glm::i8vec2(Max))))
  125. ++Error;
  126. if(!glm::all(glm::greaterThanEqual(A, glm::i8vec2(Min))))
  127. ++Error;
  128. assert(!Error);
  129. }
  130. Error += glm::all(glm::equal(AMin, glm::i8vec2(Min))) ? 0 : 1;
  131. Error += glm::all(glm::equal(AMax, glm::i8vec2(Max))) ? 0 : 1;
  132. assert(!Error);
  133. }
  134. glm::i16vec2 BMin(std::numeric_limits<glm::i16>::max());
  135. glm::i16vec2 BMax(std::numeric_limits<glm::i16>::min());
  136. {
  137. for(std::size_t i = 0; i < 100000; ++i)
  138. {
  139. glm::i16vec2 B = glm::linearRand(glm::i16vec2(Min), glm::i16vec2(Max));
  140. BMin = glm::min(BMin, B);
  141. BMax = glm::max(BMax, B);
  142. if(!glm::all(glm::lessThanEqual(B, glm::i16vec2(Max))))
  143. ++Error;
  144. if(!glm::all(glm::greaterThanEqual(B, glm::i16vec2(Min))))
  145. ++Error;
  146. assert(!Error);
  147. }
  148. Error += glm::all(glm::equal(BMin, glm::i16vec2(Min))) ? 0 : 1;
  149. Error += glm::all(glm::equal(BMax, glm::i16vec2(Max))) ? 0 : 1;
  150. assert(!Error);
  151. }
  152. glm::i32vec2 CMin(std::numeric_limits<glm::i32>::max());
  153. glm::i32vec2 CMax(std::numeric_limits<glm::i32>::min());
  154. {
  155. for(std::size_t i = 0; i < 100000; ++i)
  156. {
  157. glm::i32vec2 C = glm::linearRand(glm::i32vec2(Min), glm::i32vec2(Max));
  158. CMin = glm::min(CMin, C);
  159. CMax = glm::max(CMax, C);
  160. if(!glm::all(glm::lessThanEqual(C, glm::i32vec2(Max))))
  161. ++Error;
  162. if(!glm::all(glm::greaterThanEqual(C, glm::i32vec2(Min))))
  163. ++Error;
  164. assert(!Error);
  165. }
  166. Error += glm::all(glm::equal(CMin, glm::i32vec2(Min))) ? 0 : 1;
  167. Error += glm::all(glm::equal(CMax, glm::i32vec2(Max))) ? 0 : 1;
  168. assert(!Error);
  169. }
  170. glm::i64vec2 DMin(std::numeric_limits<glm::i64>::max());
  171. glm::i64vec2 DMax(std::numeric_limits<glm::i64>::min());
  172. {
  173. for(std::size_t i = 0; i < 100000; ++i)
  174. {
  175. glm::i64vec2 D = glm::linearRand(glm::i64vec2(Min), glm::i64vec2(Max));
  176. DMin = glm::min(DMin, D);
  177. DMax = glm::max(DMax, D);
  178. if(!glm::all(glm::lessThanEqual(D, glm::i64vec2(Max))))
  179. ++Error;
  180. if(!glm::all(glm::greaterThanEqual(D, glm::i64vec2(Min))))
  181. ++Error;
  182. assert(!Error);
  183. }
  184. Error += glm::all(glm::equal(DMin, glm::i64vec2(Min))) ? 0 : 1;
  185. Error += glm::all(glm::equal(DMax, glm::i64vec2(Max))) ? 0 : 1;
  186. assert(!Error);
  187. }
  188. }
  189. for(std::size_t i = 0; i < 100000; ++i)
  190. {
  191. glm::f32vec2 const A(glm::linearRand(glm::f32vec2(static_cast<float>(Min)), glm::f32vec2(static_cast<float>(Max))));
  192. if(!glm::all(glm::lessThanEqual(A, glm::f32vec2(static_cast<float>(Max)))))
  193. ++Error;
  194. if(!glm::all(glm::greaterThanEqual(A, glm::f32vec2(static_cast<float>(Min)))))
  195. ++Error;
  196. glm::f64vec2 const B(glm::linearRand(glm::f64vec2(Min), glm::f64vec2(Max)));
  197. if(!glm::all(glm::lessThanEqual(B, glm::f64vec2(Max))))
  198. ++Error;
  199. if(!glm::all(glm::greaterThanEqual(B, glm::f64vec2(Min))))
  200. ++Error;
  201. assert(!Error);
  202. }
  203. {
  204. float ResultFloat = 0.0f;
  205. double ResultDouble = 0.0f;
  206. for(std::size_t i = 0; i < 100000; ++i)
  207. {
  208. ResultFloat += glm::linearRand(-1.0f, 1.0f);
  209. ResultDouble += glm::linearRand(-1.0, 1.0);
  210. }
  211. Error += glm::epsilonEqual(ResultFloat, 0.0f, 0.0001f);
  212. Error += glm::epsilonEqual(ResultDouble, 0.0, 0.0001);
  213. assert(!Error);
  214. }
  215. return Error;
  216. }
  217. int test_circularRand()
  218. {
  219. int Error = 0;
  220. {
  221. std::size_t Max = 100000;
  222. float ResultFloat = 0.0f;
  223. double ResultDouble = 0.0f;
  224. double Radius = 2.0f;
  225. for(std::size_t i = 0; i < Max; ++i)
  226. {
  227. ResultFloat += glm::length(glm::circularRand(1.0f));
  228. ResultDouble += glm::length(glm::circularRand(Radius));
  229. }
  230. Error += glm::epsilonEqual(ResultFloat, float(Max), 0.01f) ? 0 : 1;
  231. Error += glm::epsilonEqual(ResultDouble, double(Max) * double(Radius), 0.01) ? 0 : 1;
  232. assert(!Error);
  233. }
  234. return Error;
  235. }
  236. int test_sphericalRand()
  237. {
  238. int Error = 0;
  239. {
  240. std::size_t Max = 100000;
  241. float ResultFloatA = 0.0f;
  242. float ResultFloatB = 0.0f;
  243. float ResultFloatC = 0.0f;
  244. double ResultDoubleA = 0.0f;
  245. double ResultDoubleB = 0.0f;
  246. double ResultDoubleC = 0.0f;
  247. for(std::size_t i = 0; i < Max; ++i)
  248. {
  249. ResultFloatA += glm::length(glm::sphericalRand(1.0f));
  250. ResultDoubleA += glm::length(glm::sphericalRand(1.0));
  251. ResultFloatB += glm::length(glm::sphericalRand(2.0f));
  252. ResultDoubleB += glm::length(glm::sphericalRand(2.0));
  253. ResultFloatC += glm::length(glm::sphericalRand(3.0f));
  254. ResultDoubleC += glm::length(glm::sphericalRand(3.0));
  255. }
  256. Error += glm::epsilonEqual(ResultFloatA, float(Max), 0.01f) ? 0 : 1;
  257. Error += glm::epsilonEqual(ResultDoubleA, double(Max), 0.0001) ? 0 : 1;
  258. Error += glm::epsilonEqual(ResultFloatB, float(Max * 2), 0.01f) ? 0 : 1;
  259. Error += glm::epsilonEqual(ResultDoubleB, double(Max * 2), 0.0001) ? 0 : 1;
  260. Error += glm::epsilonEqual(ResultFloatC, float(Max * 3), 0.01f) ? 0 : 1;
  261. Error += glm::epsilonEqual(ResultDoubleC, double(Max * 3), 0.01) ? 0 : 1;
  262. assert(!Error);
  263. }
  264. return Error;
  265. }
  266. int test_diskRand()
  267. {
  268. int Error = 0;
  269. {
  270. float ResultFloat = 0.0f;
  271. double ResultDouble = 0.0f;
  272. for(std::size_t i = 0; i < 100000; ++i)
  273. {
  274. ResultFloat += glm::length(glm::diskRand(2.0f));
  275. ResultDouble += glm::length(glm::diskRand(2.0));
  276. }
  277. Error += ResultFloat < 200000.f ? 0 : 1;
  278. Error += ResultDouble < 200000.0 ? 0 : 1;
  279. assert(!Error);
  280. }
  281. return Error;
  282. }
  283. int test_ballRand()
  284. {
  285. int Error = 0;
  286. {
  287. float ResultFloat = 0.0f;
  288. double ResultDouble = 0.0f;
  289. for(std::size_t i = 0; i < 100000; ++i)
  290. {
  291. ResultFloat += glm::length(glm::ballRand(2.0f));
  292. ResultDouble += glm::length(glm::ballRand(2.0));
  293. }
  294. Error += ResultFloat < 200000.f ? 0 : 1;
  295. Error += ResultDouble < 200000.0 ? 0 : 1;
  296. assert(!Error);
  297. }
  298. return Error;
  299. }
  300. /*
  301. #if(GLM_LANG & GLM_LANG_CXX0X_FLAG)
  302. int test_grid()
  303. {
  304. int Error = 0;
  305. typedef std::array<int, 8> colors;
  306. typedef std::array<int, 8 * 8> grid;
  307. grid Grid;
  308. colors Colors;
  309. grid GridBest;
  310. colors ColorsBest;
  311. while(true)
  312. {
  313. for(std::size_t i = 0; i < Grid.size(); ++i)
  314. Grid[i] = int(glm::linearRand(0.0, 8.0 * 8.0 * 8.0 - 1.0) / 64.0);
  315. for(std::size_t i = 0; i < Grid.size(); ++i)
  316. ++Colors[Grid[i]];
  317. bool Exit = true;
  318. for(std::size_t i = 0; i < Colors.size(); ++i)
  319. {
  320. if(Colors[i] == 8)
  321. continue;
  322. Exit = false;
  323. break;
  324. }
  325. if(Exit == true)
  326. break;
  327. }
  328. return Error;
  329. }
  330. #endif
  331. */
  332. int main()
  333. {
  334. int Error = 0;
  335. Error += test_linearRand();
  336. Error += test_circularRand();
  337. Error += test_sphericalRand();
  338. Error += test_diskRand();
  339. Error += test_ballRand();
  340. /*
  341. #if(GLM_LANG & GLM_LANG_CXX0X_FLAG)
  342. Error += test_grid();
  343. #endif
  344. */
  345. return Error;
  346. }