CS 450: COMPUTER GRAPHICS FILLING...
Transcript of CS 450: COMPUTER GRAPHICS FILLING...
CS 450: COMPUTER GRAPHICS
FILLING POLYGONSSPRING 2015
DR. MICHAEL J. REALE
DRAWING POLYGONS IN OPENGL
OPENGL POLYGONS
• There are 4 primitive types associated with polygons in OpenGL:
• GL_POLYGON
• GL_TRIANGLES
• GL_TRIANGLE_STRIP
• GL_TRIANGLE_FAN
• In ALL cases:
• Vertices MUST be specified in COUNTERCLOCKWISE order!
• If less than 3 vertices given nothing drawn
• Deprecated/Legacy: GL_QUADS, GL_QUAD_STRIP
GL_POLYGON
• In legacy:
• glBegin(GL_POLYGON);
• glVertex2iv(p1);
• glVertex2iv(p2);
• glVertex2iv(p3);
• glVertex2iv(p4);
• glVertex2iv(p5);
• glVertex2iv(p6);
• glEnd();
• Draws a polygon out of all vertices
• If not convex, no guarantee it will be filled properly
GL_TRIANGLES
• We’re going to reorder the vertices a bit…
• In legacy:
• glBegin(GL_TRIANGLES);
• glVertex2iv(p1);
• glVertex2iv(p2);
• glVertex2iv(p6);
• glVertex2iv(p3);
• glVertex2iv(p4);
• glVertex2iv(p5);
• glEnd();
• Draws a separate triangle every 3 vertices
• Any remaining vertices ignored
• For N (distinct) vertices N/3 triangles
GL_TRIANGLE_STRIP
• Again, we’re going to reorder the vertices a bit…
• In legacy:
• glBegin(GL_TRIANGLE_STRIP);
• glVertex2iv(p1);
• glVertex2iv(p2);
• glVertex2iv(p6);
• glVertex2iv(p3);
• glVertex2iv(p5);
• glVertex2iv(p4);
• glEnd();
• Draws triangle with first 3 vertices
• For each new vertex draw triangle with new vertex + last 2 vertices
• For N (distinct) vertices (N – 2) triangles
GL_TRIANGLE_FAN
• Yet again, we’re going to reorder the vertices a bit…
• In legacy:
• glBegin(GL_TRIANGLE_FAN);
• glVertex2iv(p1);
• glVertex2iv(p2);
• glVertex2iv(p3);
• glVertex2iv(p4);
• glVertex2iv(p5);
• glVertex2iv(p6);
• glEnd();
• Draws triangle with first 3 vertices
• All triangles share first vertex
• For each new vertex draw triangle with new vertex + first vertex + last vertex
• For N (distinct) vertices (N – 2) triangles
INSIDE-OUTSIDE TESTS
INTRODUCTION
• Whether we’re dealing with a simple polygon or a more complex object (e.g., a self-intersecting polygon, for instance), how do we know what’s inside and outside the polygon?
• Two common approaches:
• Odd-Even Rule
• Nonzero Winding-Number Rule
A COUPLE OF NOTES
• We’re assuming these polygons are in the XY plane (e.g., after screen mapping)
• Both approaches involve drawing a line:
• Starting at some point P in a region we want to check
• Ending somewhere well outside the polygon
• …and checking what we cross with that line
ODD-EVEN RULE
• Also called odd-parity or even-odd rule
• Draw line from position P inside region to distant point
• Count how many edges we cross
ODD-EVEN RULE
• Can use to check other kinds of regions
• E.g., area between two concentric circles
NONZERO WINDING-NUMBER RULE
• Count number of times boundary of object “winds” around a particular point in the clockwise direction
• Again, draw line from position P inside region to distant point
• Start “winding number” W at 0
• If interest with segment that crosses the line going from:
• Right-to-left (counterclockwise) add 1 to W
• Left-to-right (clockwise) subtract 1 from W
• Check value of W when done:
• If W == 0 EXTERIOR
• If W != 0 INTERIOR
NONZERO WINDING-NUMBER RULE
• To check the direction of the edge relative to the line from P:
• Make vectors for each edge (in the correct winding order) vector Ei
• Make vector from P to distant point vector U
• Two options:
• Use cross product:
• If ( U x Ei ) = +z axis right-to-left add 1 to winding number
• If ( U x Ei ) = –z axis left-to-right subtract 1 from winding number
• Use dot product:
• Get vector V that is 1) perpendicular to U, and 2) goes right-to-left ( -uy , ux )
• If ( V · Ei ) > 0 right-to-left add 1 to winding number
• Otherwise left-to-right subtract 1 from winding number
ODD-EVEN VS. NONZERO WINDING-NUMBER• For simple objects (polygons that don’t self-intersect, circles, etc.), both approaches give same result
• However, more complex objects may give different results
• Usually, nonzero winding-number rule classifies some regions as interior that odd-even says are exterior
Odd-Even Rule Nonzero Winding-Number Rule
INSIDE-OUTSIDE PROBLEM
• Caveat: need to check we don’t cross endpoints (vertices)
• Otherwise, ambiguous
CURVED PATHS?
• For curved paths, need to computer intersection points with underlying mathematical curve
• For nonzero winding-number also have to get tangent vectors
VARIATIONS OF NONZERO WINDING-NUMBER RULE
• Can be used to define Boolean operations:
• Positive W only, both counterclockwise union of A and B
• W > 1, both counterclockwise intersection of A and B
• Positive W only, B clockwise A - B
POLYGON FILLING ALGORITHMS
INTRODUCTION
• Two basic ways to fill in a polygon:
• Scan-line approach
• For each scan line the polygon touches, check which pixels on scan line are within polygon boundaries
• Flood-fill or Boundary fill approaches
• Start at interior pixel “paint” outwards until we hit boundaries OR run out of interior pixels
GENERAL SCAN-LINE POLYGON FILLING ALGORITHM
BASIC IDEA
• General scan-line polygon filling algorithm
• Find intersection points of polygon with scan lines
• Sort intersections from left to right
• For each scan line
• Fill in interior pixels along scan line
• Determine interior pixels using odd-even rule
• Polygons easiest to fill edges are linear equations intersecting with y = constant
PROBLEM: CROSSING VERTICES
• What happens if we cross a vertex?
• In some cases, want to “count” it once, but in others you want it to count twice…
SOLUTION TO CROSSING VERTICES
• Look at y coordinates of previous vertex, middle vertex (the one we’re intersection), and the next vertex
• If y values monotonically increase or decrease edges on opposition sides of scan line count vertex as one
• Otherwise edges on same side of scan line vertex is a local max/min count vertex twice
IMPLEMENTATION OF VERTEX-CROSSING SOLUTION
• Go through all edges, winding around polygon
• Check if any set of vertices vk-1 , vk , and vk+1 have y values that monotonically increase/decrease
• Option 1: if yes, shorten one of the edges
• Inherently assumes that polygon is a set of lines, each with their own vertices
• So, if you do nothing, crossing a vertex really crossing two vertices already counts as two
• Option 2: if not, separate into two vertices
• Inherently assumes that edges already share vertices
• So, if you do nothing, crossing a vertex counts as one
• Min/max vertices become two vertices with same location
COMPUTING INTERSECTIONS
• Similar to DDA and Bresenham, we can compute the intersection points of each edge with each scan line by adding some value to x and y as we move along:
• Given that the slope is a fraction of integers, we can instead have a counter w
• Every time we increment y, we add Δx to w
• If (w >= Δy) subtract Δy from w, and increment/decrement x
• Basically same as keeping track of integer and fractional parts
1
1
1
1
kk
kkk
yy
y
xx
mxx
IMPLEMENTING SCAN-LINE FILLING
• To do this efficiently, we need to know which edges we need to work with for each scanline
• Thus, we will have two lists:
• Sorted edge table
• Create this before we start fill
• Active edge table
• Create and update this as we fill the polygon
SORTED EDGE TABLE
• List for each scanline in window/screen array of lists scanList[]
• Each scanline list should be sorted by the x values (smallest to largest)
• For each edge E in the polygon:
• Determine/compute the following:
• Smallest y value (ymin) and corresponding x value
• Largest y value
• Inverse of slope (or Δx and Δy)
• Insert edge E into SORTED scanList[ymin]
• I.e., when the edge starts in x
• Only need to add non-horizontal edges
• Also, if you’re going to shorten any edges, this is a good time to do so
SORTED EDGE TABLE: EXAMPLE
ACTIVE EDGE TABLE
• List also sorted by x values (left to right)
• For each scanline y:
• Add corresponding list from sorted edge table to active list
• I.e., add any new edges
• Again, must add new edges so that the active list is still sorted by x!
• Fill in appropriate areas along scanline using active list for x coordinate boundaries
• I.e., odd-even rule
• Remove any edges that are complete
• I.e., y = ymax for that edge
• Update x values for next iteration
• I.e., add inverse slope
• Resort edges by x values
FILLING CONVEX POLYGONS
• We can simplify the scan-line fill algorithm if our polygon is:
• Convex single interior area only two edge intersections at a time
• Triangle just 3 edges total
FILLING REGIONS WITH CURVED BOUNDARIES
• We can use the scan-line filling approach for curved boundaries (e.g., circles), but:
• 1) Intersection done with curve equations (rather than linear equations) more difficult
• 2) Slope changing, so cannot use straightforward x and y increments
• Circles and ellipses only two intersection points per scanline (convex shape) AND can take advantage of symmetry
• Curve sections (e.g., elliptical arc) use combination of curve and linear equations
• More complex curves numerical techniques OR cheat and use line segment approximations
BOUNDARY-FILL AND FLOOD-FILL ALGORITHM
INTRODUCTION
• An alternative approach to the scan-line algorithm is to:
• 1) start at some interior pixel (i.e., your “seed” pixel)
• 2) “paint” outwards to fill in pixels
• 3) stop when you hit the boundary OR can’t find interior color
• Advantages: allows filling of irregularly-shaped areas
• Disadvantages: more computationally expensive
• We’re going to talk about two variants of this idea:
• Boundary-fill algorithm
• Stop when hit BOUNDARY color
• Flood-fill algorithm
• Fill if you see the INTERIOR color
PIXEL NEIGHBORS
• Given a pixel we just filled in, we need to fill in its neighbors as well
• Which pixels do we consider neighbors?
• “Strong” neighbors north, south, east, and west
• “Weak” neighbors NE, SE, NW, SW
• 4-neighbors = “Strong” neighbors
• 8-neighbors = “Strong” + “Weak” neighbors
• Regions filled with:
• 4-neighbors 4-connected region
• 8-neighbors 8-connected region
http://media.npr.org/assets/img/2014/05/24/mr-rogers_custom-7627a367f40c101dd1d2b6599ab41346bf3b8f5e.jpg?s=1400
CHOOSING NEIGHBORS
• Depending on what kind of neighbors you choose, you will get different filling results:
BOUNDARY-FILL ALGORITHM
• Assume the boundary of the region has a single color B
• Keep filling region until we encounter a pixel with color B
FLOOD-FILL ALGORITHM
• Assume interior region has same color C
• Fill pixel only if it has color C
• Advantages: boundaries can be different colors
EFFICIENT IMPLEMENTATION OF FLOOD/BOUNDARY FILLING
• Problem with these approaches lots of pixels to check, many iterations/recursive calls lots of pixels pushed on stack
• Alternative:
• Have a stack of starting points only for each span put seed point as first
• In this case, a span = horizontal run of interior pixels bounded by boundary pixels
• For each starting point:
• Fill in span of pixels
• Find left-most starting points on lines above and below
• Repeat until stack of starting points empty