Advertisement
Guest User

Untitled

a guest
Jan 18th, 2020
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.75 KB | None | 0 0
  1. #define OLC_PGE_APPLICATION
  2. #include "olcPixelGameEngine.h"
  3. #include <vector>
  4. #include <iostream>
  5. #include <cmath>
  6.  
  7. #define p(X) std::cout << #X << " = " << X << std::endl;
  8.  
  9. struct vec2d {
  10. float x, y;
  11. float length() const {
  12. return std::sqrt(x * x + y * y);
  13. }
  14. vec2d norm() const {
  15. float l = this->length();
  16. return vec2d{this->x/l,this->y/l};
  17. }
  18. vec2d& operator+=(vec2d const& o) {
  19. x += o.x;
  20. y += o.y;
  21. return *this;
  22. }
  23. vec2d operator +(vec2d const & o) const {
  24. return vec2d{ this->x + o.x,this->y + o.y};
  25. }
  26. vec2d& operator-=(vec2d const& o) {
  27. x -= o.x;
  28. y -= o.y;
  29. return *this;
  30. }
  31. vec2d operator -(vec2d const& o) const {
  32. return vec2d{ this->x - o.x,this->y - o.y };
  33. }
  34. vec2d operator*(float fac) const {
  35. return vec2d{ this->x * fac,this->y * fac };
  36. }
  37. vec2d& operator*=(float fac) {
  38. this->x* fac; this->y * fac;
  39. return *this;
  40. }
  41. vec2d operator/(float fac) const {
  42. return vec2d{ this->x / fac,this->y / fac };
  43. }
  44. vec2d& operator/=(float fac) {
  45. this->x / fac; this->y / fac;
  46. return *this;
  47. }
  48. bool operator==(vec2d const & o) const {
  49. return std::abs(this->x-o.x) < 0.0001f && std::abs(this->y - o.y) < 0.0001f;
  50. }
  51. vec2d getInLength(float l) {
  52. return (this->norm()*l);
  53. }
  54. vec2d To(vec2d to) const {
  55. return vec2d{to.x - this->x, to.y - this->y};
  56. }
  57. vec2d rotated90() const {
  58. return vec2d{ this->y,-this->x };
  59. }
  60. };
  61. struct blob {
  62. vec2d pos;
  63. vec2d vel;
  64. vec2d acc;
  65. std::vector<blob*> pointsAt;
  66. };
  67.  
  68. std::ostream& operator<<(std::ostream& os, vec2d const& v) {
  69. return os << '<' << v.x << ',' << v.y << '>';
  70. }
  71. std::ostream& operator<<(std::ostream& os, blob const& b) {
  72. return os << "blob{" << b.pos << ' ' << b.vel << ' ' << b.pointsAt.size() << '}';
  73. }
  74. template <typename T>
  75. std::ostream& operator<<(std::ostream& os, std::vector<T> const& v) {
  76. os << "[ ";
  77. for (T e : v) {
  78. os << e << ' ';
  79. }
  80. return os << "]";
  81. }
  82.  
  83.  
  84. class Example : public olc::PixelGameEngine
  85. {
  86. public:
  87. Example()
  88. {
  89. sAppName = "Example";
  90. }
  91.  
  92. public:
  93. float randf(float low = 0, float high = 1) {
  94. return low + static_cast <float> (rand()) / (static_cast <float> (RAND_MAX / (high - low)));
  95. }
  96. vec2d randPos() {
  97. return vec2d{randf(),randf()};
  98. }
  99. float lerp(float a, float b, float t)
  100. {
  101. return a + t * (b - a);
  102. }
  103. float linearConversion(float ifrom, float ito, float v, float ofrom, float oto) {
  104. float t = (v - ifrom) / (ito - ifrom);
  105. return lerp(ofrom, oto,t);
  106. }
  107. void DrawArrow(vec2d from, vec2d to, olc::Pixel color) {
  108. if (from == to) return;
  109.  
  110. DrawLine(from.x, from.y, to.x, to.y, color);
  111.  
  112. vec2d vec = from.To(to);
  113.  
  114. to = from + vec.getInLength(vec.length() - 3);
  115. vec = from.To(to);
  116.  
  117. vec2d tipStartPos = from + vec.getInLength(vec.length() - 5); // go back 10 pixels
  118.  
  119. float tipW = 3;
  120. vec2d p1 = tipStartPos + vec.rotated90().getInLength(tipW);
  121. vec2d p2 = tipStartPos + vec.rotated90().getInLength(-tipW);
  122.  
  123. //FillTriangle(p1.x,p1.y,p2.x,p2.y,to.x, to.y, color);
  124. }
  125.  
  126. std::vector<blob> blobs;
  127. std::vector<vec2d> blobPosCache;
  128. bool OnUserCreate() override
  129. {
  130. //p(linearConversion(-16342.5, -16342.5, maxX, 0, ScreenWidth() - 1))
  131.  
  132. const int blobcnt = 5;
  133.  
  134. blobs = std::vector<blob>(blobcnt);
  135. blobPosCache = std::vector<vec2d>(blobcnt);
  136.  
  137.  
  138. for (int i = 0; i < blobcnt; i++) {
  139. //blobs[i] = blob{{randf(),randf()},{randf(),randf()} };
  140. blobs[i] = blob{ {randf(-5000,5000),randf(-5000,5000)}};
  141. int to = rand() % 2;
  142. for (int j = 0; j < to; j++) {
  143. blobs[i].pointsAt.push_back(&(blobs[rand() % blobcnt]));
  144. }
  145. }
  146.  
  147. /*
  148. blobs = std::vector<blob>(2);
  149. blobPosCache = std::vector<vec2d>(2);
  150. blobs[0] = blob{ {randf(),randf()}};
  151. blobs[1] = blob{ {randf(),randf()}};
  152. blobs[0].pointsAt.push_back(&(blobs[1]));
  153. */
  154. //blobs[0].pointsAt.push_back(&(blobs[rand() % blobcnt]));
  155.  
  156. for (int x = 0; x < ScreenWidth(); x++)
  157. for (int y = 0; y < ScreenHeight(); y++)
  158. Draw(x, y, olc::WHITE);
  159. //p(blobs)
  160. return true;
  161. }
  162.  
  163. bool OnUserUpdate(float fElapsedTime) override
  164. {
  165. //p(fElapsedTime);
  166. for (int x = 0; x < ScreenWidth(); x++)
  167. for (int y = 0; y < ScreenHeight(); y++)
  168. Draw(x, y, olc::WHITE);
  169.  
  170. //std::cout << blobs << std::endl;
  171. //dont show every simulation step
  172. static int speed = 1;
  173.  
  174. speed += GetMouseWheel()/120;
  175. speed = std::abs(speed);
  176. if (GetMouseWheel() != 0)
  177. std::cout << speed << std::endl;
  178. for (int i = 0; i < speed; i++) {
  179. for (blob& b : blobs) {
  180. b.pos += b.vel * fElapsedTime;
  181. b.vel += (b.acc + b.vel * -0.8) * fElapsedTime;
  182. b.acc = vec2d{ 0,0 };
  183. }
  184. for (blob& b : blobs) {
  185. for (blob* bp : b.pointsAt) {
  186. vec2d to = b.pos.To(bp->pos);
  187. to *= .1;
  188. b.acc += to;
  189. bp->acc += to * -.1;
  190. }
  191. for (blob& ob : blobs) {
  192. if (&ob == &b) continue;
  193. if (std::find(b.pointsAt.begin(), b.pointsAt.end(), &ob) != b.pointsAt.end()) continue;
  194. vec2d to = b.pos.To(ob.pos);
  195. if (to.length() < 3000) {
  196. to = to.getInLength(1000);
  197. b.acc += to * -1;
  198. }
  199. }
  200. //b.acc += b.pos.getInLength(b.pos.length()*b.pos.length()) * -0.000001;
  201. }
  202. }
  203.  
  204. //draw everything
  205.  
  206. float maxX = max_element(std::begin(blobs), std::end(blobs), [](blob const& a, blob const& b) -> bool {return a.pos.x < b.pos.x; })->pos.x;
  207. float minX = min_element(std::begin(blobs), std::end(blobs), [](blob const& a, blob const& b) -> bool {return a.pos.x < b.pos.x; })->pos.x;
  208. float maxY = max_element(std::begin(blobs), std::end(blobs), [](blob const& a, blob const& b) -> bool {return a.pos.y < b.pos.y; })->pos.y;
  209. float minY = min_element(std::begin(blobs), std::end(blobs), [](blob const& a, blob const& b) -> bool {return a.pos.y < b.pos.y; })->pos.y;
  210.  
  211.  
  212. float xdelta = maxX - minX;
  213. float ydelta = maxY - minY;
  214. float delta;
  215. if (xdelta > ydelta) {
  216. float off = (xdelta - ydelta) / 2;
  217. minY -= off;
  218. maxY += off;
  219. delta = xdelta;
  220. } else {
  221. float off = (ydelta - xdelta) / 2;
  222. minX -= off;
  223. maxX += off;
  224. delta = xdelta;
  225. }
  226.  
  227.  
  228. for (int i = static_cast<int>(minX) / 500 * 500; i < maxX; i += 500) {
  229. float x = linearConversion(minX, maxX, i, 0, ScreenWidth());
  230. DrawLine(x, 0, x, ScreenHeight() - 1, olc::Pixel(200, 200, 200));
  231. }
  232. for (int i = static_cast<int>(minY) / 500 * 500; i < maxY; i += 500) {
  233. float y = linearConversion(minY, maxY, i, 0, ScreenHeight());
  234. DrawLine(0, y, ScreenWidth() - 1, y, olc::Pixel(200, 200, 200));
  235. }
  236.  
  237. float x = linearConversion(minX, maxX, 0, 0, ScreenWidth());
  238. DrawLine(x, 0, x, ScreenHeight() - 1, olc::Pixel(0, 0, 255));
  239. float y = linearConversion(minY, maxY, 0, 0, ScreenHeight());
  240. DrawLine(0, y, ScreenWidth() - 1, y, olc::Pixel(0, 0, 255));
  241.  
  242. for (int i = 0; i < blobs.size(); i++) {
  243. blob& const b = blobs[i];
  244. float pixelX = linearConversion(minX, maxX, b.pos.x, 10, ScreenWidth() - 10);
  245. float pixelY = linearConversion(minY, maxY, b.pos.y, 10, ScreenHeight() - 10);
  246. blobPosCache[i] = vec2d{ pixelX,pixelY };
  247. }
  248.  
  249. blob* pt2fst = &(blobs[0]);
  250.  
  251. for (int i = 0; i < blobs.size(); i++) {
  252. blob& const b = blobs[i];
  253. for (blob* bp : b.pointsAt) {
  254. unsigned bpi = bp - pt2fst;
  255. DrawArrow(blobPosCache[i],blobPosCache[bpi],olc::BLACK);
  256. }
  257. }
  258.  
  259. float radius = std::abs(linearConversion(minX, maxX, minX, 10, ScreenWidth() - 10) - linearConversion(minX, maxX, minX + 250, 10, ScreenWidth() - 10));
  260. for (vec2d pos : blobPosCache) {
  261. FillCircle(pos.x, pos.y, radius, olc::RED);
  262. }
  263.  
  264. DrawString(ScreenWidth() - 100,ScreenHeight()-30, std::to_string(maxX),olc::BLACK);
  265. DrawString(30, ScreenHeight() - 30, std::to_string(minX), olc::BLACK);
  266.  
  267. return true;
  268. }
  269. };
  270.  
  271.  
  272.  
  273. int main()
  274. {
  275. Example demo;
  276. if (demo.Construct(1000, 1000, 1, 1))
  277. demo.Start();
  278.  
  279. return 0;
  280. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement