470 likes | 647 Views
Polygon Rasterization. Chapter 3 Section 3-11 till page 130. Some of the material in these slides may have been adapted from University of Virginia, MIT, and Åbo Akademi University. Polygon. Polygon: A set of points p0, p1, p2, p3,… Convex Vs Concave. Polygon Vs Triangle.
E N D
Polygon Rasterization Chapter 3 Section 3-11 till page 130 Some of the material in these slides may have been adapted from University of Virginia, MIT, and ÅboAkademi University
Polygon Polygon: A set of points p0, p1, p2, p3,… Convex Vs Concave
Polygon Vs Triangle Triangle is the minimal unit of a polygon All polygons can be broken up into triangles Triangles are guaranteed to be: Planar Convex
General Polygon Rasterization • We want to fill the inside of a polygon • Two General Approaches • Use scan lines • Start from an interior point • Use Scan lines • Used in general purpose libraries for simple shapes • Starting from interior point • Interactive programs • Useful for complex shapes
Scan Line Rasterization • A polygon is defined by its list of vertices • We want to fill the inside of the polygon • We will use horizontal scan lines
Scan Line Rasterization • Consider the following polygon: • How do we know whether a given pixel on the scanline is inside or outside the polygon? D B C A E F
Basic Idea • Find intersection points • Sort from left to right • Fill the scan line between every pair • Does it work all the time? D B A A A A C E F
Special Cases • Both X and Y pass through a polygon vertex • Z passes through a horizontal edge X Y Z
Scan Lines Intersect Vertices • Both X and Y intersect a polygon vertex • X intersects 4 edges • Y intersects 5 edges X Y
Scan Line Intersecting Vertices I B • Polygon edges are on the same side of X at point A • Polygon Edges are on opposite side of Y at point C • Y needs special processing (why?) A 1 4 X 2,3 E H C Y D 2,3 4 5 1 G F
Handling Scan line Intersecting Vertices • Scan the polygon (counter-)clockwise • If the y-coordinate of endpoints of two consecutive edges monotonically increase or decrease, the vertex is counted as one intersecting point • Else count the vertex intersection as two
Scan Line Intersecting Vertices X scan line intersect at 1,2 and 3,4 Y scan line intersect at 1,2 and 3,4 I B A 1 4 X 2,3 E H C Y D 2 3 4 1 G F
Edge Shortening • Scan in the polygon (counter-)clockwise direction • If the Y-coordinate of two consecutive edges is increasing or decreasing • Shorten the Y-coordinate of the edge below the scan line • i.e. decrease y-coordinate by 1 • This way the scan line intersects one polygon edge only y+1 y y-1
Determining Intersection Points • Given point R, can we determine point B quickly R B • Use Bresenham's Line-Drawing Approach
|m| <1 Vs |m|>1 • For |m|<1, • y does NOT get incremented every loop • x gets incremented every loop • Hence we have multiple intersection points per scan line • For |m| >1, • y gets incremented every loop • x does not get incremented every loop • Hence we have one intersection point per scan line
Avoiding |m|<1 problem • An intersection point at a scan y line may consists of multiple x values • Let xa be the set of x-values of the intersection with edge a • Let xb be the set x-values of the intersection with edge b • For a pair of intersection points xa, xb with two edges • Fill between the one more than the rightmost x value of xa and one less than the leftmostx value xb
General Polygon Rasterization • Basic idea: use a parity test where we fill between every two intersection points for each scanline edgeCnt = 0; for each pixel on scanline (l to r) // IF you move from a edge pixel to // non-edge pixel if (oldpixel->newpixel crosses edge) edgeCnt ++; // draw the pixel if edgeCnt odd if (edgeCnt % 2) setPixel(pixel); • Why does this work? • What assumptions are we making?
Faster Polygon Rasterization • How can we optimize the code? for each scanline edgeCnt = 0; for each pixel on scanline (l to r) if (oldpixel->newpixel crosses edge) edgeCnt ++; // draw the pixel if edgeCnt odd if (edgeCnt % 2) setPixel(pixel); • Big cost: testing pixels against each edge • Solution: active edge table (AET)
Performance Improvement • The goal is to compute the intersections more efficiently. Brute force: intersect all the edges with each scanline • find the ymin and ymax of each edge and intersect the edge only when it crosses the scanline • only calculate the intersection of the edge with the first scan line it intersects • calculate dx/dy • for each additional scanline, calculate the new intersection as x = x + dx/dy
Data Structure • Edge table: • all edges sorted by their ymin coordinates. • keep a separate bucket for each scanline • within each bucket, edges are sorted by increasing x of the ymin endpoint
Edge Table y x ymin
Active Edge Table (AET) A list of edges active for current scanline, sorted in increasing x Scan line intersect DE at x=10 y = 9 y = 8
Polygon Scan-conversion Algorithm Construct the Edge Table (ET); Active Edge Table (AET) = null; for y = Ymin to Ymax Merge-sort ET[y] into AET by x value Fill between pairs of x in AET for each edge in AET if edge.ymax = y remove edge from AET else edge.x = edge.x + dx/dy sort AET by x value end scan_fill
Active Edge Table Algorithm • Pre-Process: • Sort all edges by their minimum y-coordinate • Shorten edges as needed • Ignore horizontal edges • Loop • For each scanline in the screen: • Add edges with Ymin Y • Sort edges in AET by x intersection with the current scan line • Walk from left to right, setting pixels by parity rule • Increment scanline • Retire edges with Ymax < Y • Stop when Y > Ymax for last edge
Exercise B C C` E D A
Notes about AET • At any scan line, AET contains ONLY the edges that the current scan line intersects • No need to test pixels in the frame buffer • We need to check for Ymin Y for every scan line to add edges • Make the check Ymin Y for edges outside the AET • Because edges are sorted by Ymin, we need to check for the first edge that is not in the AET • We need to check Ymax < Y for every scan line to retire edges • We need to check Ymax < Y for edges in the AET • If we sort edges in the AET by Ymax • We only need to check one edge after every scan line • Costs O(log2n) for every add/retire from the AET
Determining the interior of a Polygon • Non-Intersecting polygons are easy
Odd-Even Rule • We want to determine wither a point P is inside a polygon or not • Draw a line from P to a point beyond the polygon range • If the line intersects the polygon in odd number of points then the point is interior
Non-Zero Winding Number • The number of times polygon edges wind around a point • Interior point have non-zero winding number • Draw a line from P to a distant point withoutintersecting any vertex and without being parallel to an edge. • Consider this line vector u • Walk around the polygon in one direction. • Consider each edge as vector V in the walk direction • If u intersects any edge V, calculate uxV • If uxV > 1 counter = counter+1 • If uxV<1 counter=counter-1 • After intersecting all possible edges, if counter != 0 then P is interior Would both algorithms yield the same result?
Non-Zero Winding Number A D C E F B
Non-Zero Winding Number A D C E F B
Non-Zero Winding Number A D C E F B
What Rule Applied in the Scanline Rasterization • A interior point P on a scan line bisects the scan line • Hence we have 2 lines from P to two distant point • If P is interior then the each line of the 2 lines will have odd intersections with each of the two lines • The sum of the two odd numbers is even
What Rule Applied in the Scanline Rasterization • A interior point P on a scan line bisects the scan line • Hence we have 2 lines from P to two distant point • If P is interior then the each line of the 2 lines will have odd intersections with each of the two lines • The sum of the two odd numbers is even AET Algorithm applies odd-even rule
Boundary Fill • Basic Idea: BoundaryFill(x,y,color) • Start with an interior point • Color the starting point • Recursively Call boundaryFill(x,y, Color) for surrounding points • Four Connected • Recursively call BoundaryFill(x,y,Color) for (x+1,y), (x-1,y), (x,y+1), and (x, y-1) • What problems can occur because of 4-connected? • Eight Connected • Also call the “corners” (x+1,y+1), (x-1, y-1), (x+1, y-1), and (x-1, y+1)
Boundary Fill • Problem: stack Overflow leads to program crash • How to solve stack overflow problem? • Avoid recursive calls by doing your own stack
Avoiding Program Crash //4-way floodfill using our own stack routines void floodFill4Stack(int x, int y, int newColor, int oldColor) { if(newColor == oldColor) return; //avoid infinite loop emptyStack(); if(!push(x, y)) return; while(pop(x, y)) { screenBuffer[x][y] = newColor; if(x + 1 < w && screenBuffer[x + 1][y] == oldColor) { if(!push(x + 1, y)) return; } if(x - 1 >= 0 && screenBuffer[x - 1][y] == oldColor) { if(!push(x - 1, y)) return; } if(y + 1 < h && screenBuffer[x][y + 1] == oldColor) { if(!push(x, y + 1)) return; } if(y - 1 >= 0 && screenBuffer[x][y - 1] == oldColor) { if(!push(x, y - 1)) return; } } }