Advertisement
Guest User

izg3

a guest
Mar 22nd, 2019
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.32 KB | None | 0 0
  1. /**
  2.  * @file        student.cpp
  3.  * @author      Ladislav Mosner, VUT FIT Brno, imosner@fit.vutbr.cz
  4.  * @author      Petr Kleparnik, VUT FIT Brno, ikleparnik@fit.vutbr.cz
  5.  * @author      Kamil Behun, VUT FIT Brno, ibehun@fit.vutbr.cz
  6.  * @date        11.03.2018
  7.  *
  8.  * @brief       Deklarace funkci studentu. DOPLNUJI STUDENTI
  9.  *
  10.  */
  11.  
  12. #include "base.h"
  13. #include "student.h"
  14. #include "globals.h"
  15. #include <math.h>
  16.  
  17. /**
  18.  * @brief Vraci barvu pixelu z pozice [x, y]
  19.  * @param[in] x X souradnice pixelu
  20.  * @param[in] y Y souradnice pixelu
  21.  * @return Barva pixelu na pozici [x, y] ve formatu RGBA
  22.  */
  23. RGBA getPixel(int x, int y)
  24. {
  25.     if (x >= width || y >= height || x < 0 || y < 0) {
  26.         IZG_ERROR("Pristup do framebufferu mimo hranice okna\n");
  27.     }
  28.     return framebuffer[y * width + x];
  29. }
  30.  
  31. /**
  32.  * @brief Nastavi barvu pixelu na pozici [x, y]
  33.  * @param[in] x X souradnice pixelu
  34.  * @param[in] y Y souradnice pixelu
  35.  * @param[in] color Barva pixelu ve formatu RGBA
  36.  */
  37. void putPixel(int x, int y, RGBA color)
  38. {
  39.     if (x >= width || y >= height || x < 0 || y < 0) {
  40.         IZG_ERROR("Pristup do framebufferu mimo hranice okna\n");
  41.     }
  42.     framebuffer[y * width + x] = color;
  43. }
  44.  
  45. /**
  46.  * @brief Vykresli usecku se souradnicemi [x1, y1] a [x2, y2]
  47.  * @param[in] x1 X souradnice 1. bodu usecky
  48.  * @param[in] y1 Y souradnice 1. bodu usecky
  49.  * @param[in] x2 X souradnice 2. bodu usecky
  50.  * @param[in] y2 Y souradnice 2. bodu usecky
  51.  * @param[in] color Barva pixelu usecky ve formatu RGBA
  52.  * @param[in] arrow Priznak pro vykresleni sipky (orientace hrany)
  53.  */
  54. void drawLine(int x1, int y1, int x2, int y2, RGBA color, bool arrow = false)
  55. {
  56.  
  57.     if (arrow) {
  58.         // Sipka na konci hrany
  59.         double vx1 = x2 - x1;
  60.         double vy1 = y2 - y1;
  61.         double length = sqrt(vx1 * vx1 + vy1 * vy1);
  62.         double vx1N = vx1 / length;
  63.         double vy1N = vy1 / length;
  64.         double vx1NN = -vy1N;
  65.         double vy1NN = vx1N;
  66.         int w = 3;
  67.         int h = 10;
  68.         int xT = (int) (x2 + w * vx1NN - h * vx1N);
  69.         int yT = (int) (y2 + w * vy1NN - h * vy1N);
  70.         int xB = (int) (x2 - w * vx1NN - h * vx1N);
  71.         int yB = (int) (y2 - w * vy1NN - h * vy1N);
  72.         pinedaTriangle(Point(x2, y2), Point(xT, yT), Point(xB, yB), color, color, false);
  73.     }
  74.  
  75.     bool steep = abs(y2 - y1) > abs(x2 - x1);
  76.  
  77.     if (steep) {
  78.         SWAP(x1, y1);
  79.         SWAP(x2, y2);
  80.     }
  81.  
  82.     if (x1 > x2) {
  83.         SWAP(x1, x2);
  84.         SWAP(y1, y2);
  85.     }
  86.  
  87.     const int dx = x2 - x1, dy = abs(y2 - y1);
  88.     const int P1 = 2 * dy, P2 = P1 - 2 * dx;
  89.     int P = 2 * dy - dx;
  90.     int y = y1;
  91.     int ystep = 1;
  92.     if (y1 > y2) ystep = -1;
  93.  
  94.     for (int x = x1; x <= x2; x++) {
  95.         if (steep) {
  96.             if (y >= 0 && y < width && x >= 0 && x < height) {
  97.                 putPixel(y, x, color);
  98.             }
  99.         } else {
  100.             if (x >= 0 && x < width && y >= 0 && y < height) {
  101.                 putPixel(x, y, color);
  102.             }
  103.         }
  104.  
  105.         if (P >= 0) {
  106.             P += P2;
  107.             y += ystep;
  108.         } else {
  109.             P += P1;
  110.         }
  111.     }
  112. }
  113.  
  114. /**
  115.  * @brief Vyplni a vykresli trojuhelnik
  116.  * @param[in] v1 Prvni bod trojuhelniku
  117.  * @param[in] v2 Druhy bod trojuhelniku
  118.  * @param[in] v3 Treti bod trojuhelniku
  119.  * @param[in] color1 Barva vyplne trojuhelniku
  120.  * @param[in] color2 Barva hranice trojuhelniku
  121.  * @param[in] arrow Priznak pro vykresleni sipky (orientace hrany)
  122.  *
  123.  * SPOLECNY UKOL. Doplnuji studenti se cvicicim.
  124.  */
  125. void pinedaTriangle(const Point &v1, const Point &v2, const Point &v3, const RGBA &color1, const RGBA &color2, bool arrow)
  126. {
  127.     // Nalezeni obalky (minX, maxX), (minY, maxY) trojuhleniku.
  128.  
  129.     //////// DOPLNTE KOD /////////
  130.     int minX = MIN(MIN(v1.x, v2.x), v3.x);
  131.     int minY = MIN(MIN(v1.y, v2.y), v3.y);
  132.  
  133.     int maxX = MAX(MAX(v1.x, v2.x), v3.x);
  134.     int maxY = MAX(MAX(v1.y, v2.y), v3.y);
  135.  
  136.     // Oriznuti obalky (minX, maxX, minY, maxY) trojuhleniku podle rozmeru okna.
  137.  
  138.     //////// DOPLNTE KOD /////////
  139.     minX = MAX(0, minX);
  140.     minY = MAX(0, minY);
  141.  
  142.     maxX = MIN(width - 1, maxX);
  143.     maxY = MIN(height - 1, maxY);
  144.  
  145.     // Spocitani parametru hranove funkce (deltaX, deltaY) pro kazdou hranu.
  146.     // Hodnoty deltaX, deltaY jsou souradnicemi vektoru, ktery ma pocatek
  147.     // v prvnim vrcholu hrany, konec v druhem vrcholu.
  148.     // Vypocet prvnotni hodnoty hranove funkce.
  149.  
  150.     //////// DOPLNTE KOD /////////
  151.     int deltaX1 = v2.x - v1.x;
  152.     int deltaX2 = v3.x - v2.x;
  153.     int deltaX3 = v1.x - v3.x;
  154.  
  155.     int deltaY1 = v2.y - v1.y;
  156.     int deltaY2 = v3.y - v2.y;
  157.     int deltaY3 = v1.y - v3.y;
  158.  
  159.     int edgeF1 = (minY - v1.y)*deltaX1 - (minX - v1.x)*deltaY1;
  160.     int edgeF2 = (minY - v2.y)*deltaX2 - (minX - v2.x)*deltaY2;
  161.     int edgeF3 = (minY - v3.y)*deltaX3 - (minX - v3.x)*deltaY3;
  162.  
  163.     // Vyplnovani: Cyklus pres vsechny body (x, y) v obdelniku (minX, minY), (maxX, maxY).
  164.     // Pro aktualizaci hodnot hranove funkce v bode P (x +/- 1, y) nebo P (x, y +/- 1)
  165.     // vyuzijte hodnoty hranove funkce E (x, y) z bodu P (x, y).
  166.  
  167.     //////// DOPLNTE KOD /////////
  168.     for (int y = minY; y <= maxY; y++) {
  169.         bool even = (y - minY) % 2 == 0;
  170.         for (int x = ((even) ? minX : maxX); (even) ? (x <= maxX) : (x >= minX); x += (even) ? 1 : -1) {
  171.             if (edgeF1 >= 0 && edgeF2 >= 0 && edgeF3 >= 0) {
  172.                 putPixel(x, y, color1);
  173.             }
  174.             if (!((even && x == maxX) || (!even && x == minX))) {
  175.                 edgeF1 += (even) ? -deltaY1 : deltaY1;
  176.                 edgeF2 += (even) ? -deltaY2 : deltaY2;
  177.                 edgeF3 += (even) ? -deltaY3 : deltaY3;
  178.             }
  179.         }
  180.         edgeF1 += deltaX1;
  181.         edgeF2 += deltaX2;
  182.         edgeF3 += deltaX3;
  183.     }
  184.  
  185.     // Prekresleni hranic trojuhelniku barvou color2.
  186.     drawLine(v1.x, v1.y, v2.x, v2.y, color2, arrow);
  187.     drawLine(v2.x, v2.y, v3.x, v3.y, color2, arrow);
  188.     drawLine(v3.x, v3.y, v1.x, v1.y, color2, arrow);
  189. }
  190. /**
  191.  * @brief Vyplni a vykresli polygon
  192.  * @param[in] points Pole bodu polygonu
  193.  * @param[in] size Pocet bodu polygonu (velikost pole "points")
  194.  * @param[in] color1 Barva vyplne polygonu
  195.  * @param[in] color2 Barva hranice polygonu
  196.  *
  197.  * SAMOSTATNY BODOVANY UKOL. Doplnuji pouze studenti.
  198.  */
  199. void pinedaPolygon(const Point *points, const int size, const RGBA &color1, const RGBA &color2)
  200. {
  201.     // Pri praci muzete vyuzit pro vas predpripravene datove typy z base.h., napriklad:
  202.     //
  203.     //      Pro ukladani parametru hranovych funkci muzete vyuzit prichystany vektor parametru hranovych funkci "EdgeParams":
  204.     //
  205.     //          EdgeParams edgeParams(size)                         // Vytvorite vektor (pole) "edgeParams" parametru hranovych funkci o velikosti "size".
  206.     //          edgeParams[i].deltaX, edgeParams[i].deltaY          // Pristup k parametrum (deltaX, deltaY) hranove funkce v poli "edgeParams" na indexu "i".
  207.     //
  208.     //      Pro ukladani hodnot hranovych funkci muzete vyuzit prichystany vektor hodnot hranovych funkci "EdgeFncValues":
  209.     //
  210.     //          EdgeFncValues edgeFncValues(size)                   // Vytvorite vektor (pole) "edgeFncValues" hodnot hranovych funkci o velikosti "size".
  211.     //          edgeFncValues[i]                                    // Pristup k hodnote hranove funkce v poli "edgeFncValues" na indexu "i".
  212.     //
  213.  
  214.     // Nalezeni obalky (minX, maxX), (minY, maxY) polygonu.
  215.  
  216.     int minimalniX = points[0].x;
  217.     int maximalniX = points[0].x;
  218.     int minimalniY = points[0].y;
  219.     int maximalniY = points[0].y;
  220.  
  221.     for (int i = 1; i < size; i++)
  222.     {
  223.         if (points[i].x < minimalniX)
  224.         {
  225.             minimalniX = points[i].x;
  226.         }
  227.         if (points[i].x > maximalniX)
  228.         {
  229.             maximalniX = points[i].x;
  230.         }
  231.         if (points[i].y < minimalniY)
  232.         {
  233.             minimalniY = points[i].y;
  234.         }
  235.         if (points[i].y > maximalniY)
  236.         {
  237.             maximalniY = points[i].y;
  238.         }
  239.  
  240.     }
  241.  
  242.  
  243.     // Oriznuti obalky (minX, maxX), (minY, maxY) polygonu podle rozmeru okna
  244.  
  245.  
  246.  
  247.  
  248.     minimalniX = MAX(0, minimalniX);
  249.     minimalniY = MAX(0, minimalniY);
  250.  
  251.     maximalniX = MIN(width - 1, maximalniX);
  252.     maximalniY = MIN(height - 1, maximalniY);
  253.    
  254.    
  255.    
  256.     // Spocitani parametru (deltaX, deltaY) hranove funkce pro kazdou hranu.
  257.     // Hodnoty deltaX, deltaY jsou souradnicemi vektoru, ktery ma pocatek
  258.     // v prvnim vrcholu hrany, konec v druhem vrcholu.
  259.     // Vypocet prvnotnich hodnot hranovych funkci pro jednotlive hrany.
  260.  
  261.     EdgeParams hrany(size);
  262.     for (int i = 0; i < size; i++)
  263.     {
  264.         int dalsi = (i + 1) % size;
  265.         hrany[i].deltaX = points[dalsi].x - points[i].x;
  266.         hrany[i].deltaY = points[dalsi].y - points[i].y;
  267.  
  268.     }
  269.  
  270.  
  271.     // Test konvexnosti polygonu    
  272.  
  273.     //////// DOPLNTE KOD /////////
  274.    
  275.     EdgeFncValues edge_fnc_values(size);
  276.     for (int i = 0; i < size; i++) {
  277.         edge_fnc_values[i] = (minimalniY - points[i].y)*hrany[i].deltaX - (minimalniX - points[i].x)*hrany[i].deltaY;
  278.     }
  279.     // Vyplnovani: Cyklus pres vsechny body (x, y) v obdelniku (minX, minY), (maxX, maxY).
  280.     // Pro aktualizaci hodnot hranove funkce v bode P (x +/- 1, y) nebo P (x, y +/- 1)
  281.     // vyuzijte hodnoty hranove funkce E (x, y) z bodu P (x, y) */
  282.    
  283.    
  284.  
  285.     for (int y = minimalniY; y <= maximalniY; y++) {
  286.         bool even = (y - minimalniY) % 2 == 0;
  287.         for (int x = ((even) ? minimalniX : maximalniX); (even) ? (x <= maximalniX) : (x >= minimalniX); x += (even) ? 1 : -1) {
  288.  
  289.             bool jevetsineznula = true;
  290.             for (int i = 0; i < size; i++)
  291.             {
  292.                 if (edge_fnc_values[i] < 0) {
  293.                     jevetsineznula = false;
  294.                     break;
  295.                 }
  296.             }
  297.             if (jevetsineznula) {
  298.                 putPixel(x, y, color1);
  299.             }
  300.             if (!((even && x == maximalniX) || (!even && x == minimalniX))) {
  301.                 for (int i = 0; i < size; i++)
  302.                 {
  303.                     edge_fnc_values[i]+= (even) ? -hrany[i].deltaY : hrany[i].deltaY;
  304.                    
  305.  
  306.                 }
  307.                
  308.            
  309.             }
  310.         }
  311.         for (int i = 0; i < size; i++)
  312.         {
  313.             edge_fnc_values[i] += hrany[i].deltaX;
  314.  
  315.         }
  316.        
  317.     /*
  318.     for (int y = minY; y <= maxY; y++) {
  319.     bool even = (y - minY) % 2 == 0;
  320.     for (int x = ((even) ? minX : maxX); (even) ? (x <= maxX) : (x >= minX); x += (even) ? 1 : -1) {
  321.     if (edgeF1 >= 0 && edgeF2 >= 0 && edgeF3 >= 0) {
  322.     putPixel(x, y, color1);
  323.     }
  324.     if (!((even && x == maxX) || (!even && x == minX))) {
  325.     edgeF1 += (even) ? -deltaY1 : deltaY1;
  326.     edgeF2 += (even) ? -deltaY2 : deltaY2;
  327.     edgeF3 += (even) ? -deltaY3 : deltaY3;
  328.     }
  329.     }
  330.     edgeF1 += deltaX1;
  331.     edgeF2 += deltaX2;
  332.     edgeF3 += deltaX3;
  333.     }
  334.     */
  335.  
  336.  
  337.     // Prekresleni hranic polygonu barvou color2.
  338.     for (int i = 0; i < size; i++) {
  339.         drawLine(points[i].x, points[i].y, points[(i + 1) % size].x, points[(i + 1) % size].y, color2/*, true*/);
  340.     }
  341. }
  342.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement