Advertisement
999ms

lab3

Dec 11th, 2019
236
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 18.69 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 = 2000;
  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)) {
  363.                     continue;
  364.                 }
  365.             }
  366.             if (SignArea(p[i], p[(i + 1) % n], a) >= 0) {
  367.                 counter++;
  368.             } else {
  369.                 counter--;
  370.             }
  371.         }
  372.         pref = cur;
  373.     }
  374.     return counter;
  375. }
  376.  
  377. const TCHAR* GetTextForDraw(const std::string s) {
  378.     char* answer = new char[s.size() + 1];
  379.     for (int i = 0; i < s.size(); i++) {
  380.         answer[i] = s[i];
  381.     }
  382.     answer[s.size()] = '\0';
  383.     return answer;
  384. }
  385.  
  386. template<typename T>
  387. const TCHAR* GetTextForDraw(const T& value) {
  388.     return GetTextForDraw(std::to_string(value));
  389. }
  390.  
  391. std::pair<TPoint, TPoint> MinMaxBorders(TPolygon& polygon) {
  392.     const int inf = 1 << 30;
  393.     TPoint minPoint = { inf, inf };
  394.     TPoint maxPoint = { -inf, -inf };
  395.     for (const auto& p : polygon) {
  396.         minPoint.x = min(minPoint.x, p.x);
  397.         minPoint.y = min(minPoint.y, p.y);
  398.         maxPoint.x = max(maxPoint.x, p.x);
  399.         maxPoint.y = max(maxPoint.y, p.y);
  400.     }
  401.     return { minPoint, maxPoint };
  402. }
  403.  
  404. long long DistQrt(const TPoint& a, const TPoint& b) {
  405.     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);
  406. }
  407.  
  408. double C(int n, int m) {
  409.     double answer = 1;
  410.     for (int i = 1; i <= n; i++) {
  411.         answer *= i;
  412.     }
  413.     for (int i = 1; i <= m; i++) {
  414.         answer /= i;
  415.     }
  416.     for (int i = 1; i <= n - m; i++) {
  417.         answer /= i;
  418.     }
  419.     return answer;
  420. }
  421.  
  422. void DrawBezierLine(std::vector<TPoint>& arr, const RGBPIXEL& color) {
  423.     const int n = arr.size();
  424.     if (n <= 2) {
  425.         DrawLine(arr[0], arr.back(), color);
  426.         return;
  427.     }
  428.     auto dist = [&](const TPoint& a) { 
  429.         return abs(a.x) + abs(a.y);
  430.     };
  431.     long long D = 0;
  432.     for (int i = 2; i < n; i++) {
  433.         D = max(D, dist(arr[i - 2] - arr[i - 1] - arr[i - 1] + arr[i]));
  434.     }
  435.     double N = 1 + sqrt(n * D);
  436.     double dt = 1 / N;
  437.     auto R = [&](double t) {
  438.         double x = 0;
  439.         double y = 0;
  440.         for (int i = 0; i < n; i++) {
  441.             double p = C(n - 1, i) * pow(t, i) * pow(1 - t, n - 1 - i);
  442.             x += arr[i].x * p;
  443.             y += arr[i].y * p;
  444.         }
  445.         return TPoint(x + 0.5, y + 0.5);
  446.     };
  447.     std::vector<TPoint> a;
  448.     int q = 1 / dt + 1;
  449.     for (int i = 0; i < q; i++) {
  450.         a.push_back(R(i * 1.0 / q));
  451.     }
  452.     a.push_back(arr.back());
  453.     for (int i = 1; i < a.size(); i++) {
  454.         DrawLine(a[i - 1], a[i], color);
  455.     }
  456. }
  457.  
  458. /*
  459.     de Kasteljo
  460. */
  461. void DrawBezierLine2(std::vector<TPoint>& arr, const RGBPIXEL& color) {
  462.     const int n = arr.size();
  463.     if (n <= 2) {
  464.         DrawLine(arr[0], arr.back(), color);
  465.         return;
  466.     }
  467.     const int bits = 7;
  468.     const int size = 1 << bits;
  469.     const int halfsize = 1 << (bits - 1);
  470.     std::function<TPoint(const TPoint&, const TPoint&, int)> get = [&](const TPoint& a, const TPoint& b, int pr) {
  471.         return TPoint(a.x + (pr * (b.x - a.x) + halfsize >> bits), a.y + (pr * (b.y - a.y) + halfsize >> bits));
  472.     };
  473.    
  474.     std::function<TPoint(std::vector<TPoint>, int)> findPoint = [&](std::vector<TPoint> a, int pr) {
  475.         if (a.size() <= 2) {
  476.             return get(a[0], a.back(), pr);
  477.         } else {
  478.             for (int i = 0; i + 1 < a.size(); i++) {
  479.                 a[i] = get(a[i], a[i + 1], pr);
  480.             }
  481.             a.pop_back();
  482.             return findPoint(a, pr);
  483.         }
  484.     };
  485.  
  486.     std::vector<TPoint> result;
  487.  
  488.     for (int t = 0; t <= size; t++) {
  489.         result.push_back(findPoint(arr, t));
  490.     }
  491.     for (int i = 0; i + 1 < result.size(); i++) {
  492.         DrawLine(result[i], result[i + 1], color);
  493.     }
  494. }
  495.  
  496. int ClipLine(TPoint& a, TPoint& b, TPolygon& arr) {
  497.  
  498.     double t0 = 0, t1 = 1, t;
  499.     TPoint s = TPoint(b.x - a.x, b.y - a.y); // vector colinear with current
  500.     long long nx, ny, num, denom, x1, y1, x2, y2;
  501.     const int n = arr.Size();
  502.     if (n <= 2 || !arr.IsConvex()) {
  503.         return 1;
  504.     }  
  505.     bool isCw = false;
  506.     for (int i = 0; i + 2 < n; i++) {
  507.         isCw |= SignArea(arr[i + 0], arr[i + 1], arr[i + 2]) < 0; // polygon contains edges in clock wise order
  508.     }
  509.  
  510.     for (int i = (isCw ? 0 : n - 1); (isCw ? i < n : i >= 0); (isCw ? i++ : i--)) {
  511.         nx = arr[i + (isCw ? 1 : -1)].y - arr[i].y;
  512.         ny = arr[i].x - arr[i + (isCw ? 1 : -1)].x;
  513.         denom = nx * s.x + ny * s.y;
  514.         num = nx * (a.x - arr[i].x) + ny * (a.y - arr[i].y);
  515.         if (abs(denom) > 1e-9) {
  516.             t = - num * 1.0 / denom;
  517.             if (denom > 0) {
  518.                 if (t > t0) {
  519.                     t0 = t;
  520.                 }
  521.             } else {
  522.                 if (t < t1) {
  523.                     t1 = t;
  524.                 }
  525.             }
  526.         } else {
  527.             if (num < 0) {
  528.                 return 1;
  529.             }
  530.         }
  531.     }
  532.     if (t0 <= t1) {
  533.         x1 = a.x + t0 * (b.x - a.x);
  534.         y1 = a.y + t0 * (b.y - a.y);
  535.         x2 = a.x + t1 * (b.x - a.x);
  536.         y2 = a.y + t1 * (b.y - a.y);
  537.         a = TPoint(x1 + 0.5, y1 + 0.5); // update values
  538.         b = TPoint(x2 + 0.5, y2 + 0.5);
  539.         return 0;
  540.     }
  541.     return 1; // no visible part
  542. }
  543.  
  544. bool PointIntoTriangle(TPoint a, TPoint b, TPoint c, TPoint x) {
  545.     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;
  546. }
  547.  
  548. bool PointIntoConvexPolygon(TPolygon p, TPoint x) {
  549.     bool ans = false;
  550.     const int n = p.Size();
  551.     if (n <= 2) return false;
  552.     for (int i = 2; !ans && i < n; i++) {
  553.         ans |= PointIntoTriangle(p[i - 2], p[i - 1], p[0], x);
  554.     }
  555.     return ans;
  556. }
  557.  
  558. int Y = 15;
  559. int Dy = 20;
  560.  
  561. std::vector<TPolygon> BuildProjectionOfParallelepiped(const std::vector<std::vector<TPoint3D>>& p) {
  562.     const int n = p.size();
  563.     int ITR = 0;
  564.    
  565.     auto isInvisible = [&] (TPoint3D& pt, int index) {
  566.         for (int i = 0; i < n; i++) {
  567.             if (i == index) continue;
  568.             TPolygon cur(p[i].size());
  569.             for (int j = 0; j < p[i].size(); j++) {
  570.                 cur[j] = TPoint(p[i][j].x, p[i][j].y);
  571.             }
  572.             if (!PointIntoConvexPolygon(cur, TPoint(pt.x, pt.y))) continue;
  573.             TPoint X = TPoint(pt.x, pt.y) - cur[0];
  574.             TPoint A = cur[1] - cur[0];
  575.             TPoint B = cur[2] - cur[0];
  576.             int dZ1 = p[i][1].z - p[i][0].z;
  577.             int dZ2 = p[i][2].z - p[i][0].z;
  578.             int dZ = pt.z - p[i][0].z;
  579.             double t2 = static_cast<double>(X.x * A.y - A.x * X.y) / (A.y * B.x - A.x * B.y);
  580.             double t1 = static_cast<double>(X.x - B.x * t2) / A.x;
  581.             double curX = t1 * A.x + t2 * B.x;
  582.             double curY = t1 * A.y + t2 * B.y;
  583.             double curZ = dZ1 * t1 + dZ2 * t2 + p[i][0].z;
  584.             auto myCeil = [&] (double x) {
  585.                 if (x < 0) return static_cast<int>(x - 0.5);
  586.                 return static_cast<int>(x + 0.5);
  587.             };
  588.             curX = myCeil(curX);
  589.             curY = myCeil(curY);
  590.             curZ = myCeil(curZ);
  591.  
  592.             if (curZ < pt.z) {
  593.                 return true;
  594.             }
  595.         }  
  596.         return false;
  597.     };
  598.     std::vector<TPolygon> res;
  599.     for (int i = 0; i < n; i++) {
  600.         TPoint3D mnPt = p[i][0];
  601.         for (auto& pt : p[i]) {
  602.             if (pt.z < mnPt.z) {
  603.                 mnPt = pt;
  604.             }
  605.         }
  606.         if (isInvisible(mnPt, i)) {
  607.             res.emplace_back(p[i].size());
  608.             for (int j = 0; j < p[i].size(); j++) {
  609.                 res.back()[j] = TPoint(p[i][j].x, p[i][j].y);
  610.             }
  611.         }
  612.     }
  613.     return res;
  614. }
  615.  
  616. std::vector<bool> BuildProjectionOfParallelepiped2(const std::vector<std::vector<TPoint3D>>& p) {
  617.     std::vector<bool> result(p.size(), true);
  618.     int itr = 0;
  619.     for (const auto& v : p) {
  620.         const int n = v.size();
  621.         bool isInvisible = false;
  622.         for (int i = 0; !isInvisible && i < n; i++) {
  623.             TPoint a {v[i].x, v[i].y};
  624.             TPoint b {v[(i + 1) % n].x, v[(i + 1) % n].y};
  625.             TPoint c {v[(i + 2) % n].x, v[(i + 2) % n].y};
  626.             isInvisible = Area(b - a, c - b) > 0;
  627.         }
  628.         result[itr++] = !isInvisible;
  629.     }
  630.     return result;
  631. }
  632.  
  633. std::vector<std::vector<TPoint3D>> p;
  634. double phi = M_PI / 30;
  635. double x = 1;
  636. double y = 1;
  637. double z = 0;
  638. double angle = 0;
  639.  
  640.  
  641. bool gfInitScene() {
  642.     try {
  643.         const int WINDOW_SIZE = 900;
  644.         gfSetWindowSize(WINDOW_SIZE * 1.5, WINDOW_SIZE);
  645.         const int A = 134;
  646.         const int B = 264;
  647.         const int C = 317;
  648.         int Norm = x * x + y * y + z * z;
  649.         x /= sqrt(Norm);
  650.         y /= sqrt(Norm);
  651.         z /= sqrt(Norm);
  652.         p = {
  653.             {{0, 0, 0}, {0, B, 0}, {0, B, C}, {0, 0, C}},
  654.             {{A, 0, C}, {A, B, C}, {A, B, 0}, {A, 0, 0}},
  655.  
  656.             {{0, 0, 0}, {0, 0, C}, {A, 0, C}, {A, 0, 0}},
  657.             {{A, B, 0}, {A, B, C}, {0, B, C}, {0, B, 0}},
  658.            
  659.             {{A, 0, 0}, {A, B, 0}, {0, B, 0}, {0, 0, 0}},
  660.             {{0, 0, C}, {0, B, C}, {A, B, C}, {A, 0, C}}
  661.         };
  662.  
  663.         for (auto& v : p) {
  664.             for (auto& pt : v) {
  665.                 pt.x += 300;
  666.                 pt.y += 300;
  667.             }
  668.         }
  669.         double xyAngle = 45.0 / 180.0 * M_PI;
  670.         double xzAngle = 45.0 / 180.0 * M_PI;
  671.         double yzAngle = 0 / 180.0 * M_PI;
  672.         double cosxy = cos(xyAngle);
  673.         double cosxz = cos(xzAngle);
  674.         double cosyz = cos(yzAngle);
  675.  
  676.         double sinxy = sin(xyAngle);
  677.         double sinxz = sin(xzAngle);
  678.         double sinyz = sin(yzAngle);
  679.  
  680.  
  681.         // xy
  682.         for (auto& v : p) {
  683.             for (auto& pt : v) {
  684.                 TPoint3D nxt;
  685.                 nxt.x = cosxy * pt.x - sinxy * pt.y;
  686.                 nxt.y = sinxy * pt.x + cosxy * pt.y;
  687.                 nxt.z = pt.z;
  688.                 pt = nxt;
  689.             }
  690.         }
  691.  
  692.         // xz
  693.         for (auto& v : p) {
  694.             for (auto& pt : v) {
  695.                 TPoint3D nxt;
  696.                 nxt.x = cosxz * pt.x - sinxz * pt.z;
  697.                 nxt.z = sinxz * pt.x + cosxz * pt.z;
  698.                 nxt.y = pt.y;
  699.                 pt = nxt;
  700.             }
  701.         }
  702.  
  703.         // yz
  704.         for (auto& v : p) {
  705.             for (auto& pt : v) {
  706.                 TPoint3D nxt;
  707.                 nxt.y = cosyz * pt.y - sinyz * pt.z;
  708.                 nxt.z = sinyz * pt.y + cosyz * pt.z;
  709.                 nxt.x = pt.x;
  710.                 pt = nxt;
  711.             }
  712.         }
  713.  
  714.         int mnX = 1e9;
  715.         int mnY = 1e9;
  716.         int mnZ = 1e9;
  717.         for (auto& v : p) {
  718.             for (auto& pt : v) {
  719.                 mnX = min(mnX, pt.x);
  720.                 mnY = min(mnY, pt.y);
  721.                 mnZ = min(mnZ, pt.z);
  722.             }
  723.         }
  724.  
  725.         for (auto& v : p) {
  726.             for (auto& pt : v) {
  727.                 pt.x += 200 - mnX;
  728.                 pt.y += 200 - mnY;
  729.                 pt.z += 200 - mnZ;
  730.             }
  731.         }
  732.  
  733.         for (auto v : p) {
  734.             int dx = 0;
  735.             for (int i = 0; i < v.size(); i++) {
  736.                 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());
  737.             }
  738.         }
  739.  
  740.         auto cur = BuildProjectionOfParallelepiped2(p);
  741.         for (int i = 0; i < cur.size(); i++) {
  742.             if (cur[i]) {
  743.                 TPolygon x(p[i].size());
  744.                 for (int j = 0; j < p[i].size(); j++) {
  745.                     x[j] = TPoint(p[i][j].x, p[i][j].y);
  746.                 }
  747.                 x.Draw(RGBPIXEL::White());
  748.             }
  749.         }
  750.         const int DX = 500;
  751.         auto myWay = BuildProjectionOfParallelepiped(p);
  752.         for (auto& v : myWay) {
  753.             for (auto& pt : v) {
  754.                 pt.x += DX;
  755.             }
  756.             v.Draw(RGBPIXEL::Red());
  757.         }
  758.         TPoint3D mxPt = p[0][0];
  759.         for (auto& v : p) {
  760.             for (auto& pt : v) {
  761.                 if (pt.z > mxPt.z) {
  762.                     mxPt = pt;
  763.                 }
  764.             }
  765.         }
  766.         gfDrawRectangle(mxPt.x - 5, mxPt.y - 5, mxPt.x + 5, mxPt.y + 5, RGBPIXEL::Red());
  767.         gfDrawRectangle(mxPt.x - 5 + DX, mxPt.y - 5, mxPt.x + 5 + DX, mxPt.y + 5, RGBPIXEL::Red());
  768.     } catch (...) {
  769.         return false;
  770.     }
  771.     return true;
  772. }
  773.  
  774. void gfDrawScene()
  775. {
  776.     gfClearScreen(RGBPIXEL::Black());
  777.     angle += phi;
  778.     double s = sin(angle);
  779.     double c = cos(angle);
  780.     std::vector<std::vector<TPoint3D>> cur;
  781.     for (auto& v : p) {
  782.         cur.emplace_back();
  783.         for (auto& pt : v) {
  784.             TPoint3D nxt;
  785.             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;
  786.             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;
  787.             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;
  788.             cur.back().push_back(nxt);
  789.         }
  790.     }
  791.     auto kek = BuildProjectionOfParallelepiped2(cur);
  792.     for (int i = 0; i < kek.size(); i++) {
  793.         if (kek[i]) {
  794.             TPolygon curp(cur[i].size());
  795.             for (int j = 0; j < curp.Size(); j++) {
  796.                 curp[j] = TPoint(cur[i][j].x, cur[i][j].y);
  797.             }
  798.             curp.Draw(RGBPIXEL::White());
  799.         }
  800.     }
  801.     //
  802. }
  803.  
  804. void gfCleanupScene() {
  805. }
  806.  
  807. void gfOnLMouseClick(int x, int y) {
  808. }
  809.  
  810. void gfOnRMouseClick(int x, int y) {
  811. }
  812.  
  813. void gfOnKeyDown(UINT key) {
  814. }
  815.  
  816. void gfOnKeyUp(UINT key)
  817. {
  818. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement