Gradient.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. #include "Gradient.h"
  2. #include <cmath>
  3. #include <algorithm>
  4. /*
  5. Gradient::Gradient()
  6. {
  7. //addColor(RGBColor{255, 0, 0}, -100);
  8. addColor(RGBColor{0, 0, 0}, 0);
  9. addColor(RGBColor{ 250, 70, 24 }, 40);
  10. addColor(RGBColor{ 200, 230, 30 }, 104);
  11. addColor(RGBColor{ 70, 223, 30 }, 190);
  12. addColor(RGBColor{ 14, 20, 150 }, 295);
  13. addColor(RGBColor{ 36, 155, 169 }, 418);
  14. addColor(RGBColor{ 233, 33, 79 }, 558);
  15. addColor(RGBColor{ 254, 169, 63 }, 714);
  16. addColor(RGBColor{ 227, 93, 201 }, 885);
  17. addColor(RGBColor{ 188, 24, 161 }, 1071);
  18. addColor(RGBColor{ 45, 225, 44 }, 1271);
  19. addColor(RGBColor{ 52, 58, 250 }, 1485);
  20. addColor(RGBColor{ 87, 93, 241 }, 1712);
  21. addColor(RGBColor{ 6, 37, 208 }, 1952);
  22. addColor(RGBColor{ 193, 164, 162 }, 2205);
  23. addColor(RGBColor{ 49, 8, 90 }, 2471);
  24. addColor(RGBColor{ 124, 149, 120 }, 2749);
  25. addColor(RGBColor{ 56, 69, 6 }, 3039);
  26. addColor(RGBColor{ 231, 177, 252 }, 3341);
  27. addColor(RGBColor{ 36, 76, 95 }, 3655);
  28. addColor(RGBColor{ 1, 99, 184 }, 3980);
  29. addColor(RGBColor{ 74, 223, 199 }, 4316);
  30. addColor(RGBColor{ 249, 125, 31 }, 4664);
  31. addColor(RGBColor{ 28, 93, 214 }, 5023);
  32. addColor(RGBColor{ 232, 117, 145 }, 5393);
  33. addColor(RGBColor{ 208, 158, 49 }, 5773);
  34. addColor(RGBColor{ 218, 109, 177 }, 6164);
  35. addColor(RGBColor{ 139, 83, 177 }, 6565);
  36. addColor(RGBColor{ 16, 36, 59 }, 6977);
  37. addColor(RGBColor{ 194, 157, 26 }, 7399);
  38. addColor(RGBColor{ 77, 236, 12 }, 7831);
  39. addColor(RGBColor{ 124, 244, 151 }, 8273);
  40. addColor(RGBColor{ 128, 195, 162 }, 8725);
  41. addColor(RGBColor{ 66, 36, 194 }, 9187);
  42. addColor(RGBColor{ 81, 151, 185 }, 9659);
  43. addColor(RGBColor{ 173, 75, 175 }, 10140);
  44. addColor(RGBColor{ 43, 182, 52 }, 10631);
  45. addColor(RGBColor{ 14, 242, 141 }, 11131);
  46. addColor(RGBColor{ 156, 203, 87 }, 11641);
  47. addColor(RGBColor{ 147, 89, 150 }, 12160);
  48. addColor(RGBColor{ 213, 199, 183 }, 12689);
  49. addColor(RGBColor{ 186, 255, 52 }, 13227);
  50. addColor(RGBColor{ 28, 158, 154 }, 13774);
  51. addColor(RGBColor{ 5, 5, 116 }, 14330);
  52. addColor(RGBColor{ 126, 123, 232 }, 14895);
  53. addColor(RGBColor{ 43, 162, 251 }, 15469);
  54. addColor(RGBColor{ 198, 143, 125 }, 16052);
  55. addColor(RGBColor{ 201, 157, 178 }, 16644);
  56. addColor(RGBColor{ 213, 151, 189 }, 17245);
  57. addColor(RGBColor{ 188, 117, 169 }, 17854);
  58. addColor(RGBColor{ 156, 189, 249 }, 18472);
  59. addColor(RGBColor{ 62, 23, 33 }, 19099);
  60. addColor(RGBColor{ 167, 205, 74 }, 19734);
  61. addColor(RGBColor{ 161, 181, 210 }, 20378);
  62. addColor(RGBColor{ 179, 167, 215 }, 21030);
  63. addColor(RGBColor{ 204, 102, 126 }, 21691);
  64. addColor(RGBColor{ 123, 49, 127 }, 22360);
  65. addColor(RGBColor{ 178, 48, 136 }, 23037);
  66. addColor(RGBColor{ 108, 112, 99 }, 23723);
  67. addColor(RGBColor{ 250, 152, 78 }, 24417);
  68. addColor(RGBColor{ 79, 167, 196 }, 25119);
  69. addColor(RGBColor{ 149, 167, 8 }, 25829);
  70. addColor(RGBColor{ 196, 29, 159 }, 26548);
  71. addColor(RGBColor{ 128, 26, 20 }, 27275);
  72. addColor(RGBColor{ 69, 49, 66 }, 28010);
  73. addColor(RGBColor{ 12, 42, 198 }, 28753);
  74. addColor(RGBColor{ 61, 62, 36 }, 29504);
  75. addColor(RGBColor{ 27, 94, 114 }, 30263);
  76. addColor(RGBColor{ 54, 218, 7 }, 31030);
  77. addColor(RGBColor{ 105, 89, 170 }, 31804);
  78. addColor(RGBColor{ 100, 110, 2 }, 32586);
  79. addColor(RGBColor{ 208, 198, 148 }, 33376);
  80. addColor(RGBColor{ 80, 208, 131 }, 34174);
  81. addColor(RGBColor{ 176, 89, 59 }, 34980);
  82. addColor(RGBColor{ 255, 64, 243 }, 35793);
  83. addColor(RGBColor{ 39, 226, 232 }, 36614);
  84. addColor(RGBColor{ 154, 100, 238 }, 37443);
  85. addColor(RGBColor{ 53, 103, 192 }, 38279);
  86. addColor(RGBColor{ 187, 41, 136 }, 39123);
  87. addColor(RGBColor{ 33, 84, 227 }, 39974);
  88. addColor(RGBColor{ 71, 167, 211 }, 40833);
  89. addColor(RGBColor{ 55, 191, 255 }, 41699);
  90. addColor(RGBColor{ 60, 165, 201 }, 42573);
  91. addColor(RGBColor{ 231, 206, 192 }, 43454);
  92. addColor(RGBColor{ 233, 224, 197 }, 44343);
  93. addColor(RGBColor{ 255, 129, 13 }, 45239);
  94. addColor(RGBColor{ 131, 222, 95 }, 46143);
  95. addColor(RGBColor{ 155, 249, 72 }, 47054);
  96. addColor(RGBColor{ 248, 129, 30 }, 47972);
  97. addColor(RGBColor{ 48, 239, 206 }, 48898);
  98. addColor(RGBColor{ 176, 224, 64 }, 49831);
  99. addColor(RGBColor{ 155, 12, 162 }, 50771);
  100. addColor(RGBColor{ 6, 144, 149 }, 51718);
  101. addColor(RGBColor{ 231, 208, 16 }, 52672);
  102. addColor(RGBColor{ 190, 66, 231 }, 53634);
  103. addColor(RGBColor{ 19, 17, 253 }, 54603);
  104. addColor(RGBColor{ 4, 34, 60 }, 55579);
  105. addColor(RGBColor{ 101, 23, 88 }, 56562);
  106. addColor(RGBColor{ 9, 191, 235 }, 57552);
  107. max = 10000;
  108. //addColor(RGBColor{255, 0, 255}, 1000000000.0f);
  109. }
  110. */
  111. Gradient::Gradient(void) :
  112. max{ 1.0 }
  113. {
  114. }
  115. Gradient::Gradient(const std::vector<std::pair<RGBColor, float>>& colors, int precalcSteps)
  116. {
  117. if(colors.empty())
  118. return;
  119. /*std::sort(colors.begin(), colors.end(),
  120. [] (const std::pair<RGBColor, float>& a, const std::pair<RGBColor, float>& b) {
  121. return a.second < b.second;
  122. });*/
  123. max = colors.at(colors.size() - 1).second;
  124. for (int i = 0; i < precalcSteps; i++) {
  125. float position = i * max / precalcSteps;
  126. RGBColor left = RGBColor{ 0, 0, 0 };
  127. RGBColor right = RGBColor{ 0, 0, 0 };
  128. float lerp = 0.0f;
  129. RGBColor atPosition = RGBColor{ 0, 0, 0 };
  130. // slow, but not in any critical path
  131. for (auto it = colors.begin(); it != colors.end(); ++it) {
  132. if (it->second > position) {
  133. if (it == colors.begin()) {
  134. atPosition = it->first;
  135. break;
  136. }
  137. else {
  138. float lerp = (position - (it - 1)->second) / (it->second - (it - 1)->second);
  139. atPosition = lerpColors((it - 1)->first, it->first, lerp);
  140. break;
  141. }
  142. }
  143. }
  144. this->colors.push_back(atPosition);
  145. }
  146. }
  147. Gradient Gradient::defaultGradient(void)
  148. {
  149. std::vector<std::pair<RGBColor, float>> colors = {
  150. { RGBColor{0, 0, 0}, 0 },
  151. { RGBColor{ 250, 70, 24 }, 40 },
  152. { RGBColor{ 200, 230, 30 }, 104 },
  153. { RGBColor{ 70, 223, 30 }, 190 },
  154. { RGBColor{ 14, 20, 150 }, 295 },
  155. { RGBColor{ 36, 155, 169 }, 418 },
  156. { RGBColor{ 233, 33, 79 }, 558 },
  157. { RGBColor{ 254, 169, 63 }, 714 },
  158. { RGBColor{ 227, 93, 201 }, 885 },
  159. { RGBColor{ 188, 24, 161 }, 1071 },
  160. { RGBColor{ 45, 225, 44 }, 1271 },
  161. { RGBColor{ 52, 58, 250 }, 1485 },
  162. { RGBColor{ 87, 93, 241 }, 1712 },
  163. { RGBColor{ 6, 37, 208 }, 1952 },
  164. { RGBColor{ 193, 164, 162 }, 2205 },
  165. { RGBColor{ 49, 8, 90 }, 2471 },
  166. { RGBColor{ 124, 149, 120 }, 2749 },
  167. { RGBColor{ 56, 69, 6 }, 3039 },
  168. { RGBColor{ 231, 177, 252 }, 3341 },
  169. { RGBColor{ 36, 76, 95 }, 3655 },
  170. { RGBColor{ 1, 99, 184 }, 3980 },
  171. { RGBColor{ 74, 223, 199 }, 4316 },
  172. { RGBColor{ 249, 125, 31 }, 4664 },
  173. { RGBColor{ 28, 93, 214 }, 5023 },
  174. { RGBColor{ 232, 117, 145 }, 5393 },
  175. { RGBColor{ 208, 158, 49 }, 5773 },
  176. { RGBColor{ 218, 109, 177 }, 6164 },
  177. { RGBColor{ 139, 83, 177 }, 6565 },
  178. { RGBColor{ 16, 36, 59 }, 6977 },
  179. { RGBColor{ 194, 157, 26 }, 7399 },
  180. { RGBColor{ 77, 236, 12 }, 7831 },
  181. { RGBColor{ 124, 244, 151 }, 8273 },
  182. { RGBColor{ 128, 195, 162 }, 8725 },
  183. { RGBColor{ 66, 36, 194 }, 9187 },
  184. { RGBColor{ 81, 151, 185 }, 9659 },
  185. { RGBColor{ 173, 75, 175 }, 10140 },
  186. { RGBColor{ 43, 182, 52 }, 10631 },
  187. { RGBColor{ 14, 242, 141 }, 11131 },
  188. { RGBColor{ 156, 203, 87 }, 11641 },
  189. { RGBColor{ 147, 89, 150 }, 12160 },
  190. { RGBColor{ 213, 199, 183 }, 12689 },
  191. { RGBColor{ 186, 255, 52 }, 13227 },
  192. { RGBColor{ 28, 158, 154 }, 13774 },
  193. { RGBColor{ 5, 5, 116 }, 14330 },
  194. { RGBColor{ 126, 123, 232 }, 14895 },
  195. { RGBColor{ 43, 162, 251 }, 15469 },
  196. { RGBColor{ 198, 143, 125 }, 16052 },
  197. { RGBColor{ 201, 157, 178 }, 16644 },
  198. { RGBColor{ 213, 151, 189 }, 17245 },
  199. { RGBColor{ 188, 117, 169 }, 17854 },
  200. { RGBColor{ 156, 189, 249 }, 18472 },
  201. { RGBColor{ 62, 23, 33 }, 19099 },
  202. { RGBColor{ 167, 205, 74 }, 19734 },
  203. { RGBColor{ 161, 181, 210 }, 20378 },
  204. { RGBColor{ 179, 167, 215 }, 21030 },
  205. { RGBColor{ 204, 102, 126 }, 21691 },
  206. { RGBColor{ 123, 49, 127 }, 22360 },
  207. { RGBColor{ 178, 48, 136 }, 23037 },
  208. { RGBColor{ 108, 112, 99 }, 23723 },
  209. { RGBColor{ 250, 152, 78 }, 24417 },
  210. { RGBColor{ 79, 167, 196 }, 25119 },
  211. { RGBColor{ 149, 167, 8 }, 25829 },
  212. { RGBColor{ 196, 29, 159 }, 26548 },
  213. { RGBColor{ 128, 26, 20 }, 27275 },
  214. { RGBColor{ 69, 49, 66 }, 28010 },
  215. { RGBColor{ 12, 42, 198 }, 28753 },
  216. { RGBColor{ 61, 62, 36 }, 29504 },
  217. { RGBColor{ 27, 94, 114 }, 30263 },
  218. { RGBColor{ 54, 218, 7 }, 31030 },
  219. { RGBColor{ 105, 89, 170 }, 31804 },
  220. { RGBColor{ 100, 110, 2 }, 32586 },
  221. { RGBColor{ 208, 198, 148 }, 33376 },
  222. { RGBColor{ 80, 208, 131 }, 34174 },
  223. { RGBColor{ 176, 89, 59 }, 34980 },
  224. { RGBColor{ 255, 64, 243 }, 35793 },
  225. { RGBColor{ 39, 226, 232 }, 36614 },
  226. { RGBColor{ 154, 100, 238 }, 37443 },
  227. { RGBColor{ 53, 103, 192 }, 38279 },
  228. { RGBColor{ 187, 41, 136 }, 39123 },
  229. { RGBColor{ 33, 84, 227 }, 39974 },
  230. { RGBColor{ 71, 167, 211 }, 40833 },
  231. { RGBColor{ 55, 191, 255 }, 41699 },
  232. { RGBColor{ 60, 165, 201 }, 42573 },
  233. { RGBColor{ 231, 206, 192 }, 43454 },
  234. { RGBColor{ 233, 224, 197 }, 44343 },
  235. { RGBColor{ 255, 129, 13 }, 45239 },
  236. { RGBColor{ 131, 222, 95 }, 46143 },
  237. { RGBColor{ 155, 249, 72 }, 47054 },
  238. { RGBColor{ 248, 129, 30 }, 47972 },
  239. { RGBColor{ 48, 239, 206 }, 48898 },
  240. { RGBColor{ 176, 224, 64 }, 49831 },
  241. { RGBColor{ 155, 12, 162 }, 50771 },
  242. { RGBColor{ 6, 144, 149 }, 51718 },
  243. { RGBColor{ 231, 208, 16 }, 52672 },
  244. { RGBColor{ 190, 66, 231 }, 53634 },
  245. { RGBColor{ 19, 17, 253 }, 54603 },
  246. { RGBColor{ 4, 34, 60 }, 55579 },
  247. { RGBColor{ 101, 23, 88 }, 56562 },
  248. { RGBColor{ 9, 191, 235 }, 57552 }
  249. };
  250. return Gradient{ colors };
  251. }
  252. RGBColor Gradient::get(float x) const
  253. {
  254. if (colors.empty())
  255. return RGBColor();
  256. /*const auto [left, right, lerp] = getNeighbors(x);
  257. RGBColor lerped = lerpColors(left, right, lerp);
  258. return lerped;*/
  259. float pos = x * colors.size() / max;
  260. if (pos < 0) {
  261. pos = 0;
  262. }
  263. if (pos > colors.size() - 1) {
  264. pos = colors.size() - 1;
  265. }
  266. int left = int(pos);
  267. int right = int(pos + 1);
  268. float lerp = pos - left;
  269. if (lerp < 1e-5) {
  270. return colors.at(left);
  271. }
  272. else {
  273. return lerpColors(colors.at(left), colors.at(right), lerp);
  274. }
  275. }
  276. RGBColor Gradient::lerpColors(RGBColor a, RGBColor b, float val)
  277. {
  278. auto mklin = [] (double x) {
  279. return x * x;//::pow(x, 2.4);
  280. };
  281. auto unlin = [] (double x) {
  282. return ::sqrt(x);// ::pow(x, 1.0 / 2.4);
  283. };
  284. return RGBColor{
  285. uint8_t(unlin(mklin(b.r) * val + mklin(a.r) * (1 - val))),
  286. uint8_t(unlin(mklin(b.g) * val + mklin(a.g) * (1 - val))),
  287. uint8_t(unlin(mklin(b.b) * val + mklin(a.b) * (1 - val)))
  288. };
  289. }
  290. /*std::tuple<RGBColor, RGBColor, float> Gradient::getNeighbors(float x) const
  291. {
  292. for (auto it = colors.begin(); it != colors.end(); ++it) {
  293. if (it->second > x) {
  294. if (it == colors.begin()) {
  295. return { it->first, it->first, 0 };
  296. }
  297. else {
  298. float lerp = (x - (it - 1)->second) / (it->second - (it - 1)->second);
  299. return { (it - 1)->first, it->first, lerp };
  300. }
  301. }
  302. }
  303. return { (colors.end() - 1)->first, (colors.end() - 1)->first, 0 };
  304. }*/