Advertisement
Guest User

Untitled

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