Normal quotes
This commit is contained in:
parent
5e10794a24
commit
18011c595a
352 changed files with 6040 additions and 6040 deletions
44
40-02.md
44
40-02.md
|
|
@ -2,11 +2,11 @@
|
|||
[Previous](40-01.html) [Table of Contents](index.html) [Next](40-03.html)
|
||||
------------------------ --------------------------------- --------------------
|
||||
|
||||
Advancing the X coordinates is easy. For each edge, we’ll store the
|
||||
current X coordinate and all required error term information, and we’ll
|
||||
use that to advance the edge one scan line at a time; then, we’ll resort
|
||||
Advancing the X coordinates is easy. For each edge, we'll store the
|
||||
current X coordinate and all required error term information, and we'll
|
||||
use that to advance the edge one scan line at a time; then, we'll resort
|
||||
the AET by X coordinate as needed. Removing edges as they end is also
|
||||
easy; we’ll just count down the length of each active edge on each scan
|
||||
easy; we'll just count down the length of each active edge on each scan
|
||||
line and remove an edge when its count reaches zero. Adding edges as
|
||||
their tops are encountered is a tad more complex. While there are a
|
||||
number of ways to do this, one particularly efficient approach is to
|
||||
|
|
@ -14,7 +14,7 @@ start out by putting all the edges of the polygon, sorted by increasing
|
|||
Y coordinate, into a single list, called the *global edge table* (GET).
|
||||
Then, as each scan line is encountered, all edges at the start of the
|
||||
GET that begin on the current scan line are moved to the AET; because
|
||||
the GET is Y-sorted, there’s no need to search the entire GET. For still
|
||||
the GET is Y-sorted, there's no need to search the entire GET. For still
|
||||
greater efficiency, edges in the GET that share common Y coordinates can
|
||||
be sorted by increasing X coordinate; this ensures that no more than one
|
||||
pass through the AET per scan line is ever needed when adding new edges
|
||||
|
|
@ -22,15 +22,15 @@ from the GET in such a way as to keep the AET sorted in ascending X
|
|||
order.
|
||||
|
||||
What form should the GET and AET take? Linked lists of edge structures,
|
||||
as shown in Figure 40.3. With linked lists, all that’s required to move
|
||||
as shown in Figure 40.3. With linked lists, all that's required to move
|
||||
edges from the GET to the AET as they become active, sort the AET, and
|
||||
remove edges that have been fully drawn is the exchanging of a few
|
||||
pointers.
|
||||
|
||||
In summary, we’ll initially store all the polygon edges in
|
||||
In summary, we'll initially store all the polygon edges in
|
||||
Y-primary/X-secondary sort order in the GET, complete with initial X and
|
||||
Y coordinates, error terms and error term adjustments, lengths, and
|
||||
directions of X movement for each edge. Once the GET is built, we’ll do
|
||||
directions of X movement for each edge. Once the GET is built, we'll do
|
||||
the following:
|
||||
|
||||
**1.** Set the current Y coordinate to the Y coordinate of the first
|
||||
|
|
@ -51,13 +51,13 @@ edges in the AET by one scan line.
|
|||
|
||||
**6.** Advance the current Y coordinate by one scan line.
|
||||
|
||||
**7.** If either the AET or GET isn’t empty, go to step 2.
|
||||
**7.** If either the AET or GET isn't empty, go to step 2.
|
||||
|
||||
\
|
||||
**Figure 40.3** *The global and active edge tables as linked lists.*
|
||||
|
||||
That’s really all there is to it. Compare Listing 40.1 to the fast
|
||||
convex polygon filling code from Chapter 39, and you’ll see that,
|
||||
That's really all there is to it. Compare Listing 40.1 to the fast
|
||||
convex polygon filling code from Chapter 39, and you'll see that,
|
||||
contrary to expectation, complex polygon filling is indeed one of the
|
||||
more sane and sensible corners of the universe.
|
||||
|
||||
|
|
@ -69,10 +69,10 @@ more sane and sensible corners of the universe.
|
|||
by (XOffset, YOffset). Returns 1 for success, 0 if memory allocation
|
||||
failed. All C code tested with Borland C++.
|
||||
If the polygon shape is known in advance, speedier processing may be
|
||||
enabled by specifying the shape as follows: “convex” - a rubber band
|
||||
enabled by specifying the shape as follows: "convex" - a rubber band
|
||||
stretched around the polygon would touch every vertex in order;
|
||||
“nonconvex” - the polygon is not self-intersecting, but need not be
|
||||
convex; “complex” - the polygon may be self-intersecting, or, indeed,
|
||||
"nonconvex" - the polygon is not self-intersecting, but need not be
|
||||
convex; "complex" - the polygon may be self-intersecting, or, indeed,
|
||||
any sort of polygon at all. Complex will work for all polygons; convex
|
||||
is fastest. Undefined results will occur if convex is specified for a
|
||||
nonconvex or complex polygon.
|
||||
|
|
@ -89,7 +89,7 @@ more sane and sensible corners of the universe.
|
|||
#else /* MSC */
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include “polygon.h”
|
||||
#include "polygon.h"
|
||||
|
||||
#define SWAP(a,b) {temp = a; a = b; b = temp;}
|
||||
|
||||
|
|
@ -136,7 +136,7 @@ more sane and sensible corners of the universe.
|
|||
if ((EdgeTableBuffer =
|
||||
(struct EdgeState *) (malloc(sizeof(struct EdgeState) *
|
||||
VertexList->Length))) == NULL)
|
||||
return(0); /* couldn’’t get memory for the edge table */
|
||||
return(0); /* couldn''t get memory for the edge table */
|
||||
/* Build the global edge table */
|
||||
BuildGET(VertexList, EdgeTableBuffer, XOffset, YOffset);
|
||||
/* Scan down through the polygon edges, one scan line at a time,
|
||||
|
|
@ -150,7 +150,7 @@ more sane and sensible corners of the universe.
|
|||
XSortAET(); /* resort on X */
|
||||
CurrentY++; /* advance to the next scan line */
|
||||
}
|
||||
/* Release the memory we’ve allocated and we’re done */
|
||||
/* Release the memory we've allocated and we're done */
|
||||
free(EdgeTableBuffer);
|
||||
return(1);
|
||||
}
|
||||
|
|
@ -190,9 +190,9 @@ more sane and sensible corners of the universe.
|
|||
SWAP(StartX, EndX);
|
||||
SWAP(StartY, EndY);
|
||||
}
|
||||
/* Skip if this can’t ever be an active edge (has 0 height) */
|
||||
/* Skip if this can't ever be an active edge (has 0 height) */
|
||||
if ((DeltaY = EndY - StartY) != 0) {
|
||||
/* Allocate space for this edge’s info, and fill in the
|
||||
/* Allocate space for this edge's info, and fill in the
|
||||
structure */
|
||||
NewEdgePtr = NextFreeEdgeStruc++;
|
||||
NewEdgePtr->XDirection = /* direction in which X moves */
|
||||
|
|
@ -276,9 +276,9 @@ more sane and sensible corners of the universe.
|
|||
/* This edge is finished, so remove it from the AET */
|
||||
*CurrentEdgePtr = CurrentEdge->NextEdge;
|
||||
} else {
|
||||
/* Advance the edge’s X coordinate by minimum move */
|
||||
/* Advance the edge's X coordinate by minimum move */
|
||||
CurrentEdge->X += CurrentEdge->WholePixelXMove;
|
||||
/* Determine whether it’s time for X to advance one extra */
|
||||
/* Determine whether it's time for X to advance one extra */
|
||||
if ((CurrentEdge->ErrorTerm +=
|
||||
CurrentEdge->ErrorTermAdjUp) > 0) {
|
||||
CurrentEdge->X += CurrentEdge->XDirection;
|
||||
|
|
@ -296,7 +296,7 @@ more sane and sensible corners of the universe.
|
|||
int CurrentX;
|
||||
|
||||
/* The GET is Y sorted. Any edges that start at the desired Y
|
||||
coordinate will be first in the GET, so we’ll move edges from
|
||||
coordinate will be first in the GET, so we'll move edges from
|
||||
the GET to AET until the first edge left in the GET is no longer
|
||||
at the desired Y coordinate. Also, the GET is X sorted within
|
||||
each Y coordinate, so each successive edge we add to the AET is
|
||||
|
|
|
|||
Loading…
Reference in a new issue