Advertisement
m4ly

RAS

Mar 29th, 2015
383
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 16.50 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. void abc(View& view, const unsigned short& x1, const unsigned short& y1,
  68.                   const unsigned short& x2, const unsigned short& y2);
  69. /////////////////////////////////////////////////////////////////////////////
  70.  
  71.  
  72. void my_line(View &view, unsigned short &x1, unsigned short &y1,   const unsigned short& x2, const unsigned short& y2)
  73. {
  74.    
  75.    
  76.     int i, j, k;
  77.     double x, y;
  78.     double x_inc, y_inc;
  79.  
  80.  
  81.  
  82.  
  83.  
  84. }
  85.  
  86. /// DrawThisLine, function used in WndProc()
  87. void DrawThisLine(View& view,
  88.                   const unsigned short& x1, const unsigned short& y1,
  89.                   const unsigned short& x2, const unsigned short& y2)
  90. {
  91.    
  92.    
  93.     // NOTE: Pixel(0, 0, 255) is red it's a BGR channel
  94.  
  95.     //AntiAliasingDda(view, x1, y1, x2, y2);
  96.     //SymmetricDda(view, x1, y1, x2, y2);
  97.     //Bresenhama(view, x1, y1, x2, y2);
  98.     abc(view, x1, y1, x2, y2);
  99.  
  100. }
  101. /// DrawThisCircle, function used in WndProc()
  102. void DrawThisCircle(View& view,
  103.                     const unsigned short& x1, const unsigned short& y1,
  104.                     const unsigned short& x2, const unsigned short& y2)
  105. {
  106.     //Circle1Div4(view, x1, y1, x2, y2);
  107.     //MidpointCircle1(view, x1, y1, x2, y2);
  108.     MidpointCircle2(view, x1, y1, x2, y2);
  109.  
  110.     // fail
  111.     //Ellipsis(view, x1, y1, 50, 35);
  112. };
  113. /// FloodThisArea, function used in WndProc()
  114. void FloodThisArea(View& view, const unsigned short& x, const unsigned short& y)
  115. {
  116.     // NOTE: both works for small areas, due to perhaps filling the heap memory with recurrence calls
  117.  
  118.     //BoundryFill1Div4(view, x, y, Pixel(255, 0, 0), Pixel(0, 0, 255)); // works fine for small circles
  119.     BoundryFill1Div8(view, x, y, Pixel(255, 0, 0), Pixel(0, 0, 255));   // for know reasons ka-boom when circle
  120. };
  121.  
  122. ////////////////////////////////////////////////////////////////////////////////
  123.  
  124.  
  125. //
  126. void AntiAliasingDda(View& view, const unsigned short& x1, const unsigned short& y1,
  127.                      const unsigned short& x2, const unsigned short& y2)
  128. {
  129.     // coordinates variables
  130.     int x = x1;
  131.     float y = y1;
  132.  
  133.     // y = a*x + b, linear function
  134.     const float a = float(y2 - y1) / float(x2 - x1);
  135.  
  136.     const float lower_no_anti_aliasing_tolerance = 0.25f;
  137.     const float higher_no_anti_aliasing_tolerance = 0.75f;
  138.  
  139.     float anti_aliasing_delta_y = 0.0f;
  140.    
  141.  
  142.     unsigned char down_color = 0, up_color = 0;
  143.    
  144.     for (x, y; x < x2; ++x, y += a)
  145.     {
  146.         anti_aliasing_delta_y = y - static_cast<unsigned int>(y);
  147.        
  148.         if (anti_aliasing_delta_y < lower_no_anti_aliasing_tolerance)
  149.         {
  150.             view(x, unsigned short(y)) = Pixel(0, 0, 255);      // simplifying down
  151.         }
  152.         else if (anti_aliasing_delta_y > higher_no_anti_aliasing_tolerance)
  153.         {
  154.             view(x, unsigned short(y)+1) = Pixel(0, 0, 255);    // simplifying up
  155.         }
  156.         else
  157.         {
  158.             down_color = static_cast<unsigned char>(anti_aliasing_delta_y * 255);
  159.             up_color = 255 - down_color;
  160.             view(x, unsigned short(y)) =   Pixel(down_color, down_color, 255);
  161.             view(x, unsigned short(y)+1) = Pixel(up_color, up_color, 255);
  162.         }
  163.     };
  164. }
  165.  
  166. //
  167. void SymmetricDda(View& view, const unsigned short& x1, const unsigned short& y1,
  168.                   const unsigned short& x2, const unsigned short& y2)
  169. {
  170.     short delta_x = x2 - x1;
  171.     short delta_y = y2 - y1;
  172.  
  173.     bool positive_delta_x = delta_x >= 0;
  174.     bool positive_delta_y = delta_y >= 0;
  175.    
  176.     // maximum of two absolute values
  177.     short max_of_deltas = std::abs(delta_x) > std::abs(delta_y) ? std::abs(delta_x) : std::abs(delta_y) ;
  178.  
  179.     // log2(max_of_deltas)
  180.     short n = short(std::logf((float)max_of_deltas) / std::logf(2.0f));
  181.     short pow_2_n = static_cast<short>(std::pow(2.0f, n));
  182.     // the 2^(n-1) case
  183.     if (pow_2_n < max_of_deltas)
  184.     {
  185.         pow_2_n = static_cast<short>(std::pow(2.0f, (++n)));
  186.     };
  187.  
  188.     float epsilon = 1.0f / pow_2_n;
  189.     float increment_x = epsilon * delta_x;
  190.     float increment_y = epsilon * delta_y;
  191.  
  192.     float x = positive_delta_x ? (x1 + 0.5f) : (x1 - 0.5f);
  193.     float y = positive_delta_y ? (y1 + 0.5f) : (y1 - 0.5f);
  194.    
  195.    
  196.     for (;;)    // for is faster then while
  197.     {
  198.         if (x >= view.width() || y >= view.height()  ||
  199.             (positive_delta_x ? (x > x2) : (x < x2)) ||
  200.             (positive_delta_y ? (y > y2) : (y < y2)) )
  201.         {
  202.             break;
  203.         };
  204.  
  205.         // without anti-aliasing
  206.         view(unsigned short(x), unsigned short(y)) = Pixel(0, 0, 255);
  207.        
  208.         x += increment_x;
  209.         y += increment_y;
  210.     }
  211. }
  212.  
  213. //
  214. void Bresenhama(View& view, const unsigned short& x1, const unsigned short& y1,
  215.                 const unsigned short& x2, const unsigned short& y2)
  216. {
  217.     unsigned short delta_x = x2 - x1;
  218.     unsigned short delta_y = y2 - y1;
  219.    
  220.     short delta = 2 * delta_y - delta_x;
  221.  
  222.     short increment_e  = 2 * delta_y;
  223.     short increment_ne = 2 * (delta_y - delta_x);
  224.  
  225.     unsigned short x = x1, y = y1;
  226.     Iterator_XY position = view.xy_at(x, y);
  227.    
  228.     *position = Pixel(0, 0, 255);
  229.  
  230.  
  231.     for (; x < x2 ; ++x, ++position.x())
  232.     {
  233.         if (delta <= 0)
  234.         {
  235.             delta += increment_e;
  236.             //++x; ++position.x();
  237.         }
  238.         else
  239.         {
  240.             delta += increment_ne;
  241.             //++x; ++position.x();
  242.             ++position.y();     // going north, that is south in this coordinate system :)
  243.         };
  244.  
  245.         *position = Pixel(0, 0, 255);
  246.     }
  247. }
  248.  
  249.  
  250. ////////////////////////////////////////////////////////////////////////////////
  251.  
  252.  
  253. // draw 4 pixels
  254. void Draw4Pixels(View& view, const unsigned short& x, const unsigned short& y,
  255.                  const unsigned short& dx, const unsigned short& dy)
  256. {
  257.     unsigned short safet_variable_x, safet_variable_y;
  258.  
  259.     safet_variable_x = x + dx;
  260.     if (safet_variable_x < view.width())
  261.     {
  262.         safet_variable_y = y + dy;
  263.         if (safet_variable_y < view.height())
  264.         {
  265.             view(safet_variable_x, safet_variable_y) = Pixel(0, 0, 255);
  266.         }
  267.         safet_variable_y = y - dy;
  268.         if (safet_variable_y < view.height())
  269.         {
  270.             view(safet_variable_x, safet_variable_y) = Pixel(0, 0, 255);
  271.         }
  272.     }
  273.  
  274.     safet_variable_x = x - dx;
  275.     if (safet_variable_x < view.width())
  276.     {
  277.         safet_variable_y = y + dy;
  278.         if (safet_variable_y < view.height())
  279.         {
  280.             view(safet_variable_x, safet_variable_y) = Pixel(0, 0, 255);
  281.         }
  282.         safet_variable_y = y - dy;
  283.         if (safet_variable_y < view.height())
  284.         {
  285.             view(safet_variable_x, safet_variable_y) = Pixel(0, 0, 255);
  286.         }
  287.     }
  288. }
  289.  
  290. // draw Bresenhama circle 1/4 (old lab task)
  291. void Circle1Div4(View& view, const unsigned short& x1, const unsigned short& y1,
  292.                  const unsigned short& x2, const unsigned short& y2)
  293. {
  294.     const short radius = static_cast<short>(std::sqrt(
  295.                             std::pow(static_cast<float>(x2-x1), 2.0f) +
  296.                             std::pow(static_cast<float>(y2-y1), 2.0f)));
  297.     unsigned short x = 0;
  298.     unsigned short y = radius;
  299.     short delta = 2 - 2*radius;
  300.     short sigma;
  301.    
  302.     for (;;)
  303.     {
  304.         // draw 4 pixels
  305.         Draw4Pixels(view, x1, y1, x, y);
  306.  
  307.         if ((x == radius) && (y == 0))
  308.         {
  309.             break;
  310.         };
  311.  
  312.         //sigma = delta + delta;
  313.         sigma = 2 * delta;
  314.         if (sigma < 0)
  315.         {
  316.             sigma += 2*y - 1;
  317.             if (sigma > 0)  // choice D
  318.             {
  319.                 ++x;
  320.                 --y;
  321.                 delta += 2*(x - y + 1);
  322.             }
  323.             else            // choice H
  324.             {
  325.                 ++x;
  326.                 delta += 2*x + 1;
  327.             }
  328.         }
  329.         else
  330.         {
  331.             sigma += -2*x + 1;
  332.             if (sigma <= 0) // choise D
  333.             {
  334.                 ++x;
  335.                 --y;
  336.                 delta += 2*(x - y + 1);
  337.             }
  338.             else            // choise V
  339.             {
  340.                 --y;
  341.                 delta += -2*y +1;
  342.             }
  343.         }
  344.     }
  345. }
  346.  
  347. //
  348. void MidpointCircle1(View& view, const unsigned short& x1, const unsigned short& y1,
  349.                      const unsigned short& x2, const unsigned short& y2)
  350. {
  351.     const short radius = static_cast<short>(std::sqrt(
  352.                             std::pow(static_cast<float>(x2-x1), 2.0f) +
  353.                             std::pow(static_cast<float>(y2-y1), 2.0f)));
  354.     unsigned short x = 0;
  355.     unsigned short y = radius;
  356.     short delta = 5 - 4*radius;
  357.  
  358.     Draw4Pixels(view, x1, y1, x, y);    // horizontal
  359.     Draw4Pixels(view, x1, y1, y, x);    // vertical
  360.  
  361.     for (;;)
  362.     {
  363.         if (x > y)
  364.         {
  365.             break;
  366.         }
  367.  
  368.         if (delta < 0)
  369.         {
  370.             delta += 4*(2*x + 3);
  371.         }
  372.         else
  373.         {
  374.             delta += 4*(2*(x - y) + 5);
  375.             --y;
  376.         }
  377.  
  378.         ++x;
  379.         Draw4Pixels(view, x1, y1, x, y);    // horizontal
  380.         Draw4Pixels(view, x1, y1, y, x);    // vertical
  381.     }
  382. }
  383.  
  384. //
  385. void MidpointCircle2(View& view, const unsigned short& x1, const unsigned short& y1,
  386.                     const unsigned short& x2, const unsigned short& y2)
  387. {
  388.     const short radius = static_cast<short>(std::sqrt(
  389.                             std::pow(static_cast<float>(x2-x1), 2.0f) +
  390.                             std::pow(static_cast<float>(y2-y1), 2.0f)));
  391.     unsigned short x = 0;
  392.     unsigned short y = radius;
  393.     short delta = 5 - radius * 4;
  394.     short delta_e = 3 * 4;
  395.     short delta_se = 4*(5 - 2*radius);
  396.  
  397.     Draw4Pixels(view, x1, y1, x, y);    // horizontal
  398.     Draw4Pixels(view, x1, y1, y, x);    // vertical
  399.  
  400.     for (;;)
  401.     {
  402.         if (x >= y)
  403.         {
  404.             break;
  405.         }
  406.  
  407.         if (delta < 0)
  408.         {
  409.             delta    += delta_e;
  410.             delta_e  += 2 * 4;
  411.             delta_se += 2 * 4;
  412.         }
  413.         else
  414.         {
  415.             delta    += delta_se;
  416.             delta_e  += 2 * 4;
  417.             delta_se += 4 * 4;
  418.             --y;
  419.         }
  420.  
  421.         ++x;
  422.         Draw4Pixels(view, x1, y1, x, y);    // horizontal
  423.         Draw4Pixels(view, x1, y1, y, x);    // vertical
  424.     }
  425. }
  426.  
  427.  
  428. ////////////////////////////////////////////////////////////////////////////////
  429.  
  430.  
  431. // TODO correct the code
  432. void Ellipsis(View& view, const unsigned short& x1, const unsigned short& y1,
  433.               const unsigned short& a, const unsigned short& b)
  434. {
  435.     unsigned short x = 0;
  436.     unsigned short y = b;
  437.    
  438.     unsigned short aa = a * a;
  439.     unsigned short bb = b * b;
  440.  
  441.     short delta = 4*bb - 4*b*aa + aa;
  442.     short condition = (aa * aa) / (aa + bb);
  443.  
  444.     Draw4Pixels(view, x1, y1, x, y);    // horizontal
  445.     Draw4Pixels(view, x1, y1, y, x);    // vertical
  446.  
  447.     for (;;)
  448.     {
  449.         if (x*x > condition)
  450.         {
  451.             break;
  452.         }
  453.  
  454.         if (delta < 0)
  455.         {
  456.             delta += 4*(2*x*bb + 3*bb);
  457.         }
  458.         else
  459.         {
  460.             delta += 4*(2*bb*(x - y) + 3*bb + 2*aa);
  461.             //delta += 4*(2*bb*x - 2*aa*y + 3*bb + 2*aa);
  462.             --y;
  463.         }
  464.  
  465.         ++x;
  466.         Draw4Pixels(view, x1, y1, x, y);    // horizontal
  467.         Draw4Pixels(view, x1, y1, y, x);    // vertical
  468.     }
  469.  
  470.     x = 0;
  471.     y = a;
  472.     aa = b * b;
  473.     bb = a * a;
  474.     condition = (bb * bb) / (bb + aa);
  475.  
  476.     Draw4Pixels(view, x1, y1, x, y);    // horizontal
  477.     Draw4Pixels(view, x1, y1, y, x);    // vertical
  478.  
  479.     for (;;)
  480.     {
  481.         if (x*x > condition)
  482.         {
  483.             break;
  484.         }
  485.  
  486.         if (delta < 0)
  487.         {
  488.             delta += 4*(2*x*bb + 3*bb);
  489.         }
  490.         else
  491.         {
  492.             delta += 4*(2*bb*(x - y) + 3*bb + 2*aa);
  493.             //delta += 4*(2*bb*x - 2*aa*y + 3*bb + 2*aa);
  494.             --y;
  495.         }
  496.  
  497.         ++x;
  498.         Draw4Pixels(view, x1, y1, x, y);    // horizontal
  499.         Draw4Pixels(view, x1, y1, y, x);    // vertical
  500.     }
  501. }
  502.  
  503.  
  504. ////////////////////////////////////////////////////////////////////////////////
  505.  
  506.  
  507. // works for small areas, due to perhaps filling the heap memory with recurrence calls
  508. void BoundryFill1Div4(View& view, const unsigned short& x, const unsigned short& y,
  509.                       const Pixel& fill_color, const Pixel& border_color)
  510. {
  511.     Pixel color = view(x, y);
  512.     if ((color != fill_color) && (color != border_color))
  513.     {
  514.         view(x, y) = fill_color;
  515.  
  516.         BoundryFill1Div4(view, x+1, y,   fill_color, border_color);
  517.         BoundryFill1Div4(view, x-1, y,   fill_color, border_color);
  518.         BoundryFill1Div4(view, x,   y+1, fill_color, border_color);
  519.         BoundryFill1Div4(view, x,   y-1, fill_color, border_color);
  520.     }
  521. }
  522.  
  523. // works for small quadratic-like areas, due to perhaps filling the heap memory with recurrence calls
  524. void BoundryFill1Div8(View& view, const unsigned short& x, const unsigned short& y,
  525.                       const Pixel& fill_color, const Pixel& border_color)
  526. {
  527.     // NOTE: the eight neighbourhood implementation is useless when dealing with e.g. circles
  528.  
  529.     Pixel color = view(x, y);
  530.     if ((color != fill_color) && (color != border_color))
  531.     {
  532.         view(x, y) = fill_color;
  533.  
  534.         BoundryFill1Div8(view, x+1, y,   fill_color, border_color);
  535.         BoundryFill1Div8(view, x-1, y,   fill_color, border_color);
  536.         BoundryFill1Div8(view, x,   y+1, fill_color, border_color);
  537.         BoundryFill1Div8(view, x,   y-1, fill_color, border_color);
  538.         BoundryFill1Div8(view, x+1, y+1, fill_color, border_color);
  539.         BoundryFill1Div8(view, x+1, y-1, fill_color, border_color);
  540.         BoundryFill1Div8(view, x-1, y+1, fill_color, border_color);
  541.         BoundryFill1Div8(view, x-1, y-1, fill_color, border_color);
  542.     }
  543. }
  544.  
  545.  
  546.  
  547. //osie
  548. enum axis {x, y};
  549.  
  550. void abc(View& view, const unsigned short& x1, const unsigned short& y1,
  551.                   const unsigned short& x2, const unsigned short& y2)
  552. {
  553.     double y, x;
  554.  
  555.     double x_inc, y_inc, antialias;
  556.  
  557.     int i, max;
  558.        
  559.    
  560.     int kolor_ponizej, kolor_powyzej;
  561.  
  562.     bool zamien = false;
  563.  
  564.     axis iterance_axis;
  565.  
  566.     // wiecej na y czy na x ?
  567.     if(abs(y1-y2) > abs(x1 - x2))
  568.     {
  569.         x_inc = (x2 - x1) / (double)(y2 - y1);
  570.         y_inc = 1.0f;
  571.  
  572.         // os
  573.         iterance_axis = axis::y;
  574.  
  575.         if(y2<y1)
  576.             zamien = true;
  577.        
  578.         // liczymy max
  579.         max = zamien ? (y1 - y2) : (y2 - y1);
  580.     }
  581.     else
  582.     {
  583.  
  584.         y_inc = (y2 - y1) / (double)(x2 - x1);
  585.         x_inc = 1.f;
  586.  
  587.         // os x
  588.         iterance_axis = axis::x;
  589.  
  590.         if(x2<x1)
  591.             zamien = true;
  592.  
  593.         // liczymy max
  594.         max = zamien ? (x1 - x2) : (x2 - x1);
  595.     }
  596.  
  597.     x = zamien ? x2 : x1;
  598.     y = zamien ? y2 : y1;
  599.  
  600.     for (i = 0; i <= max; i++)
  601.     {
  602.         // inkremetnacja
  603.         x += x_inc;
  604.         y += y_inc;
  605.  
  606.         if(iterance_axis == axis::x)
  607.             antialias = y - (int)(y);
  608.         else
  609.             antialias = x - (int)(x);
  610.  
  611.         if (antialias < 0.55)
  612.         {
  613.            // normlane piksle                 R G B
  614.             view(unsigned(x), unsigned(y)) = Pixel(255, 0, 0);
  615.         }
  616.         else if (antialias > 0.25)
  617.         {
  618.             // jeden kolor
  619.             iterance_axis == axis::x ? y+=1.f : x+=1.f;
  620.          
  621.             view(unsigned(x), unsigned(y)) = Pixel(255, 0, 0);
  622.             iterance_axis == axis::x ? y-=1.f : x-=1.f;
  623.         }
  624.         else
  625.         {
  626.             // dwa kolory
  627.            
  628.             kolor_ponizej = (unsigned char)(antialias * 255);
  629.             kolor_powyzej = 255 - kolor_ponizej;
  630.          
  631.             view(unsigned(x), unsigned(y)) =   Pixel(255, kolor_ponizej, kolor_ponizej);
  632.             iterance_axis == axis::x ? y+=1.f : x+=1.f;
  633.          
  634.             view(unsigned(x), unsigned(y)) = Pixel(255, kolor_powyzej, kolor_powyzej);
  635.             iterance_axis == axis::x ? y-=1.f : x-=1.f;
  636.         }
  637.        
  638.     }
  639. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement