Advertisement
999ms

lab 1, 2, 3

Dec 11th, 2019
396
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 20.31 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(39);
  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.     bool operator < (const TPoint& o) {
  61.         return x < o.x || x == o.x && y < o.y;
  62.     }
  63.  
  64.     bool operator == (const TPoint& o) {
  65.         return x == o.x && y == o.y;
  66.     }
  67.  
  68.     bool operator != (const TPoint& o) {
  69.         return !(*this == o);
  70.     }
  71.  
  72. private:
  73.  
  74. };
  75.  
  76. class TPoint3D {
  77. public:
  78.     int x, y, z;
  79.     TPoint3D(int x = 0, int y = 0, int z = 0)
  80.         : x(x)
  81.         , y(y)
  82.         , z(z)
  83.     {
  84.     }
  85.  
  86.     TPoint3D(const TPoint3D& a, const TPoint3D& b)
  87.         : x(b.x - a.x)
  88.         , y(b.y - a.y)
  89.         , z(b.z - a.z)
  90.     {
  91.     }
  92.  
  93.     double Length() {
  94.         return std::sqrt(x * x + y * y + z * z);
  95.     }
  96.  
  97.     TPoint3D operator + (const TPoint3D& o) {
  98.         return TPoint3D(x + o.x, y + o.y, z + o.z);
  99.     }
  100.  
  101.     TPoint3D operator - (const TPoint3D& o) {
  102.         return TPoint3D(x - o.x, y - o.y, z - o.z);
  103.     }
  104.  
  105.     bool operator < (const TPoint3D& o) {
  106.         if (x != o.x) return x < o.x;
  107.         if (y != o.y) return y < o.y;
  108.         return z < o.z;
  109.     }
  110.  
  111.     bool operator == (const TPoint3D& o) {
  112.         return x == o.x && y == o.y && z == o.z;
  113.     }
  114.  
  115.     bool operator != (const TPoint3D& o) {
  116.         return !(*this == o);
  117.     }
  118. };
  119.  
  120. class TPolygon {
  121. public:
  122.     TPolygon(int n)
  123.         : n(n)
  124.         , p(std::vector<TPoint>(n))
  125.     {
  126.     }
  127.  
  128.     void SetRandomPoint(int index, int w, int h) {
  129.         if (index >= 0 && index < n) {
  130.             p[index].x = rng() % w;
  131.             p[index].y = rng() % h;
  132.         }
  133.     }
  134.  
  135.     void SetRandom(int w, int h) {
  136.         for (int i = 0; i < n; i++) {
  137.             SetRandomPoint(i, w, h);
  138.         }
  139.     }
  140.  
  141.     void Draw(const RGBPIXEL& color) {
  142.         for (int i = 0; i < n; i++) {
  143.             DrawLine(p[i].x, p[i].y, p[(i + 1) % n].x, p[(i + 1) % n].y, color);
  144.         }
  145.     }
  146.  
  147.     // should be with multithreading
  148.     void Fill(TPoint minPoint, TPoint maxPoint, RGBPIXEL color, const std::function<bool(TPoint)>& f) {
  149.         for (int x = minPoint.x; x <= maxPoint.x; x++) {
  150.             for (int y = minPoint.y; y <= maxPoint.y; y++) {
  151.                 if (f({ x, y })) {
  152.                     gfSetPixel(x, y, color);
  153.                 }
  154.             }
  155.         }
  156.     }
  157.  
  158.     int Size() const {
  159.         return n;
  160.     }
  161.  
  162.     TPoint& operator [] (int i) {
  163.         i %= n;
  164.         if (i < 0) i += n;
  165.         return p[i];
  166.     };
  167.  
  168.     TPoint* begin() {
  169.         return &p[0];
  170.     }
  171.  
  172.     TPoint* end() {
  173.         return std::next(&p.back());
  174.     }
  175.  
  176.     bool IsComplex() {
  177.         n = p.size();
  178.         if (n <= 3) {
  179.             return false;
  180.         }
  181.         for (int i = 0; i < n; i++) {
  182.             for (int j = i + 2; j < n; j++) {
  183.                 if (j == n - 1 && i == 0) continue;
  184.                 if (Intersect(p[i], p[(i + 1) % n], p[j], p[(j + 1) % n])) {
  185.                     return true;
  186.                 }
  187.             }
  188.         }
  189.         return false;
  190.     }
  191.  
  192.     bool IsConvex() {
  193.         n = p.size();
  194.         if (n <= 3) {
  195.             return true;
  196.         }
  197.         if (IsComplex()) {
  198.             return false;
  199.         }
  200.         int pos = 0;
  201.         int neg = 0;
  202.         for (int i = 0; i < n; i++) {
  203.             const int s = SignArea(p[(i - 1 + n) % n], p[i], p[(i + 1) % n]);
  204.             if (s > 0) {
  205.                 pos++;
  206.             }
  207.             if (s < 0) {
  208.                 neg++;
  209.             }
  210.             if (pos > 0 && neg > 0) {
  211.                 return false;
  212.             }
  213.         }
  214.         if (pos > 0 && neg > 0) {
  215.             return false;
  216.         }
  217.         return true;
  218.     }
  219.  
  220.     char Classify() {
  221.         if (IsConvex()) {
  222.             return CONVEX;
  223.         } else if (IsComplex()) {
  224.             return COMPLEX;
  225.         } else {
  226.             return NONCONVEX;
  227.         }
  228.     }
  229.  
  230.     void MakeConvex() {
  231.         sort(all(p));
  232.         auto cw = [&] (const TPoint & a, const TPoint & b) {
  233.             return a.x * b.y - a.y * b.x;
  234.         };
  235.         auto norm = [&] (const TPoint& a) {
  236.             return 1ll * a.x * a.x + 1ll * a.y * a.y;
  237.         };
  238.         p.erase(unique(all(p)), p.end());
  239.         sort(p.begin() + 1, p.end(), [&](TPoint& a, TPoint& b) {
  240.             long long val = cw(a - p[0], b - p[0]);
  241.             if (val != 0) return val < 0;
  242.             return norm(a - p[0]) < norm(b - p[0]);
  243.         });
  244.         const int n = p.size();
  245.         if (n <= 2) {
  246.             this->n = n;
  247.             return;
  248.         }
  249.         std::vector<TPoint> ans = { p[0], p[1] };
  250.         int sz = 2;
  251.         for (int i = 2; i < n; i++) {
  252.             while (sz >= 2 && cw(ans[sz - 1] - ans[sz - 2], p[i] - ans[sz - 1]) >= 0) {
  253.                 ans.pop_back();
  254.                 sz--;
  255.             }
  256.             sz++;
  257.             ans.push_back(p[i]);
  258.         }
  259.         while (sz >= 2 && cw(ans[sz - 1] - ans[sz - 2], ans[0] - ans[sz - 1]) >= 0) {
  260.             ans.pop_back();
  261.             sz--;
  262.         }
  263.         p = ans;
  264.         this->n = p.size();
  265.     }
  266.  
  267. private:
  268.     int n;
  269.     std::vector<TPoint> p;
  270. };
  271.  
  272. void DrawLine(int x0, int y0, int x1, int y1, const RGBPIXEL& color) {
  273.     const int deltaX = abs(x0 - x1);
  274.     const int deltaY = abs(y0 - y1);
  275.     const int signX = x0 < x1 ? 1 : -1;
  276.     const int signY = y0 < y1 ? 1 : -1;
  277.     int d = deltaX - deltaY;
  278.     gfSetPixel(x1, y1, color);
  279.     while (x0 != x1 || y0 != y1) {
  280.         gfSetPixel(x0, y0, color);
  281.         const int d2 = d << 1;
  282.         if (d2 > -deltaY) { // d > -dy / 2
  283.             d -= deltaY;
  284.             x0 += signX;
  285.         }
  286.         if (d2 < deltaX) {
  287.             d += deltaX;
  288.             y0 += signY;
  289.         }
  290.     }
  291. }
  292.  
  293. void DrawLine(TPoint a, TPoint b, const RGBPIXEL& color) {
  294.     DrawLine(a.x, a.y, b.x, b.y, color);
  295. }
  296.  
  297. inline bool cw(const TPoint& a, const TPoint& b, const TPoint& c) { // clockwise
  298.     return a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y) < 0;
  299. }
  300.  
  301. int sign(long long a) {
  302.     if (a > 0) return 1;
  303.     if (a < 0) return -1;
  304.     return 0;
  305. }
  306.  
  307. inline int SignArea(const TPoint& a, const TPoint& b, const TPoint& c) {
  308.     return sign(static_cast<long long>(b.x - a.x) * (c.y - a.y) - static_cast<long long>(b.y - a.y) * (c.x - a.x));
  309. }
  310.  
  311. inline int Area(const TPoint& a, const TPoint& b) {
  312.     return a.x * b.y - a.y * b.x;
  313. }
  314.  
  315. inline bool Intersect_1(int a, int b, int c, int d) {
  316.     if (a > b)  std::swap(a, b);
  317.     if (c > d)  std::swap(c, d);
  318.     return max(a, c) <= min(b, d);
  319. }
  320.  
  321. bool Intersect(const TPoint& a, const TPoint& b, const TPoint& c, const TPoint& d) {
  322.     return Intersect_1(a.x, b.x, c.x, d.x)
  323.         && Intersect_1(a.y, b.y, c.y, d.y)
  324.         && SignArea(a, b, c) * SignArea(a, b, d) <= 0
  325.         && SignArea(c, d, a) * SignArea(c, d, b) <= 0;
  326. }
  327.  
  328. inline RGBPIXEL RandColor() {
  329.     return RGBPIXEL(rand() % 256, rand() % 256, rand() % 256);
  330. }
  331.  
  332. bool PointInPolygonWithEvenOddRule(TPolygon& p, const TPoint& a) {
  333.     bool counter = 0;
  334.     const int inf = 2000;
  335.     TPoint b = { a.x, a.y - inf };
  336.     bool pre = false;
  337.     bool cur = false;
  338.     const int n = p.Size();
  339.     for (int i = 0; i < n; i++) {
  340.         cur = Intersect(p[i], p[(i + 1) % n], a, b);
  341.         if (cur && pre && p[i].x == a.x) {
  342.             if ((p[(i - 1 + n) % n].x > a.x) ^ (p[(i + 1) % n].x > a.x)) {
  343.                 continue;
  344.             }
  345.         }
  346.         counter ^= cur;
  347.         pre = cur;
  348.     }
  349.     return counter;
  350. }
  351.  
  352. bool PointInPolygonWithNonZeroWindingRule(TPolygon& p, const TPoint& a) {
  353.     int counter = 0;
  354.     const int inf = 9000;
  355.     TPoint b = { a.x, a.y + inf };
  356.     bool pref = false;
  357.     bool cur = false;
  358.     const int n = p.Size();
  359.     for (int i = 0; i < n; i++) {
  360.         if (cur = Intersect(p[i], p[(i + 1) % n], a, b)) {
  361.             if (cur && pref && p[i].x == a.x) {
  362.                 if ((p[(i - 1 + n) % n].x - a.x) * (p[(i + 1) % n].x - a.x) < 0) {
  363.                     continue;
  364.                 }
  365.             }
  366.             counter += SignArea(p[i], p[(i + 1) % n], a);
  367.         }
  368.         pref = cur;
  369.     }
  370.     return counter;
  371. }
  372.  
  373. const TCHAR* GetTextForDraw(const std::string& s) {
  374.     char* answer = new char[s.size() + 1];
  375.     for (int i = 0; i < s.size(); i++) {
  376.         answer[i] = s[i];
  377.     }
  378.     answer[s.size()] = '\0';
  379.     return answer;
  380. }
  381.  
  382. template<typename T>
  383. const TCHAR* GetTextForDraw(const T& value) {
  384.     return GetTextForDraw(std::to_string(value));
  385. }
  386.  
  387. std::pair<TPoint, TPoint> MinMaxBorders(TPolygon& polygon) {
  388.     const int inf = 1 << 30;
  389.     TPoint minPoint = { inf, inf };
  390.     TPoint maxPoint = { -inf, -inf };
  391.     for (const auto& p : polygon) {
  392.         minPoint.x = min(minPoint.x, p.x);
  393.         minPoint.y = min(minPoint.y, p.y);
  394.         maxPoint.x = max(maxPoint.x, p.x);
  395.         maxPoint.y = max(maxPoint.y, p.y);
  396.     }
  397.     return { minPoint, maxPoint };
  398. }
  399.  
  400. long long DistQrt(const TPoint& a, const TPoint& b) {
  401.     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);
  402. }
  403.  
  404. double C(int n, int m) {
  405.     double answer = 1;
  406.     for (int i = 1; i <= n; i++) {
  407.         answer *= i;
  408.     }
  409.     for (int i = 1; i <= m; i++) {
  410.         answer /= i;
  411.     }
  412.     for (int i = 1; i <= n - m; i++) {
  413.         answer /= i;
  414.     }
  415.     return answer;
  416. }
  417.  
  418. void DrawBezierLine(std::vector<TPoint>& arr, const RGBPIXEL& color) {
  419.     const int n = arr.size();
  420.     if (n <= 2) {
  421.         DrawLine(arr[0], arr.back(), color);
  422.         return;
  423.     }
  424.     auto dist = [&](const TPoint& a) { 
  425.         return abs(a.x) + abs(a.y);
  426.     };
  427.     long long D = 0;
  428.     for (int i = 2; i < n; i++) {
  429.         D = max(D, dist(arr[i - 2] - arr[i - 1] - arr[i - 1] + arr[i]));
  430.     }
  431.     double N = 1 + sqrt(n * D);
  432.     double dt = 1 / N;
  433.     auto R = [&](double t) {
  434.         double x = 0;
  435.         double y = 0;
  436.         for (int i = 0; i < n; i++) {
  437.             double p = C(n - 1, i) * pow(t, i) * pow(1 - t, n - 1 - i);
  438.             x += arr[i].x * p;
  439.             y += arr[i].y * p;
  440.         }
  441.         return TPoint(x + 0.5, y + 0.5);
  442.     };
  443.     std::vector<TPoint> a;
  444.     int q = 1 / dt + 1;
  445.     for (int i = 0; i < q; i++) {
  446.         a.push_back(R(i * 1.0 / q));
  447.     }
  448.     a.push_back(arr.back());
  449.     for (int i = 1; i < a.size(); i++) {
  450.         DrawLine(a[i - 1], a[i], color);
  451.     }
  452. }
  453.  
  454.  
  455. std::vector<TPoint> GetBezierLine(std::vector<TPoint>& arr, const RGBPIXEL& color) {
  456.     const int n = arr.size();
  457.     if (n <= 2) {
  458.         DrawLine(arr[0], arr.back(), color);
  459.         return arr;
  460.     }
  461.     auto dist = [&](const TPoint& a) {
  462.         return abs(a.x) + abs(a.y);
  463.     };
  464.     long long D = 0;
  465.     for (int i = 2; i < n; i++) {
  466.         D = max(D, dist(arr[i - 2] - arr[i - 1] - arr[i - 1] + arr[i]));
  467.     }
  468.     double N = 1 + sqrt(n * D);
  469.     double dt = 1 / N;
  470.     auto R = [&](double t) {
  471.         double x = 0;
  472.         double y = 0;
  473.         for (int i = 0; i < n; i++) {
  474.             double p = C(n - 1, i) * pow(t, i) * pow(1 - t, n - 1 - i);
  475.             x += arr[i].x * p;
  476.             y += arr[i].y * p;
  477.         }
  478.         return TPoint(x + 0.5, y + 0.5);
  479.     };
  480.     std::vector<TPoint> a;
  481.     int q = 1 / dt + 1;
  482.     for (int i = 0; i < q; i++) {
  483.         a.push_back(R(i * 1.0 / q));
  484.     }
  485.     a.push_back(arr.back());
  486.     return a;
  487. }
  488.  
  489. /*
  490.     de Kasteljo
  491. */
  492. void DrawBezierLine2(std::vector<TPoint>& arr, const RGBPIXEL& color) {
  493.     const int n = arr.size();
  494.     if (n <= 2) {
  495.         DrawLine(arr[0], arr.back(), color);
  496.         return;
  497.     }
  498.     const int bits = 7;
  499.     const int size = 1 << bits;
  500.     const int halfsize = 1 << (bits - 1);
  501.     std::function<TPoint(const TPoint&, const TPoint&, int)> get = [&](const TPoint& a, const TPoint& b, int pr) {
  502.         return TPoint(a.x + (pr * (b.x - a.x) + halfsize >> bits), a.y + (pr * (b.y - a.y) + halfsize >> bits));
  503.     };
  504.    
  505.     std::function<TPoint(std::vector<TPoint>, int)> findPoint = [&](std::vector<TPoint> a, int pr) {
  506.         if (a.size() <= 2) {
  507.             return get(a[0], a.back(), pr);
  508.         } else {
  509.             for (int i = 0; i + 1 < a.size(); i++) {
  510.                 a[i] = get(a[i], a[i + 1], pr);
  511.             }
  512.             a.pop_back();
  513.             return findPoint(a, pr);
  514.         }
  515.     };
  516.  
  517.     std::vector<TPoint> result;
  518.  
  519.     for (int t = 0; t <= size; t++) {
  520.         result.push_back(findPoint(arr, t));
  521.     }
  522.     for (int i = 0; i + 1 < result.size(); i++) {
  523.         DrawLine(result[i], result[i + 1], color);
  524.     }
  525. }
  526.  
  527. int ClipLine(TPoint& a, TPoint& b, TPolygon& arr) {
  528.  
  529.     double t0 = 0, t1 = 1, t;
  530.     TPoint s = TPoint(b.x - a.x, b.y - a.y); // vector colinear with current
  531.     long long nx, ny, num, denom, x1, y1, x2, y2;
  532.     const int n = arr.Size();
  533.     if (n <= 2 || !arr.IsConvex()) {
  534.         return 1;
  535.     }  
  536.     bool isCw = false;
  537.     for (int i = 0; i + 2 < n; i++) {
  538.         isCw |= SignArea(arr[i + 0], arr[i + 1], arr[i + 2]) < 0; // polygon contains edges in clock wise order
  539.     }
  540.  
  541.     for (int i = (isCw ? 0 : n - 1); (isCw ? i < n : i >= 0); (isCw ? i++ : i--)) {
  542.         nx = arr[i + (isCw ? 1 : -1)].y - arr[i].y;
  543.         ny = arr[i].x - arr[i + (isCw ? 1 : -1)].x;
  544.         denom = nx * s.x + ny * s.y;
  545.         num = nx * (a.x - arr[i].x) + ny * (a.y - arr[i].y);
  546.         if (abs(denom) > 1e-9) {
  547.             t = - num * 1.0 / denom;
  548.             if (denom > 0) {
  549.                 if (t > t0) {
  550.                     t0 = t;
  551.                 }
  552.             } else {
  553.                 if (t < t1) {
  554.                     t1 = t;
  555.                 }
  556.             }
  557.         } else {
  558.             if (num < 0) {
  559.                 return 1;
  560.             }
  561.         }
  562.     }
  563.     if (t0 <= t1) {
  564.         x1 = a.x + t0 * (b.x - a.x);
  565.         y1 = a.y + t0 * (b.y - a.y);
  566.         x2 = a.x + t1 * (b.x - a.x);
  567.         y2 = a.y + t1 * (b.y - a.y);
  568.         a = TPoint(x1 + 0.5, y1 + 0.5); // update values
  569.         b = TPoint(x2 + 0.5, y2 + 0.5);
  570.         return 0;
  571.     }
  572.     return 1; // no visible part
  573. }
  574.  
  575. bool PointIntoTriangle(TPoint a, TPoint b, TPoint c, TPoint x) {
  576.     return SignArea(a, b, x) * SignArea(a, x, c) <= 0 && SignArea(b, c, x) * SignArea(b, x, a)  <= 0 && SignArea(c, a, x) * SignArea(c, x, b) <= 0;
  577. }
  578.  
  579. bool PointIntoConvexPolygon(TPolygon p, TPoint x) {
  580.     bool ans = false;
  581.     const int n = p.Size();
  582.     if (n <= 2) return false;
  583.     for (int i = 2; !ans && i < n; i++) {
  584.         ans |= PointIntoTriangle(p[i - 2], p[i - 1], p[0], x);
  585.     }
  586.     return ans;
  587. }
  588.  
  589. int Y = 15;
  590. int Dy = 20;
  591.  
  592. std::vector<TPolygon> BuildProjectionOfParallelepiped(const std::vector<std::vector<TPoint3D>>& p) {
  593.     const int n = p.size();
  594.     int ITR = 0;
  595.    
  596.     auto isInvisible = [&] (TPoint3D& pt, int index) {
  597.         for (int i = 0; i < n; i++) {
  598.             if (i == index) continue;
  599.             TPolygon cur(p[i].size());
  600.             for (int j = 0; j < p[i].size(); j++) {
  601.                 cur[j] = TPoint(p[i][j].x, p[i][j].y);
  602.             }
  603.             if (!PointIntoConvexPolygon(cur, TPoint(pt.x, pt.y))) continue;
  604.             TPoint X = TPoint(pt.x, pt.y) - cur[0];
  605.             TPoint A = cur[1] - cur[0];
  606.             TPoint B = cur[2] - cur[0];
  607.             int dZ1 = p[i][1].z - p[i][0].z;
  608.             int dZ2 = p[i][2].z - p[i][0].z;
  609.             int dZ = pt.z - p[i][0].z;
  610.             double t2 = static_cast<double>(X.x * A.y - A.x * X.y) / (A.y * B.x - A.x * B.y);
  611.             double t1 = static_cast<double>(X.x - B.x * t2) / A.x;
  612.             double curX = t1 * A.x + t2 * B.x;
  613.             double curY = t1 * A.y + t2 * B.y;
  614.             double curZ = dZ1 * t1 + dZ2 * t2 + p[i][0].z;
  615.             auto myCeil = [&] (double x) {
  616.                 if (x < 0) return static_cast<int>(x - 0.5);
  617.                 return static_cast<int>(x + 0.5);
  618.             };
  619.             curX = myCeil(curX);
  620.             curY = myCeil(curY);
  621.             curZ = myCeil(curZ);
  622.  
  623.             if (curZ < pt.z) {
  624.                 return true;
  625.             }
  626.         }  
  627.         return false;
  628.     };
  629.     std::vector<TPolygon> res;
  630.     for (int i = 0; i < n; i++) {
  631.         TPoint3D mnPt = p[i][0];
  632.         for (auto& pt : p[i]) {
  633.             if (pt.z < mnPt.z) {
  634.                 mnPt = pt;
  635.             }
  636.         }
  637.         if (isInvisible(mnPt, i)) {
  638.             res.emplace_back(p[i].size());
  639.             for (int j = 0; j < p[i].size(); j++) {
  640.                 res.back()[j] = TPoint(p[i][j].x, p[i][j].y);
  641.             }
  642.         }
  643.     }
  644.     return res;
  645. }
  646.  
  647.  
  648. std::vector<bool> BuildProjectionOfParallelepiped2(const std::vector<std::vector<TPoint3D>>& p) {
  649.     std::vector<bool> result(p.size(), true);
  650.     int itr = 0;
  651.     for (const auto& v : p) {
  652.         const int n = v.size();
  653.         bool isInvisible = false;
  654.         for (int i = 0; !isInvisible && i < n; i++) {
  655.             TPoint a {v[i].x, v[i].y};
  656.             TPoint b {v[(i + 1) % n].x, v[(i + 1) % n].y};
  657.             TPoint c {v[(i + 2) % n].x, v[(i + 2) % n].y};
  658.             isInvisible = Area(b - a, c - b) > 0;
  659.         }
  660.         result[itr++] = !isInvisible;
  661.     }
  662.     return result;
  663. }
  664.  
  665.  
  666. std::vector<bool> BuildPointProjection(std::vector<std::vector<TPoint3D>>& p, int k) {
  667.     for (auto& v : p) {
  668.         for (auto& pt : v) {
  669.             pt.z = pt.z * 1.0 / k + 1;
  670.         }
  671.     }
  672.     return BuildProjectionOfParallelepiped2(p);
  673. }
  674.  
  675. std::vector<std::vector<TPoint3D>> p;
  676. double phi = M_PI / 355;
  677. double x = 5;
  678. double y = 3;
  679. double z = 5;
  680. double angle = 0;
  681.  
  682. std::vector<RGBPIXEL> colors = {
  683.     RGBPIXEL::White(),
  684.     RGBPIXEL::Red(),
  685.     RGBPIXEL::Green(),
  686.     RGBPIXEL::Blue(),
  687.     RGBPIXEL::DkMagenta(),
  688.     RGBPIXEL::Yellow(),
  689. };
  690.  
  691. const int WINDOW_H = 900;
  692. const int WINDOW_W = 1.5 * 900;
  693.  
  694.  
  695. bool gfInitScene() {
  696.     try {
  697.         const int WINDOW_SIZE = 900;
  698.         gfSetWindowSize(WINDOW_W, WINDOW_H);
  699.         const int A = 180;
  700.         const int B = 100;
  701.         const int C = 150;
  702.         int Norm = x * x + y * y + z * z;
  703.         x /= sqrt(Norm);
  704.         y /= sqrt(Norm);
  705.         z /= sqrt(Norm);
  706.         p = {
  707.             {{0, 0, 0}, {0, B, 0}, {0, B, C}, {0, 0, C}},
  708.             {{A, 0, C}, {A, B, C}, {A, B, 0}, {A, 0, 0}},
  709.  
  710.             {{0, 0, 0}, {0, 0, C}, {A, 0, C}, {A, 0, 0}},
  711.             {{A, B, 0}, {A, B, C}, {0, B, C}, {0, B, 0}},
  712.            
  713.             {{A, 0, 0}, {A, B, 0}, {0, B, 0}, {0, 0, 0}},
  714.             {{0, 0, C}, {0, B, C}, {A, B, C}, {A, 0, C}}
  715.         };
  716.  
  717.         for (auto& v : p) {
  718.             for (auto& pt : v) {
  719.                 pt.x += 300;
  720.                 pt.y += 300;
  721.             }
  722.         }
  723.         double xyAngle = 45.0 / 180.0 * M_PI;
  724.         double xzAngle = 45.0 / 180.0 * M_PI;
  725.         double yzAngle = 0 / 180.0 * M_PI;
  726.         double cosxy = cos(xyAngle);
  727.         double cosxz = cos(xzAngle);
  728.         double cosyz = cos(yzAngle);
  729.  
  730.         double sinxy = sin(xyAngle);
  731.         double sinxz = sin(xzAngle);
  732.         double sinyz = sin(yzAngle);
  733.  
  734.  
  735.         // xy
  736.         for (auto& v : p) {
  737.             for (auto& pt : v) {
  738.                 TPoint3D nxt;
  739.                 nxt.x = cosxy * pt.x - sinxy * pt.y;
  740.                 nxt.y = sinxy * pt.x + cosxy * pt.y;
  741.                 nxt.z = pt.z;
  742.                 pt = nxt;
  743.             }
  744.         }
  745.  
  746.         // xz
  747.         for (auto& v : p) {
  748.             for (auto& pt : v) {
  749.                 TPoint3D nxt;
  750.                 nxt.x = cosxz * pt.x - sinxz * pt.z;
  751.                 nxt.z = sinxz * pt.x + cosxz * pt.z;
  752.                 nxt.y = pt.y;
  753.                 pt = nxt;
  754.             }
  755.         }
  756.  
  757.         // yz
  758.         for (auto& v : p) {
  759.             for (auto& pt : v) {
  760.                 TPoint3D nxt;
  761.                 nxt.y = cosyz * pt.y - sinyz * pt.z;
  762.                 nxt.z = sinyz * pt.y + cosyz * pt.z;
  763.                 nxt.x = pt.x;
  764.                 pt = nxt;
  765.             }
  766.         }
  767.  
  768.         int mnX = 1e9;
  769.         int mnY = 1e9;
  770.         int mnZ = 1e9;
  771.         for (auto& v : p) {
  772.             for (auto& pt : v) {
  773.                 mnX = min(mnX, pt.x);
  774.                 mnY = min(mnY, pt.y);
  775.                 mnZ = min(mnZ, pt.z);
  776.             }
  777.         }
  778.  
  779.         for (auto& v : p) {
  780.             for (auto& pt : v) {
  781.                 pt.x -= mnX + 100;
  782.                 pt.y -= mnY + 100;
  783.                 pt.z -= mnZ + 100;
  784.             }
  785.         }
  786.  
  787.         for (auto v : p) {
  788.             int dx = 0;
  789.             for (int i = 0; i < v.size(); i++) {
  790.                 DrawLine(TPoint(v[i].x + dx, v[i].y), TPoint(v[(i + 1) % v.size()].x + dx, v[(i + 1) % v.size()].y), RGBPIXEL::Green());
  791.             }
  792.         }
  793.    
  794.         auto cur = BuildProjectionOfParallelepiped2(p);
  795.         for (int i = 0; i < cur.size(); i++) {
  796.             if (cur[i]) {
  797.                 TPolygon x(p[i].size());
  798.                 for (int j = 0; j < p[i].size(); j++) {
  799.                     x[j] = TPoint(p[i][j].x, p[i][j].y);
  800.                 }
  801.                 x.Draw(RGBPIXEL::White());
  802.             }
  803.         }
  804.         const int DX = 500;
  805.         auto myWay = BuildProjectionOfParallelepiped(p);
  806.         for (auto& v : myWay) {
  807.             for (auto& pt : v) {
  808.                 pt.x += DX;
  809.             }
  810.             v.Draw(RGBPIXEL::Red());
  811.         }
  812.         TPoint3D mxPt = p[0][0];
  813.         for (auto& v : p) {
  814.             for (auto& pt : v) {
  815.                 if (pt.z > mxPt.z) {
  816.                     mxPt = pt;
  817.                 }
  818.             }
  819.         }
  820.         gfDrawRectangle(mxPt.x - 5, mxPt.y - 5, mxPt.x + 5, mxPt.y + 5, RGBPIXEL::Red());
  821.         gfDrawRectangle(mxPt.x - 5 + DX, mxPt.y - 5, mxPt.x + 5 + DX, mxPt.y + 5, RGBPIXEL::Red());
  822.     } catch (...) {
  823.         return false;
  824.     }
  825.     return true;
  826. }
  827.  
  828. int dx = 10;
  829. int dy = 15;
  830. int sx = 0;
  831. int sy = 0;
  832. int ITR = 0;
  833.  
  834. void gfDrawScene()
  835. {
  836.     gfClearScreen(RGBPIXEL::Black());
  837.     angle += phi;
  838.     double s = sin(angle);
  839.     double c = cos(angle);
  840.  
  841.    
  842.     const int Y1 = 50;
  843.     const int X1 = 100;
  844.     ITR++;
  845.     ITR %= 500;
  846.     std::string str1 = "спокойствие...";
  847.     std::string str2 = "блаженство...";
  848.     if (ITR < 250) {
  849.    
  850.         gfDrawText(X1, Y1, GetTextForDraw(str1), RGBPIXEL::White());
  851.     } else {
  852.         gfDrawText(X1 + 50, Y1 + 50, GetTextForDraw(str2), RGBPIXEL::White());
  853.     }
  854.  
  855.     std::vector<std::vector<TPoint3D>> cur;
  856.     for (auto& v : p) {
  857.         cur.emplace_back();
  858.         for (auto& pt : v) {
  859.             TPoint3D nxt;
  860.             nxt.x = (c + (1 - c) * x * x) * pt.x + ((1 - c) * x * y - s * z) * pt.y + ((1 - c) * x * z + s * y) * pt.z;
  861.             nxt.y = ((1 - c) * y * x + s * z) * pt.x + (c + (1 - c) * y * y) * pt.y + ((1 - c) * y * z - s * x) * pt.z;
  862.             nxt.z = ((1 - c) * z * x - s * y) * pt.x + ((1 - c) * z * y + s * x) * pt.y + (c + (1 - c) * z * z) * pt.z;
  863.             cur.back().push_back(nxt);
  864.         }
  865.     }
  866.     auto kek = BuildPointProjection(cur, 15);
  867.     for (int i = 0; i < kek.size(); i++) {
  868.         if (kek[i]) {
  869.             TPolygon curp(cur[i].size());
  870.             for (int j = 0; j < curp.Size(); j++) {
  871.                 curp[j] = TPoint(cur[i][j].x + 500, cur[i][j].y + 500);
  872.             }
  873.             curp.Draw(RGBPIXEL::White());
  874.         }
  875.     }
  876.     //
  877. }
  878.  
  879. void gfCleanupScene() {
  880. }
  881.  
  882. void gfOnLMouseClick(int x, int y) {
  883. }
  884.  
  885. void gfOnRMouseClick(int x, int y) {
  886. }
  887.  
  888. void gfOnKeyDown(UINT key) {
  889. }
  890.  
  891. void gfOnKeyUp(UINT key)
  892. {
  893. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement