EECE 478 Lecture notes for January 8, 2001 Basic Raster Graphics Algorithms for Drawing 2D Primitives Idea is to approximate mathematical “ideal” primitives, described in Cartesian spaces, by sets of pixels on a raster display (bitmap in memory or framebuffer) Fundamental algorithms for scan converting primitives to pixels, and clipping them Many algorithms were initially designed for plotters Can be implemented in hardware, software and firmware Primitives: o Lines o Circles, arcs, ellipses o Region filling o Clipping o Alphanumeric symbols – text Want efficiency and speed Scan Converting Lines Assume that the line will be 1 pixel thick and will approximate an infinitely fine line What properties should the line have? o Slopes –1 to 1 = 1 pixel per column, otherwise 1 pixel per row o Constant brightness (irrespective of length or orientation) o Drawn as fast as possible Other considerations: o Pen style, line style, end point (rounded?), aliasing Assume (unless specified otherwise) that we will represent pixels as disjoint circles, centered on grid. Idea is to compute the coordinates of a pixel that lies on or near an ideal, infinitely thin line imposed on a 2D raster grid. For the algorithms discussed below, assume: o Integer coordinates of endpoints o Pixel on or off (2 states) o Slope |m| 1 (get jaggies, but antialiasing discussed later) Three line drawing algorithms will be discussed below. They are: 1. Digital Differential Algorithm (DDA) 2. Midpoint Line Algorithm 3. Bresenham’s Line Algorithm Digital Differential Algorithm (or Basic Incremental Algorithm) (brute force approach) For y = mx + b, slope m = y / x Idea is to increment x by 1 (xi) and calculate yi=mxi + b Pixel to be turned on is at (xi, round(yi)) The simplicity of this algorithm is its advantage but it is inefficient due to Floating point multiplication and Addition Rounding We can eliminate the multiplication by noting that: yi+1 = mxi+1 + b = m(xi +x ) + b = yi + mx since x = 1 = yi + m (For slope |m| > 1, just do the opposite: increment y and compute x, xi+1=xi+m-1.) C code Line (int x0, int y0, int x1, int y1) { int x; float m, y; m = (y1-y0)/(x1-x0); y=y0; for (x=x0; x<=x1; x++) { TurnOn(x, (int)(y+0.5)); y+=m; } } must check for special case m = infinity. Drawback: Floating point values (m,y) Round operation Special cases m = 0 or infinity Midpoint Line Algorithm(variant of Bresenham’s) reduces to Bresenham’s for lines and circles Uses only integer arithmetic and no rounding Idea is to provide the best-fit approximation to a true line by minimizing the error (distance) to the true line. Slope 0 m 1 (rest is done with reflection) Endpoints : (x0, y0) and (x1, y1) E – east pixel from P NE – northeast pixel Q – intersection point of line with x = xp+1 M – midpoint of E and NE Idea If Q > M then pick NE If Q < M then pick E If Q = M then pick either one (but be consistent) Error will be 0.5 How to do: Line (implicit form) F(x,y) = ax + by + c = 0 (a, b, c = ?) slope intercept form y = (dy/dx)x + B dy x - dxy + Bdx = 0 therefore a = dy, b = -dx and c = Bdx F(x,y) = 0 – on line > 0 – for points below line < 0 – for points above line so, need only compute F(xp+1,yp+1/2) and test it’s sign assume that d = F(xp+1, yp+1/2) then d > 0 pick NE d < 0 pick E d = 0 pick either, say E iteratively calculate d: depends on pick of NE or E if E dnew = F(xp+2, yp+1/2) = a(xp+2) + b(yp+1/2) + c but dold = a(xp+1) + b(yp+1/2) + c therefore dnew = dold + a E = a = dy so, do not have to computer F directly if NE dnew = F(xp+2, yp+1+1/2) dnew = dold + a + b NE = a + b = dy – dx so at each step, pick between NE and E by sign of d, then update d by NE or E to begin d = F(x0+1, y0+1/2) = F(x0, y0) + a + b/2 = a + b/2 = dy – dx/2 can get rid of fraction dx/2 by replacing F(x,y) by 2F(x,y), so need only simple addition. C code Line (int x0, int y0, int x1, int y1) { int dx, dy, dE, dNE, d, x, y; dx = x1 – x0; dy = y1 = y0; d = 2 * dy – dx; dE = 2 * dy; dNE = 2 * (dy – dx); x = x0; y = y0; while (x<x1){ if (d <=0) { d+=dE; ++x; } else { d+=dNE; x++; y++; } TurnOn(x,y); } } Addition Issues (section 3.2.3 of textbook) Endpoint order a line from P0 to P1 must be the same as the line from P1 to P0 Starting at the edge of a clip rectangle must know error at clip point or line will be altered if assumed to be starting point Varying the intensity of a line as a function of slope one way to reduce aliasing Outline primitives composed of lines