1 CS-184: Computer Graphics Lecture #9: Scan Conversion Prof. James O’Brien University of California, Berkeley With additional slides based on those of Maneesh Agrawala and Ren Ng 2 Today • 2D Scan Conversion • Drawing Lines • Drawing Curves • Filled Polygons • Filling Algorithms 2 09-ScanConversion.key - October 10, 2016
3 Draw a Line with … unit: infinitely small square unit: small but finite square 3 4 Motivation 4 09-ScanConversion.key - October 10, 2016
5 Motivation • Scan conversion is the process of representing continuous graphics object as a collection of discrete pixels. LCD pixel on laptop 5 6 Low and High resolution screen 6 09-ScanConversion.key - October 10, 2016
7 Drawing a Line 7 8 Drawing a Line 8 09-ScanConversion.key - October 10, 2016
9 Drawing a Line • Some things to consider • How thick are lines? • How should they join up? • Which pixels are the right ones? For example: 9 10 Drawing a Line • How thick? • Ends? Butt Round Square 10 09-ScanConversion.key - October 10, 2016
11 Drawing a Line • Joining? Ugly Bevel Round Miter 11 12 Drawing a Line Inclusive Endpoints 12 09-ScanConversion.key - October 10, 2016
13 Drawing a Line y = m · x + b , x ∈ [ x 1 , x 2 ] m = y 2 − y 1 x 2 − x 1 b = y 1 − m · x 1 13 14 Drawing a Line ∆ x = 1 ∆ y = m · ∆ x x=x1 y=y1 while(x<=x2) plot(x,y) x++ y+=Dy 14 09-ScanConversion.key - October 10, 2016
15 Drawing a Line ∆ x = 1 ∆ y = m · ∆ x After rounding 15 16 Drawing a Line ∆ x = 1 ∆ y = m · ∆ x y += ∆ y Accumulation of roundoff errors How slow is float- to-int conversion? 16 09-ScanConversion.key - October 10, 2016
17 Drawing a Line | m | ≤ 1 | m | > 1 17 18 Drawing a Line 18 09-ScanConversion.key - October 10, 2016
19 Drawing a Line void drawLine-Error1(int x1,x2, int y1,y2) float m = float(y2-y1)/(x2-x1) int x = x1 Not exact math float y = y1 while (x <= x2) setPixel(x,round(y),PIXEL_ON) x += 1 y += m Accumulates errors 19 20 Drawing a Line void drawLine-Error2(int x1,x2, int y1,y2) float m = float(y2-y1)/(x2-x1) int x = x1 int y = y1 float e = 0.0 while (x <= x2) setPixel(x,y,PIXEL_ON) No more rounding x += 1 e += m if (e >= 0.5) y+=1 e-=1.0 20 09-ScanConversion.key - October 10, 2016
21 Drawing a Line void drawLine-Error3(int x1,x2, int y1,y2) int x = x1 int y = y1 float e = -0.5 while (x <= x2) setPixel(x,y,PIXEL_ON) x += 1 e += float(y2-y1)/(x2-x1) if (e >= 0.0) y+=1 e-=1.0 21 22 Drawing a Line void drawLine-Error4(int x1,x2, int y1,y2) int x = x1 int y = y1 float e = -0.5*(x2-x1) // was -0.5 while (x <= x2) setPixel(x,y,PIXEL_ON) x += 1 e += y2-y1 // was /(x2-x1) if (e >= 0.0) // no change y+=1 e-=(x2-x1) // was 1.0 22 09-ScanConversion.key - October 10, 2016
23 Drawing a Line void drawLine-Error5(int x1,x2, int y1,y2) int x = x1 int y = y1 int e = -(x2-x1) // removed *0.5 while (x <= x2) setPixel(x,y,PIXEL_ON) x += 1 e += 2*(y2-y1) // added 2* if (e >= 0.0) // no change y+=1 e-=2*(x2-x1) // added 2* 23 24 Drawing a Line void drawLine-Bresenham(int x1,x2, int y1,y2) int x = x1 int y = y1 Faster int e = -(x2-x1) Not wrong while (x <= x2) 0 ≤ m ≤ 1 setPixel(x,y,PIXEL_ON) x 1 ≤ x 2 x += 1 e += 2*(y2-y1) if (e >= 0.0) y+=1 e-=2*(x2-x1) 24 09-ScanConversion.key - October 10, 2016
25 Drawing a Line 25 26 Drawing Curves x = f ( u ) u ∈ [ u 0 ... u 1 ] 26 09-ScanConversion.key - October 10, 2016
27 Drawing Curves • Draw curves by drawing line segments • Must take care in computing end points for lines • How long should each line segment be? x = f ( u ) u ∈ [ u 0 ... u 1 ] 27 28 Drawing Curves • Draw curves by drawing line segments • Must take care in computing end points for lines • How long should each line segment be? • Variable spaced points x = f ( u ) u ∈ [ u 0 ... u 1 ] 28 09-ScanConversion.key - October 10, 2016
29 Drawing Curves • Midpoint-test subdivision | f ( u mid ) − l ( 0 . 5 ) | 29 30 Drawing Curves • Midpoint-test subdivision | f ( u mid ) − l ( 0 . 5 ) | 30 09-ScanConversion.key - October 10, 2016
31 Drawing Curves • Midpoint-test subdivision | f ( u mid ) − l ( 0 . 5 ) | 31 32 Drawing Curves • Midpoint-test subdivision • Not perfect • We need more information for a guarantee... | f ( u mid ) − l ( 0 . 5 ) | 32 09-ScanConversion.key - October 10, 2016
33 Drawing Curves Later lectures on • Bézier • B-Spline • NURBS Now, let’s draw more interesting shapes… 33 34 Filling Triangles • Render an image of a geometric primitive by setting pixel colors void SetPixel(int x, int y, Color rgba) • Example: Filling the inside of a triangle P 1 P 2 P 3 09-ScanConversion.key - October 10, 2016
35 Filling Triangles • Render an image of a geometric primitive by setting pixel colors void SetPixel(int x, int y, Color rgba) • Example: Filling the inside of a triangle P 1 P 1 P 2 P 2 P 3 P 3 36 Triangle Scan Conversion • Properties of a good algorithm � Symmetric � Straight edges � Antialiased edges � No cracks between adjacent primitives � MUST BE FAST! P 1 P 2 P 4 P 3 09-ScanConversion.key - October 10, 2016
37 Triangle Scan Conversion • Properties of a good algorithm � Symmetric � Straight edges � Antialiased edges � No cracks between adjacent primitives � MUST BE FAST! P 1 P 2 P 4 P 3 38 Triangle Scan Conversion • The most common case in most applications – with good antialiasing, can be the only case – some systems render a line as two skinny triangles • Triangle represented by CCW three vertices • Simple way to think of algorithm follows the pixel-walk interpretation of line rasterization – walk from pixel to pixel over P 1 (at least) the polygon’s area – evaluate linear functions as you go P 2 – use those functions to decide which pixels are inside P 4 P 3 09-ScanConversion.key - October 10, 2016
39 Simple Algorithm • Color all pixels inside triangle void ScanTriangle(Triangle T, Color rgba){ for each pixel P at (x,y){ if (Inside(T, P)) SetPixel(x, y, rgba); } } P 1 P 2 P 3 40 Line Defines Two Halfspaces • Implicit equation for a line � On line: ax + by + c = 0 � On right: ax + by + c < 0 � On left: ax + by + c > 0 P 1 P 2 left side 09-ScanConversion.key - October 10, 2016
41 Inside Triangle Test • Point is inside triangle if it is in positive halfspace of all three boundary lines � Triangle vertices are ordered counter-clockwise � Point must be on the left side of every boundary line L 1 P L 3 L 2 42 Inside Triangle Test Boolean Inside(Triangle T, Point P) { for each boundary line L of T { Scalar d = L.a*P.x + L.b*P.y + L.c; if (d < 0.0) return FALSE; } return TRUE; } L 1 L 3 L 2 09-ScanConversion.key - October 10, 2016
43 Simple Algorithm • What is bad about this algorithm? void ScanTriangle(Triangle T, Color rgba){ for each pixel P at (x,y){ if (Inside(T, P)) SetPixel(x, y, rgba); } } P 1 P 2 P 3 44 Optimize for Triangles • Spilt triangle into two parts • Two edges per part • Y -span is monotonic 44 09-ScanConversion.key - October 10, 2016
45 Triangle Sweep-Line Algorithm • Take advantage of spatial coherence � Compute which pixels are inside using horizontal spans � Process horizontal spans in scan-line order • Take advantage of edge linearity � Use edge slopes to update coordinates incrementally dx dy 46 Triangle Sweep-Line Algorithm void ScanTriangle(Triangle T, Color rgba){ for each edge pair { initialize x L , x R ; compute dx L /dy L and dx R /dy R ; for each scanline at y for (int x = ceil(x L ); x <= x R ; x++) SetPixel(x, y, rgba); x L += dx L /dy L ; x R += dx R /dy R ; } } dx L dx R Bresenham’s algorithm dy L dy R works the same way, but uses only integer x L x R operations! 09-ScanConversion.key - October 10, 2016
47 Antialiasing Desired solution of an integral over pixel 47 48 Hardware Scan Conversion • Convert everything into triangles � Scan convert the triangles 09-ScanConversion.key - October 10, 2016
49 Polygon Scan Conversion • Fill pixels inside a polygon � Triangle � Quadrilateral � Convex � Star-shaped � Concave � Self-intersecting � Holes What problems do we encounter with arbitrary polygons? 50 Polygon Scan Conversion • Need better test for points inside polygon � Triangle method works only for convex polygons L 5 L 5 L 4 L 4 L 1 L 1 L 3B L 3 L 3A L 2 L 2 Concave Polygon Convex Polygon 09-ScanConversion.key - October 10, 2016
51 Inside Polygon Rule • What is a good rule for which pixels are inside? Concave Self-Intersecting With Holes 52 Inside Polygon Rule • Odd-parity rule � Any ray from P to infinity crosses odd number of edges Concave Self-Intersecting With Holes 09-ScanConversion.key - October 10, 2016
53 Inside/Outside Testing The Polygon Non-exterior Non-zero winding Parity 53 54 Filled Polygons 54 09-ScanConversion.key - October 10, 2016
55 Filled Polygons 55 56 Filled Polygons 56 09-ScanConversion.key - October 10, 2016
57 Filled Polygons 57 58 Filled Polygons 58 09-ScanConversion.key - October 10, 2016
Recommend
More recommend