Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Bresenham Line Implementation in C++  (Read 1955 times)

0 Members and 1 Guest are viewing this topic.

RandySavage

  • Newbie
  • *
  • Posts: 3
    • View Profile
    • Email
Bresenham Line Implementation in C++
« on: June 27, 2018, 03:41:11 pm »
Greetings, this is my first post.

I have a query.

Context:

I am using a Bresenham Line implementation using the basic sf::Image functionality in SFML C++; not OpenCV or anything like that, so I'm using Get and SetPixel to read specific (x, y) positions, rather than Points.

Content:

I want to draw a line depending on the specific sf::Colour of specific Pixels, taking an entire Image into consideration, which is read from outside the Line Function.

To do this I have a Bresenham Line Function embedded inside a For Loop, which loops through all the Pixel positions for x and y and checks for sf::Colour.

The Run portion of the Bresenham line Code is embedded in the For Loop, the Rise is outside the y portion of the Loop, as I believe that in order for the line to be drawn, with slope taken into consideration, only one position (the x Pixel or 'width' position) is necessary.

I also speculate that, if not done this way, the Run portion will not increment in the Loop, as the x and y Loop will 'take over' and make the Line think that it is always moving in vertical/horizontal directions, hence no Line is drawn.

However, if this is wrong please chime in.

Depending on an 'if' & 'else' statement in the Run portion of the Code, Pixel Colours are Set to two other Colours, corresponding roughly to the edges of the Pixel regions that have the Colour being checked for (in the original For Loop).

Expectations:

I would expect this implementation of the Line to skirt the edges of regions with Colour being checked for, it would draw lines of one Pixel in two Colours, depending on the 'direction' of the Line (corresponding to the overall x-direction of the line).

Questions:

1) The first question was raised above: is taking the Run portion of the Code outside the y Loop necessary?

2) Secondly, do I need to 'Cast' the values of specific Pixels at x and y and create new floating values at their respective current positions?

Apologies if this is a silly question, but I am not yet a master of C++.

At present I am using x and y then x1, y1 etc., as you might see in a conventional Bresenham Line implementation, but I think the specific updated Pixel Positions might need to be updated in the Function, as the Loop Runs.

I have seen people use 'Tiles' in a similar manner for Raycasting, without updating the Tile Positions in the manner I describe above. Tiles are a specific Struct in SFML (not Pixels), so I am not sure if different rules apply for them.     

3) I want to check that the Line Algorithm works; at present there are no Compiler errors in the Script and it Runs.

At first I was going to create an Array of points and push the points in the lines to the Array, however it will be easier for me to see if the line is working if I can actually draw it, on the Image in the manner I describe above.

Is there an easy way to draw the Line, as I have outlined, using SFML::Line or similar functionality that won't interfere with the overall reading/writing of the Image in the Script?

Thanks for your help with this,
Much Appreciated,
Randy Savage. 
 

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: Bresenham Line Implementation in C++
« Reply #1 on: June 28, 2018, 01:06:38 am »
I'm not sure what your expectations are, but it's unlikely that someone will look up the mentioned algorithm and then guess what your code does, just to answer some questions that otherwise can't really be answered. ;)

What's your overall goal with algorithm? And what exactly isn't working as intended?
Also helps a lot if you can show the code, so we don't have to play the guessing game.

You can draw primitives with vertex arrays and then use shaders to manipulate them to your needs.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

RandySavage

  • Newbie
  • *
  • Posts: 3
    • View Profile
    • Email
Re: Bresenham Line Implementation in C++
« Reply #2 on: June 28, 2018, 04:53:48 pm »
I am reading and writing an Image (MyImage) to a File in the Main Function, using outFN.

I want the line to get drawn, over the Image, over areas of Black Pixels; specifically the edge (or Slope) of the regions of Black Pixels. I would expect Red and Green Lines to be drawn, depending on the direction in a manner that highlights the edges of Black-Pixel Regions in the Image.

Thanks again,
Randy Savage.

RandySavage

  • Newbie
  • *
  • Posts: 3
    • View Profile
    • Email
Re: Bresenham Line Implementation in C++
« Reply #3 on: June 28, 2018, 05:14:58 pm »
void BresenhamLine(sf::Image& MyImage, char * outFN, float x1, float y1, float x2, float y2)
{
   int width = img.getSize().x;
   int height = img.getSize().y;
   int y = 0;
          const int maxX = (int)x2;
   const int ystep = (y1 < y2) ? 1 : -1;
   const float dx = x2 - x1;
   const float dy = fabs(y2 - y1);
   float error = dx / 2.0f;
   const bool Slope = (fabs(y2 - y1) > fabs(x2 - x1));

   //MyImage
   sf::Image output = MyImage;
   
   //Main Loop
   for (int x = 0; x < width; x++)
   {
      for (int y = 0; y < height; y++)
      {
         //The Run
         if (img.getPixel(x, y) == sf::Color::Black && Slope == true)
         {
            std::swap(x1, y1);
            std::swap(x2, y2);
         }

         if (img.getPixel(x, y) == sf::Color::Black && x1 > x2)
         {
            std::swap(x1, x2);
            std::swap(y1, y2);
         }
      }
                //The Rise
      for (int x = (int)x1; x < maxX; x++)
      {
         if (img.getPixel(x, y) != sf::Color::White && Slope == true)
            {
               output.setPixel(x, y, sf::Color::Red);
            }
            else
            {
               output.setPixel(y, x, sf::Color::Green);
            }
            error -= dy;
            if (error < 0)
            {
               y += ystep;
               error += dx;
            }
      }
   }
   //The Output Function
   output.saveToFile(outFN);
}