Upload
julia-hodsdon
View
220
Download
0
Embed Size (px)
Citation preview
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
• If we’re dealing with 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)
• Also, 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 is 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 curve
• For nonzero winding-number also have to get tangent vectors
VARIATIONS OF NONZERO WINDING-NUMBER RULE
• Can be used to define Boolean operations (i.e., sets)
• 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
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 CROSSING VERTEX 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, short 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 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
• 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