Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include "GDI+ image.h"
- typedef boost::gil::bgr8_pixel_t Pixel;
- typedef boost::gil::bgr8_view_t View;
- typedef boost::gil::bgr8c_view_t ViewReadOnly;
- typedef boost::gil::bgr8_view_t::x_iterator Iterator_X;
- typedef boost::gil::bgr8_view_t::y_iterator Iterator_Y;
- typedef boost::gil::bgr8_view_t::locator Iterator_XY;
- /// READ ME FIRST
- void TheLookAtMeFakeFunction(View& view, const unsigned short& x, const unsigned short& y)
- {
- // a View is the access to image's pixels ect.
- // pixel access, slow but easy to understand
- view(x, y);
- view(x, y) = Pixel(0, 0, 255); // blue, green, red channels
- // pixel access, optimalize for small x/y increments
- Iterator_XY position = view.xy_at(x, y);
- *position = Pixel(0, 0, 255);
- ++position.x(); // point at pixel(x+1, y)
- --position.y(); // point at pixel(x, y-1)
- // pixel access, row and column interators
- unsigned int row_number = 0;
- unsigned int column_number = 0;
- Iterator_X itr_x = view.row_begin(row_number);
- Iterator_Y itr_y = view.col_begin(column_number);
- // the Windows applications coordinates system is used in this code
- // origin point (0, 0) in the left upper corner
- // do not forget: pixel(b,g,r), full_red(0, 0, 255), bright_red(130, 130, 255)
- };
- ////////////////////////////////////////////////////////////////////////////////
- // function declarations, draw line
- void AntiAliasingDda(View& view, const unsigned short& x1, const unsigned short& y1,
- const unsigned short& x2, const unsigned short& y2);
- void SymmetricDda(View& view, const unsigned short& x1, const unsigned short& y1,
- const unsigned short& x2, const unsigned short& y2);
- void Bresenhama(View& view, const unsigned short& x1, const unsigned short& y1,
- const unsigned short& x2, const unsigned short& y2);
- // function declarations, draw circle
- void Circle1Div4(View& view, const unsigned short& x1, const unsigned short& y1,
- const unsigned short& x2, const unsigned short& y2);
- void MidpointCircle1(View& view, const unsigned short& x1, const unsigned short& y1,
- const unsigned short& x2, const unsigned short& y2);
- void MidpointCircle2(View& view, const unsigned short& x1, const unsigned short& y1,
- const unsigned short& x2, const unsigned short& y2);
- // function declarations, draw eliphsis
- void Ellipsis(View& view, const unsigned short& x1, const unsigned short& y1,
- const unsigned short& a, const unsigned short& b);
- // function declarations, flood area
- void BoundryFill1Div4(View& view, const unsigned short& x, const unsigned short& y,
- const Pixel& fill_color, const Pixel& border_color);
- void BoundryFill1Div8(View& view, const unsigned short& x, const unsigned short& y,
- const Pixel& fill_color, const Pixel& border_color);
- ////////////////////////////////////////////////////////////////////////////////
- /// DrawThisLine, function used in WndProc()
- void DrawThisLine(View& view,
- const unsigned short& x1, const unsigned short& y1,
- const unsigned short& x2, const unsigned short& y2)
- {
- // NOTE: Pixel(0, 0, 255) is red it's a BGR channel
- //AntiAliasingDda(view, x1, y1, x2, y2);
- //SymmetricDda(view, x1, y1, x2, y2);
- //Bresenhama(view, x1, y1, x2, y2);
- double x, xk;
- double m, y, yk;
- double d1, d2;
- x = x1 < x2 ? x1 : x2;
- xk = x1 < x2 ? x2 : x1;
- y = x1 < x2 ? (double)y1 : (double)y2;
- yk = x1 < x2 ? (double)y2 : (double)y1;
- m = (double)(yk - y) / (double)(xk - x);
- if (abs(m) < 1)
- {
- view(unsigned short(x), unsigned short(y)) = Pixel(0, 0, 255);
- while (x < xk)
- {
- x = x + 1;
- y = y + m; /* wyliczanie przyrostowo wartosci y*/
- d1 = abs(unsigned short(y) - y);
- d2 = 1 - d1;
- view(unsigned short(x), unsigned short(y)) = Pixel((int)(d1 * 255), (int)(d1 * 255), 255);
- view(unsigned short(x), unsigned short(y) + 1) = Pixel((int)(d2 * 255), (int)(d2 * 255), 255);
- }
- }
- else
- {
- x = y1 < y2 ? x1 : x2;
- xk = y1 < y2 ? x2 : x1;
- y = y1 < y2 ? (double)y1 : (double)y2;
- yk = y1 < y2 ? (double)y2 : (double)y1;
- view(unsigned short(x), unsigned short(y)) = Pixel(0, 0, 255);
- while (y < yk)
- {
- y = y + 1;
- x = x + 1 / m; /* wyliczanie przyrostowo wartosci x*/
- d1 = abs(unsigned short(x) - x);
- d2 = 1 - d1;
- view(unsigned short(x), unsigned short(y)) = Pixel((int)(d1 * 255), (int)(d1 * 255), 255);
- view(unsigned short(x) + 1, unsigned short(y)) = Pixel((int)(d2 * 255), (int)(d2 * 255), 255);
- }
- }
- }
- /// DrawThisCircle, function used in WndProc()
- void DrawThisCircle(View& view,
- const unsigned short& x1, const unsigned short& y1,
- const unsigned short& x2, const unsigned short& y2)
- {
- //Circle1Div4(view, x1, y1, x2, y2);
- //MidpointCircle1(view, x1, y1, x2, y2);
- MidpointCircle2(view, x1, y1, x2, y2);
- // fail
- //Ellipsis(view, x1, y1, 50, 35);
- };
- /// FloodThisArea, function used in WndProc()
- void FloodThisArea(View& view, const unsigned short& x, const unsigned short& y)
- {
- // NOTE: both works for small areas, due to perhaps filling the heap memory with recurrence calls
- //BoundryFill1Div4(view, x, y, Pixel(255, 0, 0), Pixel(0, 0, 255)); // works fine for small circles
- BoundryFill1Div8(view, x, y, Pixel(255, 0, 0), Pixel(0, 0, 255)); // for know reasons ka-boom when circle
- };
- ////////////////////////////////////////////////////////////////////////////////
- //
- void AntiAliasingDda(View& view, const unsigned short& x1, const unsigned short& y1,
- const unsigned short& x2, const unsigned short& y2)
- {
- // coordinates variables
- int x = x1;
- float y = y1;
- // y = a*x + b, linear function
- const float a = float(y2 - y1) / float(x2 - x1);
- const float lower_no_anti_aliasing_tolerance = 0.25f;
- const float higher_no_anti_aliasing_tolerance = 0.75f;
- float anti_aliasing_delta_y = 0.0f;
- unsigned char down_color = 0, up_color = 0;
- for (x, y; x < x2; ++x, y += a)
- {
- anti_aliasing_delta_y = y - static_cast<unsigned int>(y);
- if (anti_aliasing_delta_y < lower_no_anti_aliasing_tolerance)
- {
- view(x, unsigned short(y)) = Pixel(0, 0, 255); // simplifying down
- }
- else if (anti_aliasing_delta_y > higher_no_anti_aliasing_tolerance)
- {
- view(x, unsigned short(y) + 1) = Pixel(0, 0, 255); // simplifying up
- }
- else
- {
- down_color = static_cast<unsigned char>(anti_aliasing_delta_y * 255);
- up_color = 255 - down_color;
- view(x, unsigned short(y)) = Pixel(down_color, down_color, 255);
- view(x, unsigned short(y) + 1) = Pixel(up_color, up_color, 255);
- }
- };
- }
- //
- void SymmetricDda(View& view, const unsigned short& x1, const unsigned short& y1,
- const unsigned short& x2, const unsigned short& y2)
- {
- short delta_x = x2 - x1;
- short delta_y = y2 - y1;
- bool positive_delta_x = delta_x >= 0;
- bool positive_delta_y = delta_y >= 0;
- // maximum of two absolute values
- short max_of_deltas = std::abs(delta_x) > std::abs(delta_y) ? std::abs(delta_x) : std::abs(delta_y);
- // log2(max_of_deltas)
- short n = short(std::logf((float)max_of_deltas) / std::logf(2.0f));
- short pow_2_n = static_cast<short>(std::pow(2.0f, n));
- // the 2^(n-1) case
- if (pow_2_n < max_of_deltas)
- {
- pow_2_n = static_cast<short>(std::pow(2.0f, (++n)));
- };
- float epsilon = 1.0f / pow_2_n;
- float increment_x = epsilon * delta_x;
- float increment_y = epsilon * delta_y;
- float x = positive_delta_x ? (x1 + 0.5f) : (x1 - 0.5f);
- float y = positive_delta_y ? (y1 + 0.5f) : (y1 - 0.5f);
- for (;;) // for is faster then while
- {
- if (x >= view.width() || y >= view.height() ||
- (positive_delta_x ? (x > x2) : (x < x2)) ||
- (positive_delta_y ? (y > y2) : (y < y2)))
- {
- break;
- };
- // without anti-aliasing
- view(unsigned short(x), unsigned short(y)) = Pixel(0, 0, 255);
- x += increment_x;
- y += increment_y;
- }
- }
- //
- void Bresenhama(View& view, const unsigned short& x1, const unsigned short& y1,
- const unsigned short& x2, const unsigned short& y2)
- {
- unsigned short delta_x = x2 - x1;
- unsigned short delta_y = y2 - y1;
- short delta = 2 * delta_y - delta_x;
- short increment_e = 2 * delta_y;
- short increment_ne = 2 * (delta_y - delta_x);
- unsigned short x = x1, y = y1;
- Iterator_XY position = view.xy_at(x, y);
- *position = Pixel(0, 0, 255);
- for (; x < x2; ++x, ++position.x())
- {
- if (delta <= 0)
- {
- delta += increment_e;
- //++x; ++position.x();
- }
- else
- {
- delta += increment_ne;
- //++x; ++position.x();
- ++position.y(); // going north, that is south in this coordinate system :)
- };
- *position = Pixel(0, 0, 255);
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // draw 4 pixels
- void Draw4Pixels(View& view, const unsigned short& x, const unsigned short& y,
- const unsigned short& dx, const unsigned short& dy)
- {
- unsigned short safet_variable_x, safet_variable_y;
- safet_variable_x = x + dx;
- if (safet_variable_x < view.width())
- {
- safet_variable_y = y + dy;
- if (safet_variable_y < view.height())
- {
- view(safet_variable_x, safet_variable_y) = Pixel(0, 0, 255);
- }
- safet_variable_y = y - dy;
- if (safet_variable_y < view.height())
- {
- view(safet_variable_x, safet_variable_y) = Pixel(0, 0, 255);
- }
- }
- safet_variable_x = x - dx;
- if (safet_variable_x < view.width())
- {
- safet_variable_y = y + dy;
- if (safet_variable_y < view.height())
- {
- view(safet_variable_x, safet_variable_y) = Pixel(0, 0, 255);
- }
- safet_variable_y = y - dy;
- if (safet_variable_y < view.height())
- {
- view(safet_variable_x, safet_variable_y) = Pixel(0, 0, 255);
- }
- }
- }
- // draw Bresenhama circle 1/4 (old lab task)
- void Circle1Div4(View& view, const unsigned short& x1, const unsigned short& y1,
- const unsigned short& x2, const unsigned short& y2)
- {
- const short radius = static_cast<short>(std::sqrt(
- std::pow(static_cast<float>(x2 - x1), 2.0f) +
- std::pow(static_cast<float>(y2 - y1), 2.0f)));
- unsigned short x = 0;
- unsigned short y = radius;
- short delta = 2 - 2 * radius;
- short sigma;
- for (;;)
- {
- // draw 4 pixels
- Draw4Pixels(view, x1, y1, x, y);
- if ((x == radius) && (y == 0))
- {
- break;
- };
- //sigma = delta + delta;
- sigma = 2 * delta;
- if (sigma < 0)
- {
- sigma += 2 * y - 1;
- if (sigma > 0) // choice D
- {
- ++x;
- --y;
- delta += 2 * (x - y + 1);
- }
- else // choice H
- {
- ++x;
- delta += 2 * x + 1;
- }
- }
- else
- {
- sigma += -2 * x + 1;
- if (sigma <= 0) // choise D
- {
- ++x;
- --y;
- delta += 2 * (x - y + 1);
- }
- else // choise V
- {
- --y;
- delta += -2 * y + 1;
- }
- }
- }
- }
- //
- void MidpointCircle1(View& view, const unsigned short& x1, const unsigned short& y1,
- const unsigned short& x2, const unsigned short& y2)
- {
- const short radius = static_cast<short>(std::sqrt(
- std::pow(static_cast<float>(x2 - x1), 2.0f) +
- std::pow(static_cast<float>(y2 - y1), 2.0f)));
- unsigned short x = 0;
- unsigned short y = radius;
- short delta = 5 - 4 * radius;
- Draw4Pixels(view, x1, y1, x, y); // horizontal
- Draw4Pixels(view, x1, y1, y, x); // vertical
- for (;;)
- {
- if (x > y)
- {
- break;
- }
- if (delta < 0)
- {
- delta += 4 * (2 * x + 3);
- }
- else
- {
- delta += 4 * (2 * (x - y) + 5);
- --y;
- }
- ++x;
- Draw4Pixels(view, x1, y1, x, y); // horizontal
- Draw4Pixels(view, x1, y1, y, x); // vertical
- }
- }
- //
- void MidpointCircle2(View& view, const unsigned short& x1, const unsigned short& y1,
- const unsigned short& x2, const unsigned short& y2)
- {
- const short radius = static_cast<short>(std::sqrt(
- std::pow(static_cast<float>(x2 - x1), 2.0f) +
- std::pow(static_cast<float>(y2 - y1), 2.0f)));
- unsigned short x = 0;
- unsigned short y = radius;
- short delta = 5 - radius * 4;
- short delta_e = 3 * 4;
- short delta_se = 4 * (5 - 2 * radius);
- Draw4Pixels(view, x1, y1, x, y); // horizontal
- Draw4Pixels(view, x1, y1, y, x); // vertical
- for (;;)
- {
- if (x >= y)
- {
- break;
- }
- if (delta < 0)
- {
- delta += delta_e;
- delta_e += 2 * 4;
- delta_se += 2 * 4;
- }
- else
- {
- delta += delta_se;
- delta_e += 2 * 4;
- delta_se += 4 * 4;
- --y;
- }
- ++x;
- Draw4Pixels(view, x1, y1, x, y); // horizontal
- Draw4Pixels(view, x1, y1, y, x); // vertical
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // TODO correct the code
- void Ellipsis(View& view, const unsigned short& x1, const unsigned short& y1,
- const unsigned short& a, const unsigned short& b)
- {
- unsigned short x = 0;
- unsigned short y = b;
- unsigned short aa = a * a;
- unsigned short bb = b * b;
- short delta = 4 * bb - 4 * b*aa + aa;
- short condition = (aa * aa) / (aa + bb);
- Draw4Pixels(view, x1, y1, x, y); // horizontal
- Draw4Pixels(view, x1, y1, y, x); // vertical
- for (;;)
- {
- if (x*x > condition)
- {
- break;
- }
- if (delta < 0)
- {
- delta += 4 * (2 * x*bb + 3 * bb);
- }
- else
- {
- delta += 4 * (2 * bb*(x - y) + 3 * bb + 2 * aa);
- //delta += 4*(2*bb*x - 2*aa*y + 3*bb + 2*aa);
- --y;
- }
- ++x;
- Draw4Pixels(view, x1, y1, x, y); // horizontal
- Draw4Pixels(view, x1, y1, y, x); // vertical
- }
- x = 0;
- y = a;
- aa = b * b;
- bb = a * a;
- condition = (bb * bb) / (bb + aa);
- Draw4Pixels(view, x1, y1, x, y); // horizontal
- Draw4Pixels(view, x1, y1, y, x); // vertical
- for (;;)
- {
- if (x*x > condition)
- {
- break;
- }
- if (delta < 0)
- {
- delta += 4 * (2 * x*bb + 3 * bb);
- }
- else
- {
- delta += 4 * (2 * bb*(x - y) + 3 * bb + 2 * aa);
- //delta += 4*(2*bb*x - 2*aa*y + 3*bb + 2*aa);
- --y;
- }
- ++x;
- Draw4Pixels(view, x1, y1, x, y); // horizontal
- Draw4Pixels(view, x1, y1, y, x); // vertical
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // works for small areas, due to perhaps filling the heap memory with recurrence calls
- void BoundryFill1Div4(View& view, const unsigned short& x, const unsigned short& y,
- const Pixel& fill_color, const Pixel& border_color)
- {
- Pixel color = view(x, y);
- if ((color != fill_color) && (color != border_color))
- {
- view(x, y) = fill_color;
- BoundryFill1Div4(view, x + 1, y, fill_color, border_color);
- BoundryFill1Div4(view, x - 1, y, fill_color, border_color);
- BoundryFill1Div4(view, x, y + 1, fill_color, border_color);
- BoundryFill1Div4(view, x, y - 1, fill_color, border_color);
- }
- }
- // works for small quadratic-like areas, due to perhaps filling the heap memory with recurrence calls
- void BoundryFill1Div8(View& view, const unsigned short& x, const unsigned short& y,
- const Pixel& fill_color, const Pixel& border_color)
- {
- // NOTE: the eight neighbourhood implementation is useless when dealing with e.g. circles
- Pixel color = view(x, y);
- if ((color != fill_color) && (color != border_color))
- {
- view(x, y) = fill_color;
- BoundryFill1Div8(view, x + 1, y, fill_color, border_color);
- BoundryFill1Div8(view, x - 1, y, fill_color, border_color);
- BoundryFill1Div8(view, x, y + 1, fill_color, border_color);
- BoundryFill1Div8(view, x, y - 1, fill_color, border_color);
- BoundryFill1Div8(view, x + 1, y + 1, fill_color, border_color);
- BoundryFill1Div8(view, x + 1, y - 1, fill_color, border_color);
- BoundryFill1Div8(view, x - 1, y + 1, fill_color, border_color);
- BoundryFill1Div8(view, x - 1, y - 1, fill_color, border_color);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement