Line drawing algorithm

Hi All, I am working on a diagraming utility in Haskell. I started with line drawing. I am doing the basic stuff using the y = mx + c formula to draw a line between (x1,y1) and (x2,y2) Here's what I need to do - if dx > dy where dx = (x2 - x1) and dy = (y2 - y1) then I need to vary x between x1 and x2 and find the various y's however if dy > dx then I need to vary y beteen y1 and y2 and get various x's In the code below, I've only taken care of the situation where dx > dy - I was thinking if there was a better way to do it that takes care of the other condition as well without repeating the code. type Point = (Integer,Integer) line :: Point -> Point -> [Point] -- get all the points in the line line p1@(x1,y1) p2@(x2,y2) = line' start end start slope where (start,end) = reorderPoints p1 p2 slope = ((fromIntegral (y2-y1)) / (fromIntegral (x2-x1))) reorderPoints (px1,py1) (px2,py2) | px1 < px2 = (p1,p2) | otherwise = (p2,p1) line' :: Point -> Point -> Point -> Double -> [Point] line' start@(x1,y1) end@(x2,y2) point@(x3,y3) slope | x3 == x2 = [end] | otherwise = [point] ++ line' start end (newX,newY) slope where newX = x3 + 1 newY = y1 + round (slope * (fromIntegral (newX - x1))) hello = line (1,1) (10,10) Regards, Kashyap

CK Kashyap wrote:
Hi All,
I am working on a diagraming utility in Haskell. I started with line drawing. I am doing the basic stuff using the y = mx + c formula to draw a line between (x1,y1) and (x2,y2) Hi,
Are you doing this to learn Haskell, learn about drawing lines, or to just get it implemented? If either of the latter two, when drawing a straight line you shouldn't need to do floating point operations such as this:
newY = y1 + round (slope * (fromIntegral (newX - x1)))
Bresenham's algorithm (or similar variants) allows you to draw a line without needing floating point. A Haskell implementation is here: http://rosettacode.org/wiki/Bresenham%27s_line_algorithm#Haskell Although it may not be too understandable! Wikipedia has an explanation of the general algorithm: http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm As to how to cope with the dy > dx case in your code given the dx > dy case, you could just swap the x and y coords at the start, then swap back the x and y coords of all the output points afterwards. Odd, but effective :-) Thanks, Neil.

Thanks Neil ...
Are you doing this to learn Haskell, learn about drawing lines, or to just get it implemented? If either of the latter two, when drawing a straight line you shouldn't need to do floating point operations such as this:
Actually, my reasons are first and third.
newY = y1 + round (slope * (fromIntegral (newX - x1)))
http://rosettacode.org/wiki/Bresenham%27s_line_algorithm#Haskell
Thanks for the link.
As to how to cope with the dy > dx case in your code given the dx > dy case, you could just swap the x and y coords at the start, then swap back the x and y coords of all the output points afterwards. Odd, but effective :-) Slope would differ right for both case right?
Regards, Kashyap
participants (2)
-
CK Kashyap
-
Neil Brown