PageRenderTime 44ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/sqrtvis/src/main.cpp

https://bitbucket.org/rayburgemeestre/sqrtvis
C++ | 221 lines | 168 code | 41 blank | 12 comment | 18 complexity | 51f3767143ea9b58e67db4891a34270d MD5 | raw file
  1. #include <string>
  2. #include <map>
  3. #include <algorithm>
  4. using std::string;
  5. using std::map;
  6. using std::for_each;
  7. using std::begin;
  8. using std::end;
  9. #include <SFML/Graphics.hpp>
  10. #include <SFML/Window.hpp>
  11. #include "rsqrt_carmack.h"
  12. #include "rsqrt_lomont.h"
  13. #include "rsqrt_walsh.h"
  14. #include "rsqrt_hulsman.h"
  15. #include "rsqrt_lee.h"
  16. #include "rsqrt_hsieh.h"
  17. #include "rsqrt_karvonen.h"
  18. #include "rsqrt_julery.h"
  19. #include "rsqrt_crowne.h"
  20. #include "rsqrt_juffa.h"
  21. #include "rsqrt_other.h"
  22. #define SHOW_STACKED
  23. #define GRADIENT_TYPE_RADIAL 1
  24. #define GRADIENT_TYPE_VERTICAL 2
  25. #ifdef SHOW_STACKED
  26. //#define GRADIENT_TYPE GRADIENT_TYPE_VERTICAL
  27. #define GRADIENT_TYPE GRADIENT_TYPE_RADIAL
  28. #else
  29. #define GRADIENT_TYPE GRADIENT_TYPE_RADIAL
  30. #endif
  31. static const int formulae = 17;
  32. static const int width = 1024;
  33. #ifdef SHOW_STACKED
  34. static const int sliceHeight = 80;//32;
  35. static const int height = (sliceHeight * formulae) + (formulae - 1);
  36. #else
  37. static const int sliceHeight = 1024;
  38. static const int height = 1024;
  39. #endif
  40. double lee_sqrt(double in) { return lee::sqrt(in); }
  41. double lee_fsqrt(double in) { return lee::fsqrt(in); }
  42. double hulsman_rsqrt(double in) { return 1.0 / hulsman::rsqrt(in); }
  43. double lomont_invsqrt(double in) { return 1.0 / lomont::InvSqrt(in); }
  44. double walsh_invsqrt(double in) { return 1.0 / walsh::invSqrt(in); }
  45. double carmack_q_rsqrt(double in) { return 1.0 / carmack::Q_rsqrt(in); }
  46. double carmack_q_frsqrt(double in) { return 1.0 / carmack::Q_frsqrt(in); }
  47. double carmack_d3rsqrt(double in) { return 1.0 / carmack::D3RSqrt(in); }
  48. double carmack_d3invsqrt(double in) { return 1.0 / carmack::D3InvSqrt(in); }
  49. double hsieh_fsqrt(double in) { return hsieh::fsqrt(in); }
  50. double karvonen_inv_sqrt(double in) { return 1.0 / karvonen::Inv_Sqrt(in); }
  51. // double hsieh_fred_sqrt(double in) { return static_cast<double>(hsieh::fred_sqrt(static_cast<unsigned long>(in * /*std::numeric_limits<unsigned long>::max() */ 65535))); } <<< this created the 'fractal' ;')
  52. double hsieh_fred_sqrt(double in) { return static_cast<double>(hsieh::fred_sqrt(static_cast<unsigned long>(in))); }
  53. double hsieh_isqrt(double in) { return static_cast<double>(hsieh::isqrt(static_cast<long>(in))); } // didn't work for me
  54. double julery_isqrt(double in) { return julery::julery_isqrt(static_cast<unsigned long>(in)); }
  55. double crowne_mcrowne_isqrt(double in) { return crowne::mcrowne_isqrt(static_cast<unsigned long>(in)); }
  56. double juffa_isqrt(double in) { return juffa::isqrt(static_cast<unsigned long>(in)); }
  57. double other_sqrt_approx(double in) { return other::sqrt_approx(in); }
  58. #define min(a, b) (a < b ? a : b)
  59. #define max(a, b) (a > b ? a : b)
  60. double dummy(double in) { return in ; }
  61. int main(int argc, char *argv[])
  62. {
  63. typedef double (*sqrtfunc)(double );
  64. map<string, sqrtfunc> funcs;
  65. funcs["sqrt"] = sqrt;
  66. if (true) {
  67. funcs["lee::sqrt"] = lee_sqrt;
  68. funcs["lee::fsqrt"] = lee_fsqrt;
  69. funcs["hulsman::rsqrt"] = hulsman_rsqrt;
  70. funcs["lomont::InvSqrt"] = lomont_invsqrt;
  71. funcs["walsh::invSqrt"] = walsh_invsqrt;
  72. funcs["carmack::Q_rsqrt"] = carmack_q_rsqrt;
  73. funcs["carmack::Q_frsqrt"] = carmack_q_frsqrt;
  74. funcs["carmack::D3RSqrt"] = carmack_d3rsqrt;
  75. funcs["carmack::D3InvSqrt"] = carmack_d3invsqrt;
  76. }
  77. funcs["hsieh_fsqrt"] = hsieh_fsqrt;
  78. funcs["hsieh_fred_sqrt"] = hsieh_fred_sqrt;
  79. funcs["julery_isqrt"] = julery_isqrt;
  80. funcs["crowne_mcrowne_isqrt"] = crowne_mcrowne_isqrt;
  81. funcs["juffa_isqrt"] = juffa_isqrt;
  82. funcs["other_sqrt_approx"] = other_sqrt_approx;
  83. //funcs["approx1"] = dummy; // Not really a good approximation for sqrt!
  84. //funcs["karvonen_inv_sqrt"] = karvonen_inv_sqrt; // didn't work on my VS2012 32bit
  85. //funcs["hsieh_isqrt"] = hsieh_isqrt; // idem.
  86. carmack::init();
  87. sf::RenderWindow window(sf::VideoMode(width, height, 32), "Test");
  88. sf::Image image;
  89. sf::Font font;
  90. if (!font.loadFromFile("test.otf"))
  91. return EXIT_FAILURE;
  92. const int centerX = static_cast<int>(static_cast<float>(width) / 2.0 + 0.5);
  93. const int centerY = static_cast<int>(static_cast<float>(sliceHeight) / 2.0 + 0.5);
  94. window.clear(sf::Color(0, 0, 0, 255));
  95. int offsetY = 0;
  96. for (auto i=funcs.begin(); i!=funcs.end() ; i++)
  97. {
  98. image.create(width, sliceHeight, sf::Color(0, 0, 0, 255));
  99. auto &a = *i;
  100. auto *pixels = const_cast<sf::Uint8 *>(image.getPixelsPtr());
  101. double maxdiff = 0.0;
  102. for(int x = 0; x < width; x++)
  103. {
  104. for(int y = 0; y < sliceHeight; y++)
  105. {
  106. #if GRADIENT_TYPE == GRADIENT_TYPE_RADIAL
  107. auto res = a.second((pow(x - centerX, 2) + pow(y - centerY, 2))); /// (-90 + sqrt(pow(width/2.0,2) + pow(height/2.0,2)));
  108. #endif
  109. #if GRADIENT_TYPE == GRADIENT_TYPE_VERTICAL
  110. auto res = a.second(pow(width - x , 2)) / width;
  111. #endif
  112. /**
  113. * Hardcoded clause for, because it's not really a good sqrt() replacement I couldn't fit it in the 'funcs' map, as it operates with x and y variables:
  114. * (source: http://www.azillionmonkeys.com/qed/sqroot.html#distance)
  115. *
  116. * (1 + 1/(4-2*√2))/2 * min((1 / √2)*(|x|+|y|), max (|x|, |y|))
  117. *
  118. */
  119. if (a.first == "approx1")
  120. {
  121. static const double sqrtOf2 = sqrt(2);
  122. #if GRADIENT_TYPE == GRADIENT_TYPE_RADIAL
  123. auto xAbs = abs(x - centerX);
  124. auto yAbs = abs(y - centerY);
  125. #endif
  126. #if GRADIENT_TYPE == GRADIENT_TYPE_VERTICAL
  127. auto xAbs = abs(width - x);
  128. auto yAbs = 0;
  129. #endif
  130. res = (1. + 1./(4.-2.*sqrtOf2))/2. * min((1. / sqrtOf2)*(xAbs + yAbs), max (xAbs, yAbs));
  131. #if GRADIENT_TYPE == GRADIENT_TYPE_VERTICAL
  132. res /= width;
  133. #endif
  134. }
  135. #if GRADIENT_TYPE == GRADIENT_TYPE_RADIAL
  136. res /= (-90 + sqrt(pow(width/2.0,2) + pow(height/2.0,2)));
  137. #endif
  138. if (a.first == "approx1")
  139. res = res;
  140. #if GRADIENT_TYPE == GRADIENT_TYPE_RADIAL
  141. res *= 4;
  142. #endif
  143. char color = 255.0 * res;
  144. #if GRADIENT_TYPE == GRADIENT_TYPE_RADIAL
  145. while (res > 1.0)
  146. res -= 1.0;
  147. color = (fabs(res - 0.5) * 2.0) * 255.0;
  148. #endif
  149. pixels[(x + y * width) * 4 + 0] = color; // R
  150. pixels[(x + y * width) * 4 + 1] = color; // G
  151. pixels[(x + y * width) * 4 + 2] = color; // B
  152. pixels[(x + y * width) * 4 + 3] = 255; // A
  153. }
  154. }
  155. sf::Texture texture;
  156. texture.loadFromImage(image);
  157. sf::Sprite sprite;
  158. sprite.setTexture(texture);
  159. sf::Text error;
  160. error.setString(a.first);
  161. error.setPosition(10, 3 + offsetY);
  162. error.setCharacterSize(18);
  163. error.setFont(font);
  164. error.setColor(sf::Color(255, 0, 0, 255));
  165. sprite.setPosition(0, offsetY);
  166. #ifdef SHOW_STACKED
  167. offsetY += sliceHeight + 1;
  168. #endif
  169. window.draw(sprite);
  170. window.draw(error);
  171. static int counter = 0;
  172. char filename[80+1] = {0x00};
  173. counter++;
  174. sprintf(filename, "%d %s.bmp", counter, a.first.c_str());
  175. std::replace(begin(filename), end(filename), ':', '_');
  176. window.display();
  177. window.capture().saveToFile(filename);
  178. };
  179. return 0;
  180. }