Advertisement
Guest User

Untitled

a guest
Apr 24th, 2017
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.18 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include "GDI+ image.h"
  4.  
  5.  
  6. typedef boost::gil::bgr8_pixel_t Pixel;
  7. typedef boost::gil::bgr8_view_t View;
  8. typedef boost::gil::bgr8c_view_t ViewReadOnly;
  9. typedef boost::gil::bgr8_view_t::x_iterator Iterator_X;
  10. typedef boost::gil::bgr8_view_t::y_iterator Iterator_Y;
  11. typedef boost::gil::bgr8_view_t::locator Iterator_XY;
  12.  
  13.  
  14. /// READ ME FIRST
  15. void TheLookAtMeFakeFunction(View& view, const unsigned short& x, const unsigned short& y)
  16. {
  17. // a View is the access to image's pixels ect.
  18.  
  19. // pixel access, slow but easy to understand
  20. view(x, y);
  21. view(x, y) = Pixel(0, 0, 255); // blue, green, red channels
  22.  
  23. // pixel access, optimalize for small x/y increments
  24. Iterator_XY position = view.xy_at(x, y);
  25. *position = Pixel(0, 0, 255);
  26. ++position.x(); // point at pixel(x+1, y)
  27. --position.y(); // point at pixel(x, y-1)
  28.  
  29. // pixel access, row and column interators
  30. unsigned int row_number = 0;
  31. unsigned int column_number = 0;
  32. Iterator_X itr_x = view.row_begin(row_number);
  33. Iterator_Y itr_y = view.col_begin(column_number);
  34.  
  35. // the Windows applications coordinates system is used in this code
  36. // origin point (0, 0) in the left upper corner
  37. // do not forget: pixel(b,g,r), full_red(0, 0, 255), bright_red(130, 130, 255)
  38. };
  39.  
  40.  
  41. ////////////////////////////////////////////////////////////////////////////////
  42.  
  43.  
  44. // function declarations, draw line
  45. void AntiAliasingDda(View& view, const unsigned short& x1, const unsigned short& y1,
  46. const unsigned short& x2, const unsigned short& y2);
  47. void SymmetricDda(View& view, const unsigned short& x1, const unsigned short& y1,
  48. const unsigned short& x2, const unsigned short& y2);
  49. void Bresenhama(View& view, const unsigned short& x1, const unsigned short& y1,
  50. const unsigned short& x2, const unsigned short& y2);
  51. // function declarations, draw circle
  52. void Circle1Div4(View& view, const unsigned short& x1, const unsigned short& y1,
  53. const unsigned short& x2, const unsigned short& y2);
  54. void MidpointCircle1(View& view, const unsigned short& x1, const unsigned short& y1,
  55. const unsigned short& x2, const unsigned short& y2);
  56. void MidpointCircle2(View& view, const unsigned short& x1, const unsigned short& y1,
  57. const unsigned short& x2, const unsigned short& y2);
  58. // function declarations, draw eliphsis
  59. void Ellipsis(View& view, const unsigned short& x1, const unsigned short& y1,
  60. const unsigned short& a, const unsigned short& b);
  61. // function declarations, flood area
  62. void BoundryFill1Div4(View& view, const unsigned short& x, const unsigned short& y,
  63. const Pixel& fill_color, const Pixel& border_color);
  64. void BoundryFill1Div8(View& view, const unsigned short& x, const unsigned short& y,
  65. const Pixel& fill_color, const Pixel& border_color);
  66.  
  67.  
  68. ////////////////////////////////////////////////////////////////////////////////
  69.  
  70.  
  71. /// DrawThisLine, function used in WndProc()
  72. void DrawThisLine(View& view,
  73. const unsigned short& x1, const unsigned short& y1,
  74. const unsigned short& x2, const unsigned short& y2)
  75. {
  76. // NOTE: Pixel(0, 0, 255) is red it's a BGR channel
  77.  
  78. //AntiAliasingDda(view, x1, y1, x2, y2);
  79. //SymmetricDda(view, x1, y1, x2, y2);
  80. //Bresenhama(view, x1, y1, x2, y2);
  81.  
  82. double x, xk;
  83. double m, y, yk;
  84. double d1, d2;
  85. x = x1 < x2 ? x1 : x2;
  86. xk = x1 < x2 ? x2 : x1;
  87. y = x1 < x2 ? (double)y1 : (double)y2;
  88. yk = x1 < x2 ? (double)y2 : (double)y1;
  89. m = (double)(yk - y) / (double)(xk - x);
  90. if (abs(m) < 1)
  91. {
  92. view(unsigned short(x), unsigned short(y)) = Pixel(0, 0, 255);
  93.  
  94. while (x < xk)
  95. {
  96. x = x + 1;
  97. y = y + m; /* wyliczanie przyrostowo wartosci y*/
  98. d1 = abs(unsigned short(y) - y);
  99. d2 = 1 - d1;
  100. view(unsigned short(x), unsigned short(y)) = Pixel((int)(d1 * 255), (int)(d1 * 255), 255);
  101. view(unsigned short(x), unsigned short(y) + 1) = Pixel((int)(d2 * 255), (int)(d2 * 255), 255);
  102.  
  103. }
  104. }
  105. else
  106. {
  107. x = y1 < y2 ? x1 : x2;
  108. xk = y1 < y2 ? x2 : x1;
  109. y = y1 < y2 ? (double)y1 : (double)y2;
  110. yk = y1 < y2 ? (double)y2 : (double)y1;
  111. view(unsigned short(x), unsigned short(y)) = Pixel(0, 0, 255);
  112. while (y < yk)
  113. {
  114. y = y + 1;
  115. x = x + 1 / m; /* wyliczanie przyrostowo wartosci x*/
  116. d1 = abs(unsigned short(x) - x);
  117. d2 = 1 - d1;
  118. view(unsigned short(x), unsigned short(y)) = Pixel((int)(d1 * 255), (int)(d1 * 255), 255);
  119. view(unsigned short(x) + 1, unsigned short(y)) = Pixel((int)(d2 * 255), (int)(d2 * 255), 255);
  120. }
  121. }
  122. }
  123. /// DrawThisCircle, function used in WndProc()
  124. void DrawThisCircle(View& view,
  125. const unsigned short& x1, const unsigned short& y1,
  126. const unsigned short& x2, const unsigned short& y2)
  127. {
  128. //Circle1Div4(view, x1, y1, x2, y2);
  129. //MidpointCircle1(view, x1, y1, x2, y2);
  130. MidpointCircle2(view, x1, y1, x2, y2);
  131.  
  132. // fail
  133. //Ellipsis(view, x1, y1, 50, 35);
  134. };
  135. /// FloodThisArea, function used in WndProc()
  136. void FloodThisArea(View& view, const unsigned short& x, const unsigned short& y)
  137. {
  138. // NOTE: both works for small areas, due to perhaps filling the heap memory with recurrence calls
  139.  
  140. //BoundryFill1Div4(view, x, y, Pixel(255, 0, 0), Pixel(0, 0, 255)); // works fine for small circles
  141. BoundryFill1Div8(view, x, y, Pixel(255, 0, 0), Pixel(0, 0, 255)); // for know reasons ka-boom when circle
  142. };
  143.  
  144. ////////////////////////////////////////////////////////////////////////////////
  145.  
  146.  
  147. //
  148. void AntiAliasingDda(View& view, const unsigned short& x1, const unsigned short& y1,
  149. const unsigned short& x2, const unsigned short& y2)
  150. {
  151. // coordinates variables
  152. int x = x1;
  153. float y = y1;
  154.  
  155. // y = a*x + b, linear function
  156. const float a = float(y2 - y1) / float(x2 - x1);
  157.  
  158. const float lower_no_anti_aliasing_tolerance = 0.25f;
  159. const float higher_no_anti_aliasing_tolerance = 0.75f;
  160.  
  161. float anti_aliasing_delta_y = 0.0f;
  162.  
  163.  
  164. unsigned char down_color = 0, up_color = 0;
  165.  
  166. for (x, y; x < x2; ++x, y += a)
  167. {
  168. anti_aliasing_delta_y = y - static_cast<unsigned int>(y);
  169.  
  170. if (anti_aliasing_delta_y < lower_no_anti_aliasing_tolerance)
  171. {
  172. view(x, unsigned short(y)) = Pixel(0, 0, 255); // simplifying down
  173. }
  174. else if (anti_aliasing_delta_y > higher_no_anti_aliasing_tolerance)
  175. {
  176. view(x, unsigned short(y) + 1) = Pixel(0, 0, 255); // simplifying up
  177. }
  178. else
  179. {
  180. down_color = static_cast<unsigned char>(anti_aliasing_delta_y * 255);
  181. up_color = 255 - down_color;
  182. view(x, unsigned short(y)) = Pixel(down_color, down_color, 255);
  183. view(x, unsigned short(y) + 1) = Pixel(up_color, up_color, 255);
  184. }
  185. };
  186. }
  187.  
  188. //
  189. void SymmetricDda(View& view, const unsigned short& x1, const unsigned short& y1,
  190. const unsigned short& x2, const unsigned short& y2)
  191. {
  192. short delta_x = x2 - x1;
  193. short delta_y = y2 - y1;
  194.  
  195. bool positive_delta_x = delta_x >= 0;
  196. bool positive_delta_y = delta_y >= 0;
  197.  
  198. // maximum of two absolute values
  199. short max_of_deltas = std::abs(delta_x) > std::abs(delta_y) ? std::abs(delta_x) : std::abs(delta_y);
  200.  
  201. // log2(max_of_deltas)
  202. short n = short(std::logf((float)max_of_deltas) / std::logf(2.0f));
  203. short pow_2_n = static_cast<short>(std::pow(2.0f, n));
  204. // the 2^(n-1) case
  205. if (pow_2_n < max_of_deltas)
  206. {
  207. pow_2_n = static_cast<short>(std::pow(2.0f, (++n)));
  208. };
  209.  
  210. float epsilon = 1.0f / pow_2_n;
  211. float increment_x = epsilon * delta_x;
  212. float increment_y = epsilon * delta_y;
  213.  
  214. float x = positive_delta_x ? (x1 + 0.5f) : (x1 - 0.5f);
  215. float y = positive_delta_y ? (y1 + 0.5f) : (y1 - 0.5f);
  216.  
  217.  
  218. for (;;) // for is faster then while
  219. {
  220. if (x >= view.width() || y >= view.height() ||
  221. (positive_delta_x ? (x > x2) : (x < x2)) ||
  222. (positive_delta_y ? (y > y2) : (y < y2)))
  223. {
  224. break;
  225. };
  226.  
  227. // without anti-aliasing
  228. view(unsigned short(x), unsigned short(y)) = Pixel(0, 0, 255);
  229.  
  230. x += increment_x;
  231. y += increment_y;
  232. }
  233. }
  234.  
  235. //
  236. void Bresenhama(View& view, const unsigned short& x1, const unsigned short& y1,
  237. const unsigned short& x2, const unsigned short& y2)
  238. {
  239. unsigned short delta_x = x2 - x1;
  240. unsigned short delta_y = y2 - y1;
  241.  
  242. short delta = 2 * delta_y - delta_x;
  243.  
  244. short increment_e = 2 * delta_y;
  245. short increment_ne = 2 * (delta_y - delta_x);
  246.  
  247. unsigned short x = x1, y = y1;
  248. Iterator_XY position = view.xy_at(x, y);
  249.  
  250. *position = Pixel(0, 0, 255);
  251.  
  252.  
  253. for (; x < x2; ++x, ++position.x())
  254. {
  255. if (delta <= 0)
  256. {
  257. delta += increment_e;
  258. //++x; ++position.x();
  259. }
  260. else
  261. {
  262. delta += increment_ne;
  263. //++x; ++position.x();
  264. ++position.y(); // going north, that is south in this coordinate system :)
  265. };
  266.  
  267. *position = Pixel(0, 0, 255);
  268. }
  269. }
  270.  
  271.  
  272. ////////////////////////////////////////////////////////////////////////////////
  273.  
  274.  
  275. // draw 4 pixels
  276. void Draw4Pixels(View& view, const unsigned short& x, const unsigned short& y,
  277. const unsigned short& dx, const unsigned short& dy)
  278. {
  279. unsigned short safet_variable_x, safet_variable_y;
  280.  
  281. safet_variable_x = x + dx;
  282. if (safet_variable_x < view.width())
  283. {
  284. safet_variable_y = y + dy;
  285. if (safet_variable_y < view.height())
  286. {
  287. view(safet_variable_x, safet_variable_y) = Pixel(0, 0, 255);
  288. }
  289. safet_variable_y = y - dy;
  290. if (safet_variable_y < view.height())
  291. {
  292. view(safet_variable_x, safet_variable_y) = Pixel(0, 0, 255);
  293. }
  294. }
  295.  
  296. safet_variable_x = x - dx;
  297. if (safet_variable_x < view.width())
  298. {
  299. safet_variable_y = y + dy;
  300. if (safet_variable_y < view.height())
  301. {
  302. view(safet_variable_x, safet_variable_y) = Pixel(0, 0, 255);
  303. }
  304. safet_variable_y = y - dy;
  305. if (safet_variable_y < view.height())
  306. {
  307. view(safet_variable_x, safet_variable_y) = Pixel(0, 0, 255);
  308. }
  309. }
  310. }
  311.  
  312. // draw Bresenhama circle 1/4 (old lab task)
  313. void Circle1Div4(View& view, const unsigned short& x1, const unsigned short& y1,
  314. const unsigned short& x2, const unsigned short& y2)
  315. {
  316. const short radius = static_cast<short>(std::sqrt(
  317. std::pow(static_cast<float>(x2 - x1), 2.0f) +
  318. std::pow(static_cast<float>(y2 - y1), 2.0f)));
  319. unsigned short x = 0;
  320. unsigned short y = radius;
  321. short delta = 2 - 2 * radius;
  322. short sigma;
  323.  
  324. for (;;)
  325. {
  326. // draw 4 pixels
  327. Draw4Pixels(view, x1, y1, x, y);
  328.  
  329. if ((x == radius) && (y == 0))
  330. {
  331. break;
  332. };
  333.  
  334. //sigma = delta + delta;
  335. sigma = 2 * delta;
  336. if (sigma < 0)
  337. {
  338. sigma += 2 * y - 1;
  339. if (sigma > 0) // choice D
  340. {
  341. ++x;
  342. --y;
  343. delta += 2 * (x - y + 1);
  344. }
  345. else // choice H
  346. {
  347. ++x;
  348. delta += 2 * x + 1;
  349. }
  350. }
  351. else
  352. {
  353. sigma += -2 * x + 1;
  354. if (sigma <= 0) // choise D
  355. {
  356. ++x;
  357. --y;
  358. delta += 2 * (x - y + 1);
  359. }
  360. else // choise V
  361. {
  362. --y;
  363. delta += -2 * y + 1;
  364. }
  365. }
  366. }
  367. }
  368.  
  369. //
  370. void MidpointCircle1(View& view, const unsigned short& x1, const unsigned short& y1,
  371. const unsigned short& x2, const unsigned short& y2)
  372. {
  373. const short radius = static_cast<short>(std::sqrt(
  374. std::pow(static_cast<float>(x2 - x1), 2.0f) +
  375. std::pow(static_cast<float>(y2 - y1), 2.0f)));
  376. unsigned short x = 0;
  377. unsigned short y = radius;
  378. short delta = 5 - 4 * radius;
  379.  
  380. Draw4Pixels(view, x1, y1, x, y); // horizontal
  381. Draw4Pixels(view, x1, y1, y, x); // vertical
  382.  
  383. for (;;)
  384. {
  385. if (x > y)
  386. {
  387. break;
  388. }
  389.  
  390. if (delta < 0)
  391. {
  392. delta += 4 * (2 * x + 3);
  393. }
  394. else
  395. {
  396. delta += 4 * (2 * (x - y) + 5);
  397. --y;
  398. }
  399.  
  400. ++x;
  401. Draw4Pixels(view, x1, y1, x, y); // horizontal
  402. Draw4Pixels(view, x1, y1, y, x); // vertical
  403. }
  404. }
  405.  
  406. //
  407. void MidpointCircle2(View& view, const unsigned short& x1, const unsigned short& y1,
  408. const unsigned short& x2, const unsigned short& y2)
  409. {
  410. const short radius = static_cast<short>(std::sqrt(
  411. std::pow(static_cast<float>(x2 - x1), 2.0f) +
  412. std::pow(static_cast<float>(y2 - y1), 2.0f)));
  413. unsigned short x = 0;
  414. unsigned short y = radius;
  415. short delta = 5 - radius * 4;
  416. short delta_e = 3 * 4;
  417. short delta_se = 4 * (5 - 2 * radius);
  418.  
  419. Draw4Pixels(view, x1, y1, x, y); // horizontal
  420. Draw4Pixels(view, x1, y1, y, x); // vertical
  421.  
  422. for (;;)
  423. {
  424. if (x >= y)
  425. {
  426. break;
  427. }
  428.  
  429. if (delta < 0)
  430. {
  431. delta += delta_e;
  432. delta_e += 2 * 4;
  433. delta_se += 2 * 4;
  434. }
  435. else
  436. {
  437. delta += delta_se;
  438. delta_e += 2 * 4;
  439. delta_se += 4 * 4;
  440. --y;
  441. }
  442.  
  443. ++x;
  444. Draw4Pixels(view, x1, y1, x, y); // horizontal
  445. Draw4Pixels(view, x1, y1, y, x); // vertical
  446. }
  447. }
  448.  
  449.  
  450. ////////////////////////////////////////////////////////////////////////////////
  451.  
  452.  
  453. // TODO correct the code
  454. void Ellipsis(View& view, const unsigned short& x1, const unsigned short& y1,
  455. const unsigned short& a, const unsigned short& b)
  456. {
  457. unsigned short x = 0;
  458. unsigned short y = b;
  459.  
  460. unsigned short aa = a * a;
  461. unsigned short bb = b * b;
  462.  
  463. short delta = 4 * bb - 4 * b*aa + aa;
  464. short condition = (aa * aa) / (aa + bb);
  465.  
  466. Draw4Pixels(view, x1, y1, x, y); // horizontal
  467. Draw4Pixels(view, x1, y1, y, x); // vertical
  468.  
  469. for (;;)
  470. {
  471. if (x*x > condition)
  472. {
  473. break;
  474. }
  475.  
  476. if (delta < 0)
  477. {
  478. delta += 4 * (2 * x*bb + 3 * bb);
  479. }
  480. else
  481. {
  482. delta += 4 * (2 * bb*(x - y) + 3 * bb + 2 * aa);
  483. //delta += 4*(2*bb*x - 2*aa*y + 3*bb + 2*aa);
  484. --y;
  485. }
  486.  
  487. ++x;
  488. Draw4Pixels(view, x1, y1, x, y); // horizontal
  489. Draw4Pixels(view, x1, y1, y, x); // vertical
  490. }
  491.  
  492. x = 0;
  493. y = a;
  494. aa = b * b;
  495. bb = a * a;
  496. condition = (bb * bb) / (bb + aa);
  497.  
  498. Draw4Pixels(view, x1, y1, x, y); // horizontal
  499. Draw4Pixels(view, x1, y1, y, x); // vertical
  500.  
  501. for (;;)
  502. {
  503. if (x*x > condition)
  504. {
  505. break;
  506. }
  507.  
  508. if (delta < 0)
  509. {
  510. delta += 4 * (2 * x*bb + 3 * bb);
  511. }
  512. else
  513. {
  514. delta += 4 * (2 * bb*(x - y) + 3 * bb + 2 * aa);
  515. //delta += 4*(2*bb*x - 2*aa*y + 3*bb + 2*aa);
  516. --y;
  517. }
  518.  
  519. ++x;
  520. Draw4Pixels(view, x1, y1, x, y); // horizontal
  521. Draw4Pixels(view, x1, y1, y, x); // vertical
  522. }
  523. }
  524.  
  525.  
  526. ////////////////////////////////////////////////////////////////////////////////
  527.  
  528.  
  529. // works for small areas, due to perhaps filling the heap memory with recurrence calls
  530. void BoundryFill1Div4(View& view, const unsigned short& x, const unsigned short& y,
  531. const Pixel& fill_color, const Pixel& border_color)
  532. {
  533. Pixel color = view(x, y);
  534. if ((color != fill_color) && (color != border_color))
  535. {
  536. view(x, y) = fill_color;
  537.  
  538. BoundryFill1Div4(view, x + 1, y, fill_color, border_color);
  539. BoundryFill1Div4(view, x - 1, y, fill_color, border_color);
  540. BoundryFill1Div4(view, x, y + 1, fill_color, border_color);
  541. BoundryFill1Div4(view, x, y - 1, fill_color, border_color);
  542. }
  543. }
  544.  
  545. // works for small quadratic-like areas, due to perhaps filling the heap memory with recurrence calls
  546. void BoundryFill1Div8(View& view, const unsigned short& x, const unsigned short& y,
  547. const Pixel& fill_color, const Pixel& border_color)
  548. {
  549. // NOTE: the eight neighbourhood implementation is useless when dealing with e.g. circles
  550.  
  551. Pixel color = view(x, y);
  552. if ((color != fill_color) && (color != border_color))
  553. {
  554. view(x, y) = fill_color;
  555.  
  556. BoundryFill1Div8(view, x + 1, y, fill_color, border_color);
  557. BoundryFill1Div8(view, x - 1, y, fill_color, border_color);
  558. BoundryFill1Div8(view, x, y + 1, fill_color, border_color);
  559. BoundryFill1Div8(view, x, y - 1, fill_color, border_color);
  560. BoundryFill1Div8(view, x + 1, y + 1, fill_color, border_color);
  561. BoundryFill1Div8(view, x + 1, y - 1, fill_color, border_color);
  562. BoundryFill1Div8(view, x - 1, y + 1, fill_color, border_color);
  563. BoundryFill1Div8(view, x - 1, y - 1, fill_color, border_color);
  564. }
  565. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement