106 lines
5.6 KiB
Markdown
106 lines
5.6 KiB
Markdown
---
|
|
title: Michael Abrash's Graphics Programming Black Book, Special Edition
|
|
author: Michael Abrash
|
|
date: '1997-07-01'
|
|
isbn: '1576101746'
|
|
publisher: The Coriolis Group
|
|
category: 'Web and Software Development: Game Development,Web and Software Development:
|
|
Graphics and Multimedia Development'
|
|
chapter: '40'
|
|
pages: 755-756
|
|
---
|
|
|
|
An insertion sort that scans backward through the AET from the current
|
|
edge rather than forward from the start of the AET could be quite a bit
|
|
faster, because edges rarely move more than one or two positions through
|
|
the AET. However, scanning backward requires a doubly linked list,
|
|
rather than the singly linked list used in Listing 40.1. I've chosen to
|
|
use a singly linked list partly to minimize memory requirements
|
|
(double-linking requires an extra pointer field) and partly because
|
|
supporting back links would complicate the code a good bit. The main
|
|
reason, though, is that the potential rewards for the complications of
|
|
back links and insertion sorting aren't great enough; profiling a
|
|
variety of polygons reveals that less than ten percent of total time is
|
|
spent sorting the AET.
|
|
|
|
> 
|
|
> The potential 1 to 5 percent speedup gained by optimizing AET sorting
|
|
> just isn't worth it in any but the most demanding application—a good
|
|
> example of the need to keep an overall perspective when comparing the
|
|
> theoretical characteristics of various approaches.
|
|
|
|
### Nonconvex Polygons {#Heading8}
|
|
|
|
Nonconvex polygons can be filled somewhat faster than complex polygons.
|
|
Because edges never cross or switch positions with other edges once
|
|
they're in the AET, the AET for a nonconvex polygon needs to be sorted
|
|
only when new edges are added. In order for this to work, though, edges
|
|
must be added to the AET in strict left-to-right order. Complications
|
|
arise when dealing with two edges that start at the same point, because
|
|
slopes must be compared to determine which edge is leftmost. This is
|
|
certainly doable, but because of space limitations and limited
|
|
performance returns, I haven't implemented this in Listing 40.1.
|
|
|
|
#### Details, Details {#Heading9}
|
|
|
|
Every so often, a programming demon that I'd thought I'd forever laid to
|
|
rest arises to haunt me once again. A minor example of this—an imp, if
|
|
you will—is the use of " = " when I mean " == ," which I've done all too
|
|
often in the past, and am sure I'll do again. That's minor deviltry,
|
|
though, compared to the considerably greater evils of one of my personal
|
|
scourges, of which I was recently reminded anew: too-close attention to
|
|
detail. Not seeing the forest for the trees. Looking low when I should
|
|
have looked high. Missing the big picture, if you catch my drift.
|
|
|
|
Thoreau said it best: "Our life is frittered away by detail....Simplify,
|
|
simplify." That quote sprang to mind when I received a letter a while
|
|
back from Anton Treuenfels of Fridley, Minnesota, thanking me for
|
|
clarifying the principles of filling adjacent convex polygons in my
|
|
ongoing writings on graphics programming. (You'll find this material in
|
|
the previous two chapters.) Anton then went on to describe his own
|
|
method for filling convex polygons.
|
|
|
|
Anton's approach had its virtues and drawbacks, foremost among the
|
|
virtues being a simplicity Thoreau would have admired. For instance, in
|
|
writing my polygon-filling code, I had spent quite some time trying to
|
|
figure out the best way to identify which edge was the left edge and
|
|
which the right, finally settling on comparing the slopes of the edges
|
|
if the top of the polygon wasn't flat, and comparing the starting points
|
|
of the edges if the top was flat. Anton simplified this tremendously by
|
|
not bothering to figure out ahead of time which was the right edge of
|
|
the polygon and which the left, instead scanning out the two edges in
|
|
whatever order he found them and letting the low-level drawing code
|
|
test, and if necessary swap, the endpoints of each horizontal line of
|
|
the fill, so that filling started at the leftmost edge. This is a little
|
|
slower than my approach (although the difference is almost surely
|
|
negligible), but it also makes quite a bit of code go away.
|
|
|
|
What that example, and others like it in Anton's letter, did was kick my
|
|
mind into a mode that it hadn't—but should have—been in when I wrote the
|
|
code, a mode in which I began to wonder, "How else can I simplify this
|
|
code?"; what you might call Occam's Razor mode. You see, I created the
|
|
convex polygon-drawing code by first writing pseudocode, then writing C
|
|
code, and finally writing assembly code, and once the pseudocode was
|
|
finished, I stopped thinking about the interactions of the various
|
|
portions of the program.
|
|
|
|
In other words, I became so absorbed in individual details that I forgot
|
|
to consider the code as a whole. That was a mistake, and an embarrassing
|
|
one for someone who constantly preaches that programmers should look at
|
|
their code from a variety of perspectives; the next chapter shows just
|
|
how much difference thinking about the big picture can make. May my
|
|
embarrassment be your enlightenment.
|
|
|
|
The point is not whether, in the final analysis, my code or Anton's code
|
|
is better; both have their advantages. The point is that I was
|
|
programming with half a deck because I was so fixated on the details of
|
|
a single type of implementation; I ended up with relatively
|
|
hard-to-write, complex code, and missed out on many potentially useful
|
|
optimizations by being so focused. It's a big world out there, and there
|
|
are many subtle approaches to any problem, so relax and keep the big
|
|
picture in mind as you implement your programs. Your code will likely be
|
|
not only better, but also simpler. And whenever you see me walking
|
|
across hot coals in this book or elsewhere when there's an easier way to
|
|
go, please, let me know!
|
|
|
|
Thanks, Anton.
|