You are on page 1of 19

Line Drawing Algorithms

• Output Primitives : basic geometric structures that form


a complex picture structure
ex) point,line,circle,filled-area,etc.
– Straight line : y = mx + b
– For given two end points(x1,y1),(x2,y2)
y2 − y1
m= , b = y1 − mx1
x2 − x1
– For any given x internal ∆x
y2 − y1
m= ∆y = m ⋅ ∆x  (1.a )
∆x
1
∆x = ⋅ ∆y  (1.b)
m
Lines & Slopes
• The slope of a line (m) is defined by its start and
end coordinates
• The diagram below shows some examples of lines
and their slopes
m=∞
m = -4 m=4
m = -2 m=2

m = -1 m=1

m = -1/2 m = 1/ 2

m = -1/3 m = 1/3

m=0 m=0
DDA(Digital Differential Analyzer) Algorithm
• DDA(Digital Differential Analyzer) Algorithm
– Scan conversion line algorithm based on ∆x or ∆y
– Sample the line at unit interval in one coord. and determine
corresponding integer value
• When line slope (m) is positive.
Case 1) 0 < m ≤1
− Sample at unit x interval (∆x = 1)
− From eq.(1.a)
xk +1 = xk + 1 yk +1 = yk + m
Case 2) m>1
− Sample at unit y interval (∆ y = 1)
− From eq.(1.b)

1
xk +1 = xk + yk +1 = yk + 1
m
DDA(Digital Differential Analyzer) Algorithm
• When line slope(m) is negative.
Case 3) -1 ≤ m < 0
− Sample at unit x interval (∆ x = -1)

xk +1 = xk − 1 yk +1 = yk − m
Case 4) m < -1
− Sample at unit y interval (∆ y = -1)
− From eq.(3,b)
1
xk +1 = xk − yk +1 = yk − 1
m
• DDA Algorithm
- Faster method than y = mx + b using but may specifies inaccurate pixel section
- Rounding off operations and floating point arithmetic operations are time
consuming.
Pseudo Code of DDA Algorithm
#include <stdlib.h>
#include <math.h>
inline int round( const float a ) { return int(a+0.5); }
void lineDDA( int x0, int y0, int xEnd, int yEnd )
{
int dx = xEnd – x0, dy = yEnd – y0, steps, k;
float xIncrement, yIncrement, x = x0, y = y0;
if( fabs(dx) > fabs(dy) )
steps = fabs(dx);
else
steps = fabs(dy);
xIncrement = float(dx)/float(steps);
yIncrement = float(dy)/float(steps);
setPixel( round(x), round(y) );
for( k=0; k<steps; k++ ) {
x += xIncrement;
y += yIncrement;
setPixel( round(x), round(y) );
}
}
Bresenham’s Algorithm

• Bresenham’s Algorithm
– Originally developed for digital plotter.
– Seek optimum raster loc. to represent a straight line
– Increment by one unit (x or y) depending on the slope of
line
– corresponding value is determined by examining the
distance between the actual line and nearest grid loc.
The Big Idea
• Move across the x axis in unit intervals and at each
step choose between two different y coordinates

For example, from


5

(xk+1, yk+1)
position (2, 3) we have
4
to choose between (3, 3)
(xk, yk) and (3, 4)
3
We would like the point
(xk+1, yk)
2
that is closer to the
original line
2 3 4 5
Deriving The Bresenham Line Algorithm
• At sample position xk+1 y
the vertical separations
k+1
dupper
y
from the mathematical dlower
yk
line are labelled dupper
and dlower xk+1
The y coordinate on the mathematical line at xk+1
is:

y = m( xk + 1) + b
Deriving The Bresenham Line Algorithm (cont…)

• So, dupper and dlower are given as follows:


d lower = y − yk
= m( xk + 1) + b − yk
• and:
d upper = ( yk + 1) − y
= yk + 1 − m( xk + 1) − b
• We can use these to make a simple decision about
which pixel is closer to the mathematical line
Deriving The Bresenham Line Algorithm (cont…)
• This simple decision is based on the difference
between the two pixel positions:
d lower − d upper = 2m( xk + 1) − 2 yk + 2b − 1
• Let’s substitute m with ∆y/∆x where ∆x and
∆y are the differences between the end-points:
∆y
∆x(d lower − d upper ) = ∆x(2 ( xk + 1) − 2 yk + 2b − 1)
∆x
= 2∆y ⋅ xk − 2∆x ⋅ yk + 2∆y + ∆x(2b − 1)

= 2∆y ⋅ xk − 2∆x ⋅ yk + c
Deriving The Bresenham Line Algorithm (cont…)

• So, a decision parameter pk for the kth step along


a line is given by:
pk = ∆x(d lower − d upper )
= 2∆y ⋅ xk − 2∆x ⋅ yk + c
• The sign of the decision parameter pk is the same
as that of dlower – dupper
• If pk is negative, then we choose the lower pixel,
otherwise we choose the upper pixel
Deriving The Bresenham Line Algorithm (cont…)

• Remember coordinate changes occur along the x


axis in unit steps so we can do everything with
integer calculations
• At step k+1 the decision parameter is given as:
pk +1 = 2∆y ⋅ xk +1 − 2∆x ⋅ yk +1 + c
• Subtracting pk from this we get:

pk +1 − pk = 2∆y ( xk +1 − xk ) − 2∆x( yk +1 − yk )
Deriving The Bresenham Line Algorithm (cont…)

• But, xk+1 is the same as xk+1 so:


pk +1 = pk + 2∆y − 2∆x( yk +1 − yk )

• where yk+1 - yk is either 0 or 1 depending on the


sign of pk
• The first decision parameter p0 is evaluated at (x0,
y0) is given as:
p0 = 2∆y − ∆x
Bresenham Example
• Let’s have a go at this
• Let’s plot the line from (20, 10) to (30, 18)
• First off calculate all of the constants:
– Δx: 10
– Δy: 8
– 2Δy: 16
– 2Δy - 2Δx: -4
• Calculate the initial decision parameter p0:
– p0 = 2Δy – Δx = 6
Bresenham Example (cont…)
18 k pk (xk+1,yk+1)

17 0
16 1
15 2

14 3

13 4

12
5
6
11
7
10
8
20 21 22 23 24 25 26 27 28 29 30
9
Bresenham Line Algorithm Summary

• The Bresenham line algorithm has the following


advantages:
– An fast incremental algorithm
– Uses only integer calculations
• Comparing this to the DDA algorithm, DDA has the
following problems:
– Accumulation of round-off errors can make the pixelated
line drift away from what was intended
– The rounding operations and floating point arithmetic
involved are time consuming
Example :To illustrate the algorithm, we digitize the line with
endpoints (20, 10) and (30, 18)
Slope = 0.8 (∆x=10, ∆y=8)
Initial decision parameter: p0 = 2∆y −∆x = 6
Increments:2∆y = 16, 2∆y − 2∆x =−4
Plot the initial point (x0, y0) = (20, 10) and determine successive
pixel positions:

k pk (xk+1, yk+1) k pk (xk+1, yk+1) k pk (xk+1, yk+1)


0 6 (21, 11) 3 14 (24, 13) 6 2 (27, 16)
1 2 (22, 12) 4 10 (25, 14) 7 –2 (28, 16)
2 –2 (23, 12) 5 6 (26, 15) 8 14 (29, 17)
#include <stdlib.h>
#include <math.h>
/* Bresenham’s algorithm for |m|<1.0 */
void lineBres( int x0, int y0, int xEnd, int yEnd )
{
int dx = fabs(xEnd – x0), dy = fabs(yEnd – y0);
int p = 2 * dy – dx;
int twoDy = 2 * dy, twoDyMinusDx = 2 * (dy – dx);
/* Determine which endpoint to use as start position */
if( x0 > xEnd ) {
x = xEnd; y = yEnd; xEnd = x0;
}
else {
x = x0; y = y0;
}
setPixel( x, y );
while( x < xEnd ) {
x++;
if( p < 0 )
p += twoDy;
else {
y++;
p += twoDyMinusDx;
}
setPixel( x, y );
}
}

You might also like