allekco

CG

Dec 18th, 2019
464
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 27.20 KB | None | 0 0
  1. #include "StdAfx.h"
  2. #include "GF.h"
  3. #include <iostream>
  4. #include <vector>
  5.  
  6. using namespace std;
  7.  
  8. #ifndef M_PI
  9. const double M_PI = 3.1415926535897932384626433832795;
  10. #endif
  11.  
  12. enum { LEFT, RIGHT, BEYOND, BEHIND, ORIGIN, DEST, BETWEEN, COLLINEAR, PARALLEL, CROSS, SKEW, SKEW_CROSS,
  13.     SKEW_NO_CROSS, CROSS_LEFT, CROSS_RIGHT, INESSNTIAL, TOUCHING, COMPLEX, SIMPLE, CONVEX, NON_CONVEX,
  14.     INSIDE, OUTSIDE, CLOCKWISE, COUNTERCLOCKWISE };
  15.  
  16.  
  17. // Ваша реализация необходимых вам функций
  18. void DrawLine( int x0, int y0, int x1, int y1, RGBPIXEL color )
  19. {
  20.     int dx = abs(x1 - x0);      //
  21.     int dy = abs(y1 - y0);
  22.     int signX = x1 > x0 ? 1 : -1;       //if x1>x0 -> 1
  23.     int signY = y1 > y0 ? 1 : -1;
  24.     if (dx == 0 && dy == 0)
  25.     {
  26.         gfSetPixel(x0, y0, color);      //ставит один пиксель
  27.     }
  28.     else
  29.     {
  30.         if (dx - dy >= 0)       //прямоульгольник вытянут по x
  31.         {
  32.             int x = x0;
  33.             int y = y0;
  34.             int E = 2 * dy - dx;        //ошибка
  35.             while (x != x1 || y != y1)      //пока не дойдем в кон точку
  36.             {
  37.                 gfSetPixel(x, y, color);
  38.                 if (signY >= 0)     //усл для того чтобы одинаковая прямая от x0 и обратно
  39.                 {
  40.                     if (E >= 0)     //всегда измен x, иногда измен y
  41.                     {
  42.                         E -= 2 * dx;
  43.                         y += signY;    
  44.                     }
  45.                 }
  46.                 else
  47.                 {
  48.                     if (E > 0)
  49.                     {
  50.                         E -= 2 * dx;
  51.                         y += signY;
  52.                     }
  53.                 }
  54.                 x += signX;     //увеличиваем или умен на шаг в 1 пиксель
  55.                 E += 2 * dy;
  56.  
  57.             }
  58.             gfSetPixel(x, y, color);
  59.         }
  60.         else        //прям вытянут по y
  61.         {
  62.             int x = x0;
  63.             int y = y0;
  64.             int E = 2 * dx - dy;
  65.             while (x != x1 || y != y1)
  66.             {
  67.                 gfSetPixel(x, y, color);
  68.                 if (signX >= 0)
  69.                 {
  70.                     if (E >= 0)
  71.                     {
  72.                         E -= 2 * dy;
  73.                         x += signX;
  74.                     }
  75.                 }
  76.                 else
  77.                 {
  78.                     if (E > 0)
  79.                     {
  80.                         E -= 2 * dy;
  81.                         x += signX;
  82.                     }
  83.                 }
  84.                 y += signY;
  85.                 E += 2 * dx;
  86.             }
  87.             gfSetPixel(x, y, color);
  88.         }
  89.     }
  90.    
  91. }
  92.  
  93. void DrawPolygon(vector<vector<int>>& P, RGBPIXEL color)        // рисуем полигон. в динамический массиве 2 x n сначала x,потом y
  94. {
  95.     if (P.size() == 2)      //проверка что два столбика
  96.     {
  97.         if (P[0].size() == P[1].size())     //количество x должно совпадать с y
  98.         {
  99.             for (int i = 0; i < P[0].size() - 1; i++)      
  100.             {
  101.                 DrawLine(P[0][i], P[1][i], P[0][i + 1], P[1][i + 1], color);
  102.             }
  103.             DrawLine(P[0][P[0].size() - 1], P[1][P[0].size() - 1], P[0][0], P[1][0], color);        //прорисовываем отдельно последнюю строчку
  104.         }
  105.     }
  106. }
  107.  
  108. int Classify(int x1, int y1, int x2, int y2, int x, int y)      //где лежит точка относительно прямой
  109. {
  110.     int ax = x2 - x1;       //вектор a=(ax,ay) совпадает с прямой
  111.     int ay = y2 - y1;
  112.     int bx = x - x1;
  113.     int by = y - y1;
  114.     int s = ax * by - bx * ay; //определитель смотрим знак у k
  115.     if (s > 0)
  116.         return LEFT;
  117.     if (s < 0)
  118.         return RIGHT;  
  119.     //если прошел сюда то векторы колинеарны
  120.     if ((ax * bx < 0) || (ay * by < 0))     //на прямой продолжающей отрезок сзади
  121.         return BEHIND;
  122.     if ((ax * ax + ay * ay) < (bx * bx + by * by)) // спереди
  123.         return BEYOND;
  124.     if ((x == x1) && (y == y1)) //в начало попали
  125.         return ORIGIN;
  126.     if ((x == x2) && (y == y2))
  127.         return DEST;
  128.     return BETWEEN; // попали четко на отрезок
  129. }
  130.  
  131. int PolyTypeConv(vector<vector<int>>& P) //определяет тип полигона: выпуклый, невыпуклый
  132. {
  133.     if (P[0].size() <= 2)       //чтобы было 3 x,y
  134.     {
  135.         return -1; //не полигон
  136.     }
  137.     int type0 = Classify(P[0][0], P[1][0], P[0][1], P[1][1], P[0][2], P[1][2]); //запоминаем тип 3 точки относительно отрезка 1-2 точек
  138.     for (int j = 0; j < P[0].size() - 1; j++)  //пробегаем по всем ребрам
  139.         for (int i = j + 2; i < P[0].size() + j - 1; i++)       //пробегаем по точкам, кроме ребра
  140.         {
  141.             int type = Classify(P[0][j], P[1][j], P[0][j + 1], P[1][j + 1], P[0][i % P[0].size()], P[1][i % P[0].size()]);
  142.             if (type == DEST || type == ORIGIN || type == BEYOND || type == BEHIND)
  143.             {
  144.                 return -1; //не полигон
  145.             }
  146.             if (type != type0) {
  147.             return NON_CONVEX;      //невыпуклый полигон
  148.             }
  149.         }
  150.     return CONVEX;
  151. }
  152.  
  153. int Intersect(int xa, int ya, int xb, int yb, int xc, int yc, int xd, int yd, double& t)    //пересекаются 2 прямые ab и cd или нет
  154. {
  155.     int nx = yd - yc;       //направляющий вектор
  156.     int ny = xc - xd;
  157.     int denom = nx * (xb - xa) + ny * (yb - ya);        //знаменатель
  158.     if (denom == 0)
  159.     {
  160.         int type = Classify(xc, yc, xd, yd, xa, ya);
  161.         if ((type == LEFT) || (type == RIGHT))
  162.             return PARALLEL;
  163.         else
  164.             return COLLINEAR;       //на одной прямой
  165.     }
  166.     int num = nx * (xa - xc) + ny * (ya - yc);
  167.     t = -double(num) / double(denom);       //именно для отрезков пересечение если t от 0 до 1
  168.     return CROSS;
  169. }
  170.  
  171. int PolyTypeSimp(vector<vector<int>>& P) //простой или самопересечениями
  172. {
  173.     if (PolyTypeConv(P) == -1)
  174.     {
  175.         return -1; //не полигон
  176.     }
  177.     if (PolyTypeConv(P) == CONVEX) {
  178.         return SIMPLE;
  179.     }
  180.  
  181.     for (int j = 0; j < P[0].size() - 1; j++)
  182.         for (int i = j + 2; i < j + P[0].size() - 1; i++)
  183.         {
  184.             double t1 = -1; //заданы произвольно, меняются в intersect
  185.             double t2 = -2;
  186.             int type1 = Intersect(P[0][j], P[1][j], P[0][j + 1], P[1][j + 1], P[0][(i % P[0].size())], P[1][(i % P[0].size())], P[0][((i + 1) % P[0].size())], P[1][((i + 1) % P[0].size())], t1);
  187.             int type2 = Intersect(P[0][(i % P[0].size())], P[1][(i % P[0].size())], P[0][((i + 1) % P[0].size())], P[1][((i + 1) % P[0].size())], P[0][j], P[1][j], P[0][j + 1], P[1][j + 1], t2);
  188.             if (type1 == CROSS && type2 == CROSS)
  189.                 if (t1 >= 0 && t1 <= 1 && t2 >= 0 && t2 <= 1) { //если обе t находятся от 0 до 1
  190.                     return COMPLEX;     //сложный
  191.                 }
  192.         }
  193.     return SIMPLE;
  194. }
  195.  
  196. int EdgeType(int x0, int y0, int x1, int y1, int x, int y)      //каким образом прямая из точки x,y пересекает прямую. для заливки
  197. {
  198.     switch (Classify(x0, y0, x1, y1, x, y))
  199.     {
  200.     case LEFT:
  201.         if (y > y0 && y <= y1)
  202.             return CROSS_LEFT;
  203.         else
  204.             return INESSNTIAL;  // не пересекает
  205.     case RIGHT:
  206.         if (y > y1 && y <= y0)
  207.             return CROSS_RIGHT;
  208.         else
  209.             return INESSNTIAL;
  210.     case BETWEEN:
  211.     case ORIGIN:
  212.     case DEST:
  213.         return TOUCHING;
  214.     default:
  215.         return INESSNTIAL;
  216.     }
  217. }
  218.  
  219. int PInPolyEO(int x, int y, vector<vector<int>>& P)     // even-odd(считает число пересевчений, направл не интересует) закрашивает тольок ушки звезды
  220. {
  221.     int prm = 0;
  222.     for (int i = 0; i < P[0].size(); i++)
  223.     {
  224.         switch (EdgeType(P[0][i], P[1][i], P[0][(i + 1) % P[0].size()], P[1][(i + 1) % P[0].size()], x, y))
  225.         {
  226.         case TOUCHING:
  227.             return INSIDE;
  228.         case CROSS_LEFT:
  229.         case CROSS_RIGHT:
  230.             prm = 1 - prm;
  231.             break;
  232.         }
  233.     }
  234.     if (prm == 0)
  235.         return OUTSIDE;
  236.     else
  237.         return INSIDE;
  238. }
  239.  
  240. int PInPolyNZW(int x, int y, vector<vector<int>>& P) // закрасит всю звезду (учитывает и направления тоже)
  241. {
  242.     int prm = 0;
  243.     for (int i = 0; i < P[0].size(); i++)
  244.     {
  245.         switch (EdgeType(P[0][i], P[1][i], P[0][(i + 1) % P[0].size()], P[1][(i + 1) % P[0].size()], x, y))
  246.         {
  247.         case TOUCHING:
  248.             return INSIDE;
  249.         case CROSS_LEFT:
  250.             prm = prm + 1;
  251.             break;
  252.         case CROSS_RIGHT:
  253.             prm = prm - 1;
  254.             break;
  255.         }
  256.     }
  257.     if (prm != 0)
  258.         return INSIDE;
  259.     else
  260.         return OUTSIDE;
  261. }
  262.  
  263. int Max_El_1D(vector<int>& P) //максимальный элемент одномерного массива
  264. {
  265.     int max = P[0];
  266.     for (int i = 0; i < P.size(); i++)
  267.     {
  268.         if (P[i] > max)
  269.             max = P[i];
  270.     }
  271.     return max;
  272. }
  273.  
  274. int Min_El_1D(vector<int>& P)
  275. {
  276.     int min = P[0];
  277.     for (int i = 0; i < P.size(); i++)
  278.     {
  279.         if (P[i] < min)
  280.             min = P[i];
  281.     }
  282.     return min;
  283. }
  284.  
  285. void FillingEO(vector<vector<int>>& P, RGBPIXEL color)
  286. {
  287.     int x_max = Max_El_1D(P[0]);
  288.     int x_min = Min_El_1D(P[0]);
  289.     int y_max = Max_El_1D(P[1]);
  290.     int y_min = Min_El_1D(P[1]);
  291.     for (int y = y_min; y <= y_max; y++) //увеличиваем по пикселю и закрашиваем если внутри
  292.         for (int x = x_min; x <= x_max; x++)
  293.         {
  294.             if (PInPolyEO(x, y, P) == INSIDE)
  295.                 gfSetPixel(x, y, color);
  296.         }
  297. }
  298.  
  299. void FillingNZW(vector<vector<int>>& P, RGBPIXEL color)
  300. {
  301.     int x_max = Max_El_1D(P[0]);
  302.     int x_min = Min_El_1D(P[0]);
  303.     int y_max = Max_El_1D(P[1]);
  304.     int y_min = Min_El_1D(P[1]);
  305.     for (int y = y_min; y <= y_max; y++)
  306.         for (int x = x_min; x <= x_max; x++)
  307.         {
  308.             if (PInPolyNZW(x, y, P) == INSIDE)
  309.                 gfSetPixel(x, y, color);
  310.         }
  311. }
  312.  
  313. //2 ЛР
  314.  
  315. vector<int> R3(double t, vector<vector<int>>& P) // параметрическое задание кривой безье 3 порядка
  316. {
  317.     vector<int> R = { 0 , 0 }; //точка
  318.     R[0] = int((1 - t) * (1 - t) * (1 - t) * P[0][0] + 3 * t * (1 - t) * (1 - t) * P[0][1] + 3 * t * t * (1 - t) * P[0][2] + t * t * t * P[0][3]);
  319.     R[1] = int((1 - t) * (1 - t) * (1 - t) * P[1][0] + 3 * t * (1 - t) * (1 - t) * P[1][1] + 3 * t * t * (1 - t) * P[1][2] + t * t * t * P[1][3]);
  320.     return R;
  321. }
  322.  
  323. int dist(int x, int y)  
  324. {
  325.     return abs(x) + abs(y);
  326. }
  327.  
  328. void DrawBesie3(vector<vector<int>>& P, RGBPIXEL color)
  329. {
  330.     int D = Max(dist(P[0][0] - 2 * P[0][1] + P[0][2], P[1][0] - 2 * P[1][1] + P[1][2]), dist(P[0][1] - 2 * P[0][2] + P[0][3], P[1][1] - 2 * P[1][2] + P[1][3]));
  331.     double N = 1 + sqrt(3 * D);
  332.     double dt = 1 / N;
  333.     double t = dt;
  334.     vector<int> P1, P2;
  335.     P1 = R3(0, P); //нач точка
  336.     while (t <= 1)
  337.     {
  338.         P2 = R3(t, P);
  339.         t += dt;
  340.         DrawLine(P1[0], P1[1], P2[0], P2[1], color);
  341.         P1 = P2;
  342.     }
  343.     P2 = R3(1, P);
  344.     DrawLine(P1[0], P1[1], P2[0], P2[1], color);
  345. }
  346.  
  347. int PolyTypeConvOrient(vector<vector<int>>& P, int& t) //проверка на ориентацию
  348. {
  349.     t = -1;
  350.     if (P[0].size() <= 2)
  351.     {
  352.         gfDrawText(300, 300, "Not polygon", RGBPIXEL::Cyan());
  353.         return -1;
  354.     }
  355.     int type0 = Classify(P[0][0], P[1][0], P[0][1], P[1][1], P[0][2], P[1][2]);
  356.     for (int j = 0; j < P[0].size() - 1; j++)
  357.         for (int i = j + 2; i < P[0].size() + j - 1; i++)
  358.         {
  359.             int type = Classify(P[0][j], P[1][j], P[0][j + 1], P[1][j + 1], P[0][i % P[0].size()], P[1][i % P[0].size()]);
  360.             if (type == DEST || type == ORIGIN || type == BEYOND || type == BEHIND)
  361.             {
  362.                 gfDrawText(300, 300, "Not polygon", RGBPIXEL::Cyan());
  363.                 return -1;
  364.             }
  365.             if (type != type0)
  366.                 return NON_CONVEX;
  367.         }
  368.     if (type0 == LEFT)
  369.         t = CLOCKWISE;  //по часовой(система левосторонняя)
  370.     if (type0 == RIGHT)
  371.         t = COUNTERCLOCKWISE;
  372.     return CONVEX;
  373. }
  374.  
  375. void ClipLine(vector<vector<int>>& line, vector<vector<int>>& Poly, RGBPIXEL color) //алгоритм отсечения Кируса-Бека
  376. {
  377.     int n = Poly[0].size();  //количество вершин(точек)
  378.     int trigger = -1; //отвечает за по\против часовой (ориентация)
  379.     int type = PolyTypeConvOrient(Poly, trigger);
  380.     if (type == NON_CONVEX)
  381.         gfDrawText(500, 100, "Невыпуклый", RGBPIXEL::Red());
  382.     else
  383.     {
  384.         if (trigger == CLOCKWISE) //переворачиваем, делаем копию buff и меняем
  385.         {
  386.             vector<vector<int>> buff = Poly;
  387.             for (int j = 0; j < 2; j++)
  388.                 for (int i = 1; i < n; i++)
  389.                 {
  390.                     buff[j][i] = Poly[j][n - i];
  391.                 }
  392.             Poly = buff;
  393.         }
  394.         double t0 = 0, t1 = 1, t;
  395.         int sx = line[0][1] - line[0][0];
  396.         int sy = line[1][1] - line[1][0];
  397.         int nx, ny;
  398.         double num, denom;
  399.         for (int i = 0; i < n; i++)
  400.         {
  401.             nx = Poly[1][(i + 1) % n] - Poly[1][i];
  402.             ny = Poly[0][i] - Poly[0][(i + 1) % n];
  403.             denom = nx * sx + ny * sy;
  404.             num = nx * (line[0][0] - Poly[0][i]) + ny * (line[1][0] - Poly[1][i]);
  405.             if (abs(denom) > 0.01)
  406.             {
  407.                 t = -num / denom;
  408.                 if (denom > 0)
  409.                 {
  410.                     if (t > t0)
  411.                         t0 = t;
  412.  
  413.                 }
  414.                 else
  415.                 {
  416.                     if (t < t1)
  417.                         t1 = t;
  418.                 }
  419.             }
  420.         }
  421.         if (t0 <= t1) //&& t1>0)
  422.             DrawLine(int(line[0][0] + t0 * sx), int(line[1][0] + t0 * sy), int(line[0][0] + t1 * sx), int(line[1][0] + t1 * sy), color);
  423.     }
  424.  
  425. }
  426.  
  427. void test() {
  428.     DrawLine(100, 100, 160, 160, RGBPIXEL::Green());
  429.     DrawLine(100, 100, 160, 120, RGBPIXEL(200, 200, 200));
  430.     DrawLine(100, 100, 160, 100, RGBPIXEL::Cyan());
  431.     DrawLine(100, 100, 160, 60, RGBPIXEL(100, 100, 0));
  432.     DrawLine(100, 100, 160, 40, RGBPIXEL::Red());
  433.     DrawLine(100, 100, 120, 40, RGBPIXEL(100, 100, 0));
  434.     DrawLine(100, 100, 100, 40, RGBPIXEL::Yellow());
  435.     DrawLine(100, 100, 80, 40, RGBPIXEL(150, 100, 0));
  436.     DrawLine(100, 100, 40, 40, RGBPIXEL::Blue());
  437.     DrawLine(100, 100, 40, 60, RGBPIXEL(100, 100, 0));
  438.     DrawLine(100, 100, 40, 100, RGBPIXEL::White());
  439.     DrawLine(100, 100, 40, 120, RGBPIXEL(150, 100, 10));
  440.     DrawLine(100, 100, 40, 160, RGBPIXEL::Magenta());
  441.     DrawLine(100, 100, 80, 160, RGBPIXEL(200, 150, 0));
  442.     DrawLine(100, 100, 100, 160, RGBPIXEL::DkCyan());
  443.     DrawLine(100, 100, 120, 160, RGBPIXEL(200, 200, 0));
  444.  
  445.     vector<vector<int>> Poly = { {40, 160, 100, 40}, {240, 240, 200, 300} };
  446.     DrawPolygon(Poly, RGBPIXEL::Red());
  447.  
  448.     if (PolyTypeConv(Poly) == CONVEX) gfDrawText(60, 310, "CONVEX", RGBPIXEL::Blue());
  449.     else gfDrawText(60, 310, "NON CONVEX", RGBPIXEL::Blue());
  450.  
  451.     if (PolyTypeSimp(Poly) == SIMPLE) gfDrawText(60, 330, "SIMPLE", RGBPIXEL::Blue());
  452.     else gfDrawText(60, 330, "COMPLEX", RGBPIXEL::Blue());
  453.  
  454.  
  455.     vector<vector<int>> Poly0 = { {300, 360, 240, 360, 240}, {40, 160, 80, 80, 160} };
  456.     DrawPolygon(Poly0, RGBPIXEL::Cyan());
  457.  
  458.     if (PolyTypeConv(Poly0) == CONVEX) gfDrawText(260, 170, "CONVEX", RGBPIXEL::Blue());
  459.     else gfDrawText(260, 170, "NON CONVEX", RGBPIXEL::Blue());
  460.  
  461.     if (PolyTypeSimp(Poly0) == SIMPLE) gfDrawText(260, 200, "SIMPLE", RGBPIXEL::Blue());
  462.     else gfDrawText(260, 200, "COMPLEX", RGBPIXEL::Blue());
  463.  
  464.  
  465.     vector<vector<int>> PolyStar = { {300, 320, 360, 320, 300, 280, 240, 280}, {240, 280, 300, 320, 360, 320, 300, 280} };
  466.     DrawPolygon(PolyStar, RGBPIXEL::Cyan());
  467.  
  468.     if (PolyTypeConv(PolyStar) == CONVEX) gfDrawText(260, 380, "CONVEX", RGBPIXEL::Blue());
  469.     else gfDrawText(260, 380, "NON CONVEX", RGBPIXEL::Blue());
  470.  
  471.     if (PolyTypeSimp(PolyStar) == SIMPLE) gfDrawText(260, 400, "SIMPLE", RGBPIXEL::Blue());
  472.     else gfDrawText(260, 400, "COMPLEX", RGBPIXEL::Blue());
  473.  
  474.  
  475.     vector<vector<int>> Poly1 = { {500, 560, 440, 560, 440}, {40, 160, 80, 80, 160} };
  476.     DrawPolygon(Poly1, RGBPIXEL::Cyan());
  477.     gfDrawText(470, 10, "EVEN-ODD", RGBPIXEL::Blue());
  478.     FillingEO(Poly1, RGBPIXEL::Yellow());
  479.  
  480.     if (PolyTypeConv(Poly1) == CONVEX) gfDrawText(460, 170, "CONVEX", RGBPIXEL::Blue());
  481.     else gfDrawText(460, 170, "NON CONVEX", RGBPIXEL::Blue());
  482.  
  483.     if (PolyTypeSimp(Poly1) == SIMPLE) gfDrawText(460, 200, "SIMPLE", RGBPIXEL::Blue());
  484.     else gfDrawText(460, 200, "COMPLEX", RGBPIXEL::Blue());
  485.  
  486.  
  487.     vector<vector<int>> Poly2 = { {500 + 200, 560 + 200, 440 + 200, 560 + 200, 440 + 200}, {40, 160, 80, 80, 160} };
  488.     DrawPolygon(Poly2, RGBPIXEL::Magenta());
  489.     gfDrawText(630, 10, "NON-ZERO-WINDING", RGBPIXEL::Blue());
  490.     FillingNZW(Poly2, RGBPIXEL::Yellow());
  491.  
  492.     if (PolyTypeConv(Poly2) == CONVEX) gfDrawText(460 + 200, 170, "CONVEX", RGBPIXEL::Blue());
  493.     else gfDrawText(460 + 200, 170, "NON CONVEX", RGBPIXEL::Blue());
  494.  
  495.     if (PolyTypeSimp(Poly2) == SIMPLE) gfDrawText(460 + 200, 200, "SIMPLE", RGBPIXEL::Blue());
  496.     else gfDrawText(460 + 200, 200, "COMPLEX", RGBPIXEL::Blue());
  497.  
  498.  
  499.     //2 лр
  500.  
  501.     vector<vector<int>> LineBesie1 = { {450,700,400,600},{400,200,200,400} };
  502.     DrawBesie3(LineBesie1, RGBPIXEL::Red());
  503.  
  504.     vector<vector<int>> LineBesie2 = { {650,700,700,750},{400,200,200,400} };
  505.     DrawBesie3(LineBesie2, RGBPIXEL::Green());
  506.  
  507.     vector<vector<int>> ConvexPoly = { {850,1000, 1050, 1050, 900},{60, 60, 150, 400, 400} };
  508.     DrawPolygon(ConvexPoly, RGBPIXEL::Red());
  509.  
  510.     vector<vector<int>> LineFirst = { {800, 1100},{450, 350} };
  511.     DrawLine(LineFirst[0][0], LineFirst[1][0], LineFirst[0][1], LineFirst[1][1], RGBPIXEL::Blue());
  512.     ClipLine(LineFirst, ConvexPoly, RGBPIXEL::Green());
  513.  
  514.     vector<vector<int>> LineSecond = { {800, 950},{250, 300} };
  515.     DrawLine(LineSecond[0][0], LineSecond[1][0], LineSecond[0][1], LineSecond[1][1], RGBPIXEL::Blue());
  516.     ClipLine(LineSecond, ConvexPoly, RGBPIXEL::Green());
  517.  
  518.     vector<vector<int>> LineThird = { {900, 1100},{150, 150} };
  519.     DrawLine(LineThird[0][0], LineThird[1][0], LineThird[0][1], LineThird[1][1], RGBPIXEL::Blue());
  520.     ClipLine(LineThird, ConvexPoly, RGBPIXEL::Green());
  521.  
  522.  
  523.     vector<vector<int>> LineFourth = { {800, 820},{300, 400} };
  524.     DrawLine(LineFourth[0][0], LineFourth[1][0], LineFourth[0][1], LineFourth[1][1], RGBPIXEL::Blue());
  525.     ClipLine(LineFourth, ConvexPoly, RGBPIXEL::Green());
  526.  
  527.     vector<vector<int>> Linefifth = { {970, 990},{260, 340} };
  528.     DrawLine(Linefifth[0][0], Linefifth[1][0], Linefifth[0][1], Linefifth[1][1], RGBPIXEL::Blue());
  529.     ClipLine(Linefifth, ConvexPoly, RGBPIXEL::Green());
  530.  
  531.     /*  int l = 5;
  532.     vector<vector<int>> line1 = { {430, 590, 590, 430}, {300+l/2, 300+l/2, 300-l/2, 300-l/2} };
  533.     DrawPolygon(line1, RGBPIXEL::Red());
  534.     FillingEO(line1, RGBPIXEL::Red());
  535.  
  536.     l = 5;
  537.     vector<vector<int>> line2 = { {510, 590, 590, 510}, {300 + l / 2, 240 + l / 2, 240 - l / 2, 300 - l / 2} };
  538.     DrawPolygon(line2, RGBPIXEL::Yellow());
  539.     FillingEO(line2, RGBPIXEL::Yellow());
  540.  
  541.     l = 5;
  542.     vector<vector<int>> line3 = { {510+l/2, 510+l/2, 510-l/2, 510-l/2}, {300, 240, 240, 300} };
  543.     DrawPolygon(line3, RGBPIXEL::Cyan());
  544.     FillingEO(line3, RGBPIXEL::Cyan());
  545.  
  546.     l = 5;
  547.     vector<vector<int>> line4 = { {510, 430, 430, 510}, {300 + l / 2, 240 + l / 2, 240 - l / 2, 300 - l / 2} };
  548.     DrawPolygon(line4, RGBPIXEL::Blue());
  549.     FillingEO(line4, RGBPIXEL::Blue());
  550. */
  551. }
  552.  
  553. void ParallelProjection(vector<vector<int>>& fig, RGBPIXEL color) //параллельная проекция
  554. {
  555.     vector<vector<int>> PolyUp = { {0,0,0,0},{0,0,0,0} };
  556.     vector<vector<int>> PolyDown = { {0,0,0,0},{0,0,0,0} };
  557.     int i;
  558.     for (i = 0; i < 4; i++)
  559.     {
  560.         PolyUp[0][i] = fig[0][i + 4];    //x
  561.         PolyUp[1][i] = fig[1][i + 4];         //y
  562.         PolyDown[0][i] = fig[0][i];    //x
  563.         PolyDown[1][i] = fig[1][i];    //y
  564.         DrawLine(PolyDown[0][i], PolyDown[1][i], PolyUp[0][i], PolyUp[1][i], color);  //рисуем вертикальные ребра
  565.     }
  566.     DrawPolygon(PolyUp, color); //верхняя сторона проекции
  567.     DrawPolygon(PolyDown, color); //нижняя сторона проекции
  568.  
  569. }
  570.  
  571. void PerspectiveProjection(int k, vector<vector<int>>& fig, RGBPIXEL color) { //одноточечная перспективная проекция
  572.     int i = 0;
  573.     vector<vector<int>> PolyUp = { {0,0,0,0},{0,0,0,0} };
  574.     vector<vector<int>> PolyDown = { {0,0,0,0},{0,0,0,0} };
  575.     for (i = 0; i < 4; i++)
  576.     {
  577.         PolyUp[0][i] = k * fig[0][i + 4] / (fig[2][i + 4] + k);  
  578.         PolyUp[1][i] = k * fig[1][i + 4] / (fig[2][i + 4] + k);
  579.         PolyDown[0][i] = k * fig[0][i] / (fig[2][i] + k);
  580.         PolyDown[1][i] = k * fig[1][i] / (fig[2][i] + k);
  581.         DrawLine(PolyDown[0][i], PolyDown[1][i], PolyUp[0][i], PolyUp[1][i], color); //ребра
  582.     }
  583.     DrawPolygon(PolyUp, color); //верхняя плоскость
  584.     DrawPolygon(PolyDown, color);
  585. }
  586.  
  587. void DeleteEdgePar(vector<vector<int>>& fig, RGBPIXEL color)
  588. {
  589.     int eps = 600, i = 0, x[4], y[4], z[3], A[6], B[6], C[6], D[6], xc = 0, yc = 0, zc = 0, l = 0;
  590.     vector<vector<int>> Poly = { {0,0,0,0},{0,0,0,0} };
  591.     for (i = 0; i < 8; i++)
  592.     {
  593.         xc += fig[0][i];
  594.         yc += fig[1][i];
  595.         zc += fig[2][i];
  596.     }
  597.     xc = xc / 8;
  598.     yc = yc / 8;
  599.     zc = zc / 8;
  600.     for (i = 0; i < 6; i++) //6 граней, идем по каждой
  601.     {
  602.         if (i == 0)
  603.         {
  604.             x[0] = fig[0][0];
  605.             x[1] = fig[0][1];
  606.             x[2] = fig[0][2];
  607.             y[0] = fig[1][0];
  608.             y[1] = fig[1][1];
  609.             y[2] = fig[1][2];
  610.             z[0] = fig[2][0];
  611.             z[1] = fig[2][1];
  612.             z[2] = fig[2][2];
  613.             x[3] = fig[0][3];
  614.             y[3] = fig[1][3];
  615.         }
  616.         if (i == 1)
  617.         {
  618.             x[0] = fig[0][4];
  619.             x[1] = fig[0][5];
  620.             x[2] = fig[0][6];
  621.             y[0] = fig[1][4];
  622.             y[1] = fig[1][5];
  623.             y[2] = fig[1][6];
  624.             z[0] = fig[2][4];
  625.             z[1] = fig[2][5];
  626.             z[2] = fig[2][6];
  627.             x[3] = fig[0][7];
  628.             y[3] = fig[1][7];
  629.         }
  630.  
  631.         if (i == 2)
  632.         {
  633.             x[0] = fig[0][0];
  634.             x[1] = fig[0][1];
  635.             x[2] = fig[0][5];
  636.             y[0] = fig[1][0];
  637.             y[1] = fig[1][1];
  638.             y[2] = fig[1][5];
  639.             z[0] = fig[2][0];
  640.             z[1] = fig[2][1];
  641.             z[2] = fig[2][5];
  642.             x[3] = fig[0][4];
  643.             y[3] = fig[1][4];
  644.         }
  645.         if (i == 3)
  646.         {
  647.             x[0] = fig[0][2];
  648.             x[1] = fig[0][3];
  649.             x[2] = fig[0][7];
  650.             y[0] = fig[1][2];
  651.             y[1] = fig[1][3];
  652.             y[2] = fig[1][7];
  653.             z[0] = fig[2][2];
  654.             z[1] = fig[2][3];
  655.             z[2] = fig[2][7];
  656.             x[3] = fig[0][6];
  657.             y[3] = fig[1][6];
  658.  
  659.         }
  660.         if (i == 4)
  661.         {
  662.             x[0] = fig[0][0];
  663.             x[1] = fig[0][3];
  664.             x[2] = fig[0][7];
  665.             y[0] = fig[1][0];
  666.             y[1] = fig[1][3];
  667.             y[2] = fig[1][7];
  668.             z[0] = fig[2][0];
  669.             z[1] = fig[2][3];
  670.             z[2] = fig[2][7];
  671.             x[3] = fig[0][4];
  672.             y[3] = fig[1][4];
  673.         }
  674.         if (i == 5)
  675.         {
  676.             x[0] = fig[0][1];
  677.             x[1] = fig[0][2];
  678.             x[2] = fig[0][6];
  679.             y[0] = fig[1][1];
  680.             y[1] = fig[1][2];
  681.             y[2] = fig[1][6];
  682.             z[0] = fig[2][1];
  683.             z[1] = fig[2][2];
  684.             z[2] = fig[2][6];
  685.             x[3] = fig[0][5];
  686.             y[3] = fig[1][5];
  687.  
  688.         }
  689.         A[i] = (y[1] - y[0]) * (z[2] - z[0]) - (y[2] - y[0]) * (z[1] - z[0]);
  690.         B[i] = (x[2] - x[0]) * (z[1] - z[0]) - (z[2] - z[0]) * (x[1] - x[0]);
  691.         C[i] = (x[1] - x[0]) * (y[2] - y[0]) - (y[1] - y[0]) * (x[2] - x[0]);
  692.         if ((A[i] * (x[0] - xc) + B[i] * (y[0] - yc) + C[i] * (z[0] - zc)) < 0)
  693.         {
  694.             A[i] = -A[i];
  695.             B[i] = -B[i];
  696.             C[i] = -C[i];
  697.         }
  698.         if (C[i] * (eps - zc) > 0)
  699.         {  
  700.             for (int j = 0; j < 4; j++) {
  701.                 Poly[0][j] = x[j];
  702.                 Poly[1][j] = y[j];
  703.             }
  704.             DrawPolygon(Poly, color);
  705.             //DrawPolygon(Poly, RGBPIXEL(250, 40*i, 30)); чтобы видно какими полигонами он рисует
  706.         }
  707.     }
  708. }
  709.  
  710. void DeleteEdgePer(int k, vector<vector<int>>& fig, RGBPIXEL color)
  711. {
  712.     for (int i = 0; i < 8; i++) {
  713.         fig[0][i] = k * fig[0][i] / (fig[2][i] + k);
  714.         fig[1][i] = k * fig[1][i] / (fig[2][i] + k);
  715.     }
  716.    
  717.     DeleteEdgePar(fig, color);
  718. }
  719. // Вызывается один раз в самом начале при инициализации приложения
  720. bool gfInitScene()
  721. {
  722.     gfSetWindowSize(1150, 600);
  723.     //test(); 1 и 2 лр
  724.    
  725.     return true;
  726. }
  727.  
  728. void test_tmp() {
  729.     vector<vector<int>> Poly = { {320, 120, 320, 520, 320, 120, 320, 520}, {250, 350, 450, 350, 150, 250, 350, 250 },
  730.                                                                                             { 50, 70, 90, 70, 410, 430, 450, 430 } };
  731.     vector<vector<int>> Poly2 = { {320, 120, 320, 520, 320, 120, 320, 520}, {250, 350, 450, 350, 150, 250, 350, 250 } };
  732.     gfDrawText(320, 250, "1", RGBPIXEL(0, 128, 255));
  733.     gfDrawText(120, 350, "2", RGBPIXEL(0, 128, 255));
  734.     gfDrawText(320, 150, "5", RGBPIXEL(0, 128, 255));
  735.     gfDrawText(120, 250, "6", RGBPIXEL(0, 128, 255));
  736.     ParallelProjection(Poly2, RGBPIXEL::Red());
  737.     DrawPolygon(Poly2, RGBPIXEL::Cyan());
  738. }
  739.  
  740. void first() {
  741.     vector<vector<int>> Box = { {320, 120, 320, 520, 320, 120, 320, 520}, {250, 350, 450, 350, 150, 250, 350, 250 },
  742.                                                                                     { 50, 70, 90, 70, 410, 430, 450, 430 } }; // наклонный параллелепиппед
  743.     vector<vector<int>> Box2 = { {320, 120, 320, 520, 320, 120, 320, 520}, {130, 230, 330, 230, 30, 130, 230, 130 },
  744.                                                                                 { 50, 70, 90, 70, 410, 430, 450, 430 } }; // наклонный параллелепиппед
  745.     ParallelProjection(Box, RGBPIXEL::Red());
  746. }
  747.  
  748. void second() {
  749.     int k = 100;
  750.     vector<vector<int>> Box = { {320, 120, 320, 520, 320, 120, 320, 520}, {250, 350, 450, 350, 150, 250, 350, 250 },
  751.                                                                                     { 50, 70, 90, 70, 410, 430, 450, 430 } }; // наклонный параллелепиппед
  752.     PerspectiveProjection(k, Box, RGBPIXEL::Green());
  753. }
  754.  
  755. void third() {
  756.     int k = 100;
  757.     vector<vector<int>> Box = { {320, 120, 320, 520, 320, 120, 320, 520}, {250, 350, 450, 350, 150, 250, 350, 250 },
  758.                                                                                     { 50, 70, 90, 70, 410, 430, 450, 430 } };
  759.     vector<vector<int>> Box2 = { {300, 100, 150, 350, 300, 100, 150, 350}, {500, 500, 550, 550, 350, 350, 400, 400 },
  760.                                                                                     { 50, 50, 200, 200, 50, 50, 200, 200 } };
  761.     //ParallelProjection(Box, RGBPIXEL::DkCyan());
  762.     DeleteEdgePar(Box, RGBPIXEL::Cyan());
  763.     //PerspectiveProjection(k, Box, RGBPIXEL::DkGreen());
  764.     DeleteEdgePer(k, Box, RGBPIXEL::Green());
  765. }
  766.  
  767. void forth() {
  768.     static int x = 0;
  769.     vector<vector<int>> Box0 = { {320, 120, 320, 520, 320, 120, 320, 520}, {250, 350, 450, 350, 150, 250, 350, 250 },
  770.                                                                                     { 50, 70, 90, 70, 410, 430, 450, 430 } };
  771.     vector<vector<int>> Box = Box0;
  772.     float nx=1, ny=1, nz=1;
  773.     float len = sqrt(nx * nx + ny * ny + nz * nz);
  774.     nx = nx / len; ny = ny / len; nz = nz / len; //единичный вектор вокруг которого
  775.     float a = 0.01 * x;
  776.     for (int i = 0; i < 8; i++)
  777.     { //матрица Родригеса
  778.         Box[0][i] = Box0[0][i] * (cos(a) + nx * nx * (1 - cos(a))) + Box0[1][i] * (nx * ny * (1 - cos(a)) - nz * sin(a)) + Box0[2][i] * (ny * sin(a) + nx * nz * (1 - cos(a)));
  779.         Box[1][i] = Box0[0][i] * (sin(a) - nx * ny * (1 - cos(a))) + Box0[1][i] * (cos(a) + ny * ny * (1 - cos(a))) + Box0[2][i] * (-nx * sin(a) + ny * nz * (1 - cos(a)));
  780.         Box[2][i] = Box0[0][i] * (-ny * sin(a) + nx * ny * (1 - cos(a))) + Box0[1][i] * (nx * sin(a) + ny * nz * (1 - cos(a))) + Box0[2][i] * (cos(a) + nz * nz * (1 - cos(a)));
  781.     }
  782.  
  783.     ParallelProjection(Box, RGBPIXEL::Cyan()); //Вращение паралельной проекции
  784.     PerspectiveProjection(500, Box, RGBPIXEL::Red()); //Вращение точечной проекции
  785.  
  786.     x += 1 % gfGetWindowWidth();
  787. }
  788.  
  789. // Вызывается в цикле до момента выхода из приложения.
  790. // Следует использовать для создания анимационных эффектов
  791. void gfDrawScene()
  792. {  
  793.     gfClearScreen(RGBPIXEL::Black());
  794.    
  795.    
  796.     //first();
  797.     //second();
  798.     //third();
  799.     forth();
  800.        
  801.     //int x = gfGetMouseX(),
  802.     //    y = gfGetMouseY();
  803.     //gfDrawRectangle(x - 10, y - 10, x + 10, y + 10, RGBPIXEL::Green());
  804. }
  805.  
  806. // Вызывается один раз перед выходом из приложения.
  807. // Следует использовать для освобождения выделенных
  808. // ресурсов (памяти, файлов и т.п.)
  809. void gfCleanupScene()
  810. {
  811. }
  812.  
  813. // Вызывается когда пользователь нажимает левую кнопку мыши
  814. void gfOnLMouseClick( int x, int y )
  815. {
  816.     x; y;
  817.     gfDrawRectangle(x - 10, y - 10, x + 10, y + 10, RGBPIXEL::Green());
  818. }
  819.  
  820. // Вызывается когда пользователь нажимает правую кнопку мыши
  821. void gfOnRMouseClick( int x, int y )
  822. {
  823.     x; y;
  824. }
  825.  
  826. // Вызывается когда пользователь нажимает клавишу на клавиатуре
  827. void gfOnKeyDown( UINT key )
  828. {
  829.     key;
  830.  
  831.     if( key == 'A' )
  832.         gfDisplayMessage( "'A' key has been pressed" );
  833. }
  834.  
  835. // Вызывается когда пользователь отжимает клавишу на клавиатуре
  836. void gfOnKeyUp( UINT key )
  837. {
  838.     key;
  839.  
  840.     //if( key == 'B' )
  841.     //    gfDisplayMessage( "'B' key has been un-pressed" );
  842. }
Advertisement
Add Comment
Please, Sign In to add comment