Home > Software design >  Find Pixels that Line Passes Over
Find Pixels that Line Passes Over

Time:02-26

I have the equation of a line in y=ax b form, and a starting point, and I want to find all the pixels this line crosses over/into.

At the moment, I was just stepping the x value a bit, calculating y, truncating to find pixel index and adding it to a list if not already in the list, and continuing until reaching a destination point. Kind of as follows (python/pseudocode):

temp_x = start_x
prev_tested = None
pixel_list = []
while(not at destination):
    temp_y = ... find y from x and line equation
    pixel = (int(temp_y), int(temp_x))

    if pixel is not the same as the prev_pixel:
        pixel_list.append(pixel)

    temp_x  = some_step_value

But this just seems wildly inaccurate and inefficient (No need to tell me that in the answers, I understand this is a bad algo). The step value affects a lot. Too large and I will miss pixels (especially if there is a large slope). Too small and I am just wasting iterations. I figured that I can make my step value proportional to my slope, so that I try to minimize the number of iterations I have to do, while also not skipping over too much. But it is not perfect, still skipping over pixels that the line only barely enters the corner.

I feel like there has to be some kind of way to just absolutely determine which pixels a line is touching, but I have had no look finding anything myself. Is there some resource anyone could point me towards that could help with this?

CodePudding user response:

Your step value should be always 1 . What to step over, however depends on your line being more on the horizontal or more on the vertical (that is "a < 1" or "a > 1". For one, step x on 1, and y will be a fraction of that, and for lines more on vertical, y will step with 1 and x will be a fraction of that.

def draw_line(a, b, start_x, destination):
    result = []
    x = start_x
    y = a * x   b
    result.append((int(x),int(y)))
    while int(x) != destination[0] and int(y) != destination[1]:
        if abs(a) < 1:
            x  = 1 if destination[0] > start_x else -1 
            y  = (1 / a) if a!= 0 else 0
        else:
            y  = 1 if destination[1] > y else -1
            x  = 1 / a
        result.append((int(x), int(y)))

    return result
    # maybe there is some missing corner case for vertical lines. 

CodePudding user response:

Dx= X1 - X0
Dy= Y1 - Y0
D= Max(Abs(Dx), Abs(Dy))
for I= 0 to D
  X= X0   I * Dx / D
  Y= Y0   I * Dy / D

works in all cases (except the degenerate D=0).


Technical note:

You can avoid the two divisions. One by the fact that the fraction simplifies to ±1, and the other by computing the quotient and remainder incrementally.

  • Related