Download Scan Converting Triangles: Understanding Triangle Rasterization - Prof. Leona Mcmillan and more Study notes Computer Science in PDF only on Docsity!
Scan Conver+ng Triangles
Expect a new problem set to appear online sometime later today.
It will be due on 10/14 before the break. First Quiz on 10/21.
Primi+ve Rasteriza+on
• 2‐D SAMPLING problem
• Which pixels (samples) of an “ideal” analy5cal
primi5ve should be turned on? Based on
– closeness of the primi5ve
to the sample to the
sample point
– Percentage coverage of
an aperture (a no5on
that used to be popular)
– Whether the sample is inside or outside of a closed
primi5ve
Triangles are always Convex
What does it mean to be a convex?
An object is convex if and only if any line segment connec5ng two points on its boundary is contained en5rely within the object or one of its boundaries.
Why is being convex important?
Because no ma^er how a triangle is oriented on the screen
a given scan line will contain only a single segment or span
of that triangle.
Triangles Approximate Shapes Any 2‐dimensional shape (or 3D surface) can be approximated by a polygon using a locally linear (planar) approxima5on. To improve the quality of fit we need only increase the number edges.
Scan‐conver+ng Triangles
The two most common strategies for scan‐conver5ng
triangles are edge walking and edge equa=ons
There are, however, other techniques including:
– Recursive subdivision of primi5ve (micro‐polygons)
– Recursive subdivision of screen (Warnock’s algorithm)
Edge‐Walking Rasterizers
Notes on edge walking:
- Sort the ver5ces in both x and y
- Determine if the middle vertex, or breakpoint lies on the leg or right side of the polygon. If the triangle has an edge parallel to the scan line direc5on then there is no breakpoint.
- Determines the leg and right extents for each scan line (called spans ).
- Walk down the leg and right edges filling the pixels in‐between un5l either a breakpoint or the bo^om vertex is reached.
Advantages and Disadvantages:
- Generally very fast
- Loaded with special cases (leg and right breakpoints, no breakpoints)
- Difficult to get right
- Requires compu5ng frac5onal offsets when interpola5ng parameters across the triangle
Rasterizing with Edge Equa+ons
- An edge equa5on is simply a
discrimina+ng func+on.
- You can think of it as answering a
ques5on about any given point (x, y)
- An edge equa5on segments a planar
region into three parts, a boundary, and
two half‐spaces. The boundary is
iden5fied by points where the edge
equa5on is equal to zero. The half‐spaces
are dis5nguished by differences in the
edge equa5on’s sign. We can choose
which half‐space is posi5ve by
mul5plica5on by ‐1.
- We can scale all three edges so that their
nega5ve half‐spaces are on the triangle’s
exterior.
Notes on using Edge Equa+ons
• Compute edge equa5ons from ver5ces
• Orient edge equa5ons (make the interior region posi5ve)
• Compute a bounding box
• Scan through pixels in bounding box evalua5ng the edge equa5ons
• When all three are posi5ve then draw the pixel.
Numerical Precision of C Computers represent floa5ng‐point number internally in a format similar to scien5fic nota5on. The very worse thing that you can do with numbers represented in scien5fic nota5on is subtract numbers of similar magnitude. Here is what happens: We loose most of the significant digits in our result. In the case of triangles, these sort of precision problems to occur frequently, because, in general, the ver5ces of a triangle are close to each other and thus
Maintaining Precision in C
Thankfully, we can avoid this subtrac5on of large
numbers when compu5ng an expression for
C. Given that we know A and B we can solve
for C as follows:
or
To eliminate any bias toward either vertex we
will average of these C values
Support Rou+nes
• setupTri() computes edge equa5ons
• boundingBox()
computes
the extent
of the triangle
Notes:
uses “area” to
orient edge
handles
image extent
def setupTri(v0, v1, v2): e0 = EdgeEqn(v1, v2) e1 = EdgeEqn(v2, v0) e2 = EdgeEqn(v0, v1) area = e0.C + e1.C + e2.C if (area < 0): e0.flip() e1.flip() e2.flip() return (e0, e1, e2) def boundingBox(im, v0, v1, v2): xlist = [v0[0], v1[0], v2[0]] ylist = [v0[1], v1[1], v2[1]] xmin = max(min(xlist), 0) xmax = min(max(xlist), im.size[0]-1) ymin = max(min(ylist), 0) ymax = min(max(ylist), im.size[1]-1) return (xmin, xmax, ymin, ymax)
Setup Details
In setupTri() we did two peculiar things. We computed the triangle’s area and
we oriented the edge equa5ons
From analy5c geometry we know the area of triangle
{(x
1
,y
1
), (x
2
,y
2
), (x
3
,y
3
)} is:
Area is posi5ve if the ver5ces are counterclockwise and nega5ve if clockwise
An aside: In terms of our discriminator, what does a posi5ve C imply?
A Triangle Rasterizer
• Now scan over the samples
within the triangle’s bounding
box turning on those pixels
that are inside
10/4/08 Comp 665 – Image Transforms & Warps 19
def FlatTri(im, v0, v1, v2, color):
edge0, edge1, edge2 = setupTri(v0, v1, v2)
xmin, xmax, ymin, ymax = boundingBox(im, v0, v1, v2)
for y in xrange(ymin,ymax+1):
for x in xrange(xmin,xmax+1):
e0 = edge0.evaluateAt(x,y)
e1 = edge1.evaluateAt(x,y)
e2 = edge2.evaluateAt(x,y)
if ((e0 >= 0) and (e1 >= 0) and (e2 >= 0)):
im.putpixel((x,y), color)
Rasterizing Tricks
- Since triangles are convex, we can only be inside for a single interval on
any given scanline. We can add a flag to keep track of when we exit the
triangle’s interior. If ever we find ourselves outside of the triangle having
already set some pixels on the current span then we can skip over the
remainder of the scanline.
def FlatTri(im, v0, v1, v2, color): edge0, edge1, edge2 = setupTri(v0, v1, v2) xmin, xmax, ymin, ymax = boundingBox(im, v0, v1, v2) for y in xrange(ymin,ymax+1): beenInside = False for x in xrange(xmin,xmax+1): e0 = edge0.evaluateAt(x,y) e1 = edge1.evaluateAt(x,y) e2 = edge2.evaluateAt(x,y) if ((e0 >= 0) and (e1 >= 0) and (e2 >= 0)): im.putpixel((x,y), color) beenInside = True elif beenInside: break