Advertisement
999ms

Untitled

Dec 5th, 2019
248
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.54 KB | None | 0 0
  1. #include "Graphics.h"
  2. #include "StdAfx.h"
  3. #include "GF.h"
  4. #include <functional>
  5. #include <vector>
  6. #include <algorithm>
  7. #include <bitset>
  8. #include <cstdlib>
  9. #include <cstring>
  10. #include <string>
  11. #include <string.h>
  12. #include <random>
  13. #include <iostream>
  14.  
  15. #define all(x) (x).begin(),(x).end()
  16.  
  17. #ifndef M_PI
  18. const double M_PI = 3.1415926535897932384626433832795;
  19. #endif
  20.  
  21. const char CONVEX = 1;
  22. const char COMPLEX = 2;
  23. const char NONCONVEX = 3;
  24.  
  25. std::mt19937 rng(59);
  26.  
  27. class TPoint;
  28. void DrawLine(TPoint a, TPoint b, const RGBPIXEL& color);
  29. void DrawLine(int x0, int y0, int x1, int y1, const RGBPIXEL& color);
  30. bool Intersect(const TPoint& a, const TPoint& b, const TPoint& c, const TPoint& d);
  31. int SignArea(const TPoint& a, const TPoint& b, const TPoint& c);
  32.  
  33. class TPoint {
  34. public:
  35. int x, y;
  36. TPoint(int x = 0, int y = 0)
  37. : x(x)
  38. , y(y)
  39. {
  40. }
  41.  
  42. TPoint(const TPoint& a, const TPoint& b)
  43. : x(b.x - a.x)
  44. , y(b.y - a.y)
  45. {
  46. }
  47.  
  48. double Length() {
  49. return hypot(x, y);
  50. }
  51.  
  52. TPoint operator + (const TPoint& o) {
  53. return TPoint(x + o.x, y + o.y);
  54. }
  55.  
  56. TPoint operator - (const TPoint& o) {
  57. return TPoint(x - o.x, y - o.y);
  58. }
  59.  
  60. private:
  61.  
  62. };
  63.  
  64. class TPolygon {
  65. public:
  66. TPolygon(int n)
  67. : n(n)
  68. , p(std::vector<TPoint>(n))
  69. {
  70. }
  71.  
  72. void SetRandomPoint(int index, int w, int h) {
  73. if (index >= 0 && index < n) {
  74. p[index].x = rng() % w;
  75. p[index].y = rng() % h;
  76. }
  77. }
  78.  
  79. void SetRandom(int w, int h) {
  80. for (int i = 0; i < n; i++) {
  81. SetRandomPoint(i, w, h);
  82. }
  83. }
  84.  
  85. void Draw(const RGBPIXEL& color) {
  86. for (int i = 0; i < n; i++) {
  87. DrawLine(p[i].x, p[i].y, p[(i + 1) % n].x, p[(i + 1) % n].y, color);
  88. }
  89. }
  90.  
  91. // should be with multithreading
  92. void Fill(TPoint minPoint, TPoint maxPoint, RGBPIXEL color, const std::function<bool(TPoint)>& f) {
  93. for (int x = minPoint.x; x <= maxPoint.x; x++) {
  94. for (int y = minPoint.y; y <= maxPoint.y; y++) {
  95. if (f({x, y})) {
  96. gfSetPixel(x, y, color);
  97. }
  98. }
  99. }
  100. }
  101.  
  102. int Size() const {
  103. return n;
  104. }
  105.  
  106. TPoint& operator [] (int i) {
  107. i %= n;
  108. if (i < 0) i += n;
  109. return p[i];
  110. };
  111.  
  112. TPoint* begin() {
  113. return &p[0];
  114. }
  115.  
  116. TPoint* end() {
  117. return std::next(&p.back());
  118. }
  119.  
  120. bool IsComplex() {
  121. if (n <= 3) {
  122. return false;
  123. }
  124. for (int i = 0; i < n; i++) {
  125. for (int j = i + 2; j < n; j++) {
  126. if (j == n - 1 && i == 0) continue;
  127. if (Intersect(p[i], p[i + 1], p[j], p[j + 1])) {
  128. return true;
  129. }
  130. }
  131. }
  132. return false;
  133. }
  134.  
  135. bool IsConvex() {
  136. if (n <= 3) {
  137. return true;
  138. }
  139. if (IsComplex()) {
  140. return false;
  141. }
  142. int pos = 0;
  143. int neg = 0;
  144. for (int i = 0; i < n; i++) {
  145. const int s = SignArea(p[i - 1 + n], p[i], p[i + 1]);
  146. if (s > 0) {
  147. pos++;
  148. }
  149. if (s < 0) {
  150. neg++;
  151. }
  152. if (pos > 0 && neg > 0) {
  153. return false;
  154. }
  155. }
  156. if (pos > 0 && neg > 0) {
  157. return false;
  158. }
  159. return true;
  160. }
  161.  
  162. char Classify() {
  163. if (IsConvex()) {
  164. return CONVEX;
  165. } else if (IsComplex()) {
  166. return COMPLEX;
  167. } else {
  168. return NONCONVEX;
  169. }
  170. }
  171.  
  172. private:
  173. int n;
  174. std::vector<TPoint> p;
  175. };
  176.  
  177. void DrawLine(int x0, int y0, int x1, int y1, const RGBPIXEL& color) {
  178. const int deltaX = abs(x0 - x1);
  179. const int deltaY = abs(y0 - y1);
  180. const int signX = x0 < x1 ? 1 : -1;
  181. const int signY = y0 < y1 ? 1 : -1;
  182. int d = deltaX - deltaY;
  183. gfSetPixel(x1, y1, color);
  184. while (x0 != x1 || y0 != y1) {
  185. gfSetPixel(x0, y0, color);
  186. const int d2 = d << 1;
  187. if (d2 > -deltaY) { // d > -dy / 2
  188. d -= deltaY;
  189. x0 += signX;
  190. }
  191. if (d2 < deltaX) {
  192. d += deltaX;
  193. y0 += signY;
  194. }
  195. }
  196. }
  197.  
  198. void DrawLine(TPoint a, TPoint b, const RGBPIXEL& color) {
  199. DrawLine(a.x, a.y, b.x, b.y, color);
  200. }
  201.  
  202. inline bool cw (const TPoint& a, const TPoint& b, const TPoint& c) { // clockwise
  203. return a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y) < 0;
  204. }
  205.  
  206. int sign(int a) {
  207. if (a > 0) return 1;
  208. if (a < 0) return -1;
  209. return 0;
  210. }
  211.  
  212. inline int SignArea (const TPoint& a, const TPoint& b, const TPoint& c) {
  213. return sign((b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x));
  214. }
  215.  
  216. inline int Area (const TPoint& a, const TPoint& b) {
  217. return a.x * b.y - a.y * b.x;
  218. }
  219.  
  220. inline bool Intersect_1 (int a, int b, int c, int d) {
  221. if (a > b) std::swap (a, b);
  222. if (c > d) std::swap (c, d);
  223. return max(a,c) <= min(b,d);
  224. }
  225.  
  226. bool Intersect (const TPoint& a, const TPoint& b, const TPoint& c, const TPoint& d) {
  227. return Intersect_1 (a.x, b.x, c.x, d.x)
  228. && Intersect_1 (a.y, b.y, c.y, d.y)
  229. && SignArea(a,b,c) * SignArea(a,b,d) <= 0
  230. && SignArea(c,d,a) * SignArea(c,d,b) <= 0;
  231. }
  232.  
  233. inline RGBPIXEL RandColor() {
  234. return RGBPIXEL(rand() % 256, rand() % 256, rand() % 256);
  235. }
  236.  
  237. bool PointInPolygonWithEvenOddRule(TPolygon& p, const TPoint& a) {
  238. bool counter = 0;
  239. const int inf = 2000;
  240. TPoint b = { a.x, a.y - inf };
  241. bool pre = false;
  242. bool cur = false;
  243. const int n = p.Size();
  244. for (int i = 0; i < n; i++) {
  245. cur = Intersect(p[i], p[(i + 1) % n], a, b);
  246. if (cur && pre && p[i].x == a.x) {
  247. if ((p[(i - 1 + n) % n].x > a.x) ^ (p[(i + 1) % n].x > a.x)) {
  248. continue;
  249. }
  250. }
  251. counter ^= cur;
  252. pre = cur;
  253. }
  254. return counter;
  255. }
  256.  
  257. bool PointInPolygonWithNonZeroWindingRule(TPolygon& p, const TPoint& a) {
  258. int counter = 0;
  259. const int inf = 2000;
  260. TPoint b = { a.x, a.y - inf };
  261. bool pref = false;
  262. bool cur = false;
  263. const int n = p.Size();
  264. for (int i = 0; i < n; i++) {
  265. if (cur = Intersect(p[i], p[(i + 1) % n], a, b)) {
  266. if (cur && pref && p[i].x == a.x) {
  267. if ((p[(i - 1 + n) % n].x > a.x) ^ (p[(i + 1) % n].x > a.x)) {
  268. continue;
  269. }
  270. }
  271. if (SignArea(p[i], p[(i + 1) % n], a) >= 0) {
  272. counter++;
  273. } else {
  274. counter--;
  275. }
  276. }
  277. pref = cur;
  278. }
  279. return counter;
  280. }
  281.  
  282. const TCHAR* GetTextForDraw(const std::string s) {
  283. char* answer = new char[s.size() + 1];
  284. for (int i = 0; i < s.size(); i++) {
  285. answer[i] = s[i];
  286. }
  287. answer[s.size()] = '\0';
  288. return answer;
  289. }
  290.  
  291. template<typename T>
  292. const TCHAR* GetTextForDraw(const T& value) {
  293. return GetTextForDraw(std::to_string(value));
  294. }
  295.  
  296. std::pair<TPoint, TPoint> MinMaxBorders(TPolygon& polygon) {
  297. const int inf = 1 << 30;
  298. TPoint minPoint = {inf, inf};
  299. TPoint maxPoint = {-inf, -inf};
  300. for (const auto& p : polygon) {
  301. minPoint.x = min(minPoint.x, p.x);
  302. minPoint.y = min(minPoint.y, p.y);
  303. maxPoint.x = max(maxPoint.x, p.x);
  304. maxPoint.y = max(maxPoint.y, p.y);
  305. }
  306. return {minPoint, maxPoint};
  307. }
  308.  
  309. long long DistQrt(const TPoint& a, const TPoint& b) {
  310. return static_cast<long long>(a.x - b.x) * (a.x - b.x) + static_cast<long long>(a.y - b.y) * (a.y - b.y);
  311. }
  312.  
  313. long long C(int n, int m) {
  314. long long answer = 1;
  315. for (int i = n - m + 1; i <= n; i++) {
  316. answer *= i;
  317. }
  318. for (int i = 1; i <= m; i++) {
  319. answer /= i;
  320. }
  321. return answer;
  322. }
  323.  
  324. using namespace std;
  325.  
  326. void DrawBezierLine (std::vector<TPoint>& arr, const RGBPIXEL& color) {
  327. const int n = arr.size();
  328. if (n <= 2) {
  329. DrawLine(arr[0], arr.back(), color);
  330. return;
  331. }
  332. auto dist = [&] (const TPoint& a) {
  333. return abs(a.x) + abs(a.y);
  334. };
  335. long long D = 0;
  336. for (int i = 2; i < n; i++) {
  337. D = max(D, dist(arr[i - 2] - arr[i - 1] - arr[i - 1] + arr[i]));
  338. }
  339. double N = 1 + sqrt(3 * D);
  340. double dt = 1 / N;
  341. auto R = [&] (double t) {
  342. double x = 0;
  343. double y = 0;
  344. for (int i = 0; i < n; i++) {
  345. double k = C(n, i) * pow(t, i) * pow(1 - t, n - i);
  346. x += arr[i].x * k;
  347. y += arr[i].y * k;
  348.  
  349. }
  350. return TPoint(x + 0.5, y + 0.5);
  351. };
  352. cout << "here" << endl;
  353. std::vector<TPoint> a;
  354. for (double t = 0; t < 1; t += dt) {
  355. a.push_back(R(t));
  356. }
  357. for (int i = 1; i < a.size(); i++) {
  358. DrawLine(a[i - 1], a[i], color);
  359. }
  360. }
  361.  
  362. /*
  363. de Kasteljo
  364. */
  365. void DrawBezierLine2(std::vector<TPoint>& arr, const RGBPIXEL& color) {
  366. const int n = arr.size();
  367. if (n <= 2) {
  368. DrawLine(arr[0], arr.back(), color);
  369. return;
  370. }
  371. const int bits = 5;
  372. const int size = 1 << bits;
  373. const int halfsize = 1 << (bits - 1);
  374. std::function<TPoint(const TPoint&, const TPoint&, int)> get = [&] (const TPoint& a, const TPoint& b, int pr) {
  375. return TPoint(a.x + (pr * (b.x - a.x) + halfsize >> bits), a.y + (pr * (b.y - a.y) + halfsize >> bits));
  376. };
  377.  
  378. std::function<TPoint(std::vector<TPoint>, int)> findPoint = [&] (std::vector<TPoint> a, int pr) {
  379. if (a.size() <= 2) {
  380. return get(a[0], a.back(), pr);
  381. } else {
  382. for (int i = 0; i + 1 < a.size(); i++) {
  383. a[i] = get(a[i], a[i + 1], pr);
  384. }
  385. a.pop_back();
  386. return findPoint(a, pr);
  387. }
  388. };
  389.  
  390. std::vector<TPoint> result;
  391.  
  392. for (int t = 0; t <= size; t++) {
  393. result.push_back(findPoint(arr, t));
  394. }
  395. for (int i = 0; i + 1 < result.size(); i++) {
  396. DrawLine(result[i], result[i + 1], color);
  397. }
  398.  
  399. }
  400.  
  401. bool gfInitScene() {
  402. try {
  403. const int WINDOW_SIZE = 800;
  404. gfSetWindowSize(WINDOW_SIZE, WINDOW_SIZE);
  405. const int n = 5;
  406. TPolygon arr(n);
  407. arr.SetRandom(WINDOW_SIZE, WINDOW_SIZE);
  408. std::vector<TPoint> kek;
  409. for (int i = 0; i < n; i++) {
  410. kek.push_back(arr[i]);
  411. }
  412. arr.Draw(RGBPIXEL::Yellow());
  413. DrawBezierLine(kek, RGBPIXEL::Green());
  414. DrawBezierLine2(kek, RGBPIXEL::White());
  415. } catch (...) {
  416. return false;
  417. }
  418. return true;
  419. }
  420.  
  421. void gfDrawScene()
  422. {
  423. //gfClearScreen(RGBPIXEL::Black());
  424. //int x = gfGetMouseX(), y = gfGetMouseY();
  425. //gfDrawRectangle(x - 10, y - 10, x + 10, y + 10, RGBPIXEL::Green());
  426. }
  427.  
  428. void gfCleanupScene()
  429. {
  430.  
  431. }
  432.  
  433. void gfOnLMouseClick( int x, int y )
  434. {
  435.  
  436. }
  437.  
  438. void gfOnRMouseClick( int x, int y )
  439. {
  440. }
  441.  
  442. void gfOnKeyDown( UINT key ) {
  443.  
  444. }
  445.  
  446. void gfOnKeyUp( UINT key )
  447. {
  448. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement