Errata to _Graphics Gems_, first edition, edited by Andrew Glassner (glassner@microsoft.com), Academic Press 1990. Code available online at ftp://princeton.edu/pub/Graphics/GraphicsGems/Gems. compiled by Eric Haines (erich@eye.com) from author and reader contributions version 1.14 date: 8/12/96 ----- Errors in the text: p. 3, bottom: The equation "N . P + c = 0" is better expressed as "N . P - c = 0" in order to match Figure 1a. [also see p. 9 errata] p. 5, V2 Perpendicular: change "N <- (-Vx, Vy)" to "N <- (-Vy, Vx)" p. 5, V2 Reflect: change "N <- (-Vy, -Vx)" to "N <- (-Vx, -Vy)" p. 6: change P1 and P2 lines to P1 <- (( -b+sqrt(d) ) / 2a) * lv + lu P2 <- (( -b-sqrt(d) ) / 2a) * lv + lu i.e. the value computed is multiplied by the direction vector and the line's origin is added to this new vector to get the intersection point. p. 9-10, starting at bottom: If the equation on p. 3 is expressed as "N . P - c = 0", then change all "+ c" references to "- c" and "l-sub-c" to "- l-sub-c". p. 10, for "if not l-normalized", the operation in the next line should divide q by "( l-sub-n dot l-sub-n)", not "Length( l-sub-n )". p. 105, last sentence of first paragraph: "ajacent" to "adjacent". p. 216, caption for figure 2: "54" should read "45" to be consistent with the figure (error in two places in caption). p. 282, 5 and 7 lines from bottom: should read "then PUSH(dadRx + 1, rx, pushlx, pushrx, y-dir, -dir )" and "then PUSH(lx, dadLx-1, pushlx, pushrx, y-dir, -dir )" i.e. the final "dir" should be "-dir". p. 283, 3 lines from bottom: add an "end" above the "else begin". p. 284, 12 lines down: move "x <- x + 1;" to after the next "end" statement (move it down only one line). p. 365, last line: "Kajia" to "Kajiya". p. 395, first paragraph: change "discussed by Haines (1989)" to "discussed by Haines in Glassner (1989)". p. 448, last sentence of second paragraph: change "and now nearly as simple" to "and not nearly as simple". p. 463, second to last line: change "then alpha <- alpha + pi/2" to "then alpha <- pi - alpha". p. 495, equation 5: this should have an equal sign (=) before the plus-or-minus (+/-). p. 499, middle of page: change "and i,j,K" to "and i,j,k". p. 503, last sentence: change "Let P' = Rot_(alpha, N) ..." to "Let P' = Rot_(theta, N) ...". p. 516, last paragraph: a reader notes an additional reference which predates Berger and Salmon & Slater, namely "The Viewing Transformation," Technical Memo. no. 84, Alvy Ray Smith, Computer Graphics Project, Lucasfilm, June 24, 1983 (rev. May 4, 1984). p. 602, second paragraph: the matrix Tij should be: [ 1 0 0 0 ] [ 0 1/2 0 0 ] [ 0 0 1/4 0 ] [ 0 0 0 1/8 ] p. 610: the binomial "( n-i [over] j )" should be "( n-1 [over] j )". This error appears on the fifth line of the long derivation and within the Zi,j definition. p. 809: the author of "Approximation of Sweep Surfaces by Tensor Product B-Splines" is M. (not J.) Bloomenthal. The author is correctly attributed in the text (page 569). p. 814: 5th line from bottom. "Knuth 1981" should read "Knuth 1981b" and "Vol. 2" should read "Vol. 1". The reference above this should be "Knuth 1981a". p. 820, 9th line from bottom: "D.P. Greenburg" should be "D.P. Greenberg". ----- The following are errors in the code listings (corrected in the online code at princeton.edu:pub/Graphics/GraphicsGems/Gems). Serious errors (ones your compiler cannot or may not catch): p. 630: Delete FLOOR and CEILING macros (they're more like truncations). Change ROUND macro to (i.e. add parentheses around "a"): #define ROUND(a) ((a)>0 ? (int)((a)+0.5) : -(int)(0.5-(a))) Change SGN macro to (i.e. change positive condition result to "1"): #define SGN(a) (((a)<0) ? -1 : 1) p. 632: procedure declarations for routines in the "2D and 2D Vector C Library" (next pages) are missing from "GraphicsGems.h", e.g. double V2SquaredLength() ; double V2Length() ; Vector2 *V2Negate() ; ... p. 638, third line from bottom: in V3Combine change last "result->y" to "result->z" p. 640: V3MulPointByMatrix() does not work. A separate local Point3 (e.g. "Point3 q ;") should be used in place of "p" for assignment and then passed back. p. 649, top: add "#include " p. 662, line 10: add "#include " p. 665, line 1: change "FLOOR(...)" to "(floor((double)(...))". p. 663, line 45: change first "+" to "="; should read "VnextLeft = (Vleft=VnextLeft) + 1;" p. 667, line 6: change "POLY_NMAX 8" to "POLY_NMAX 10" (for triangles and quadrilaterals). Six clipping planes used on convex polygons gives +6 potential extra vertices generated. p. 670-673, throughout: change "int mask" declarations to "unsigned long mask" declarations. This avoids an infinite loop occuring when the highest bit is set. p. 676, line 11: add the line "up = (double *)u;" p. 671, line 1: add at top of page the following test (or make sure the Poly_vert structure has <= 32 doubles at compilation time): if (sizeof(Poly_vert)/sizeof(double) > 32) { fprintf(stderr, "Poly_vert structure too big; must be <=32 doubles\n"); exit(1); } p. 687, line 8: Identical points cause two points to be drawn. Between the first two plot() commands, add the line: if ( pixels_left < 0 ) return ; p. 714, line 20: the last "1" in "if (i + 1 < l * 1)" should be an "l" p. 716, line 27: missing "/" at end of comment (if not fixed, code compiles but is wrong) p. 720, lines 3 and 6 from bottom: change "m+1>>1" to "(m+1)>>1" to establish correct evaluation order. p. 737, lines 19-24, from "if ((quadrant..." to "}", should read (and note corrected indentations on "else" statement): if (coord[i] < minB[i] || coord[i] > maxB[i]) return (FALSE); } else { coord[i] = candidatePlane[i]; } p. 745, throughout: delete references to "lx", which is set but not used p. 748, line 22: change "negetive" to "negative" p. 753, line 35: change "int n1, n2," to "int n1=0, n2=0," so that first fprintf() error message has defined values p. 756, line 15: "unsigned int *fi=&f;" to "unsigned int *fi = (unsigned int *) &f;" for type consistency, and some compilers think "=&" means "&=" p. 766, top: add '#include "GraphicsGems.h"' and '#include ' line 25: change "det = det4x4( out );" to "det = det4x4( in );" throughout: change "matrix4" to "Matrix4" p. 774, line 5: change "theta," to "theta = 0," p. 799, bottom and p. 800, line 11: add this pair of lines between "DrawBezierCurve(...);" and "return;": free((void *)u); free((void *)bezCurve); Also, see errata note at end of this file. p. 800, line 19: add this pair of lines before "tHatCenter = ...": free((void *)u); free((void *)bezCurve); Syntax errors (ones your compiler or lint will catch): p. 633-642, throughout: replace "};" with "}" to make lint happy p. 640, gcd(): the variable "k" is set but not used - remove it p. 649, line 31: change "LengthVector3" to "V3Length" p. 650, line 1: bad end-of comment; delete "/" p. 651, throughout: Can't use "const" as a variable name, as it is a reserved word in ANSI C. Use "liconst" instead. p. 657, 659: make "nicenum" declarations match, i.e. use either "double nicenum()" or "static double nicenum()" for both occurrences p. 659: change "exp" to "expv", since "exp()" is a math library function. p. 660, line 11: header missing end of comment "*/" p. 662, line 13: change "SYBYRES" to "SUBYRES" line 16: bad space after "MODRES" line 42: change "XRmax" to "xRmax" p. 665, line 15: missing semicolon after "int area" line 27: change "O" to "0" in "if (partialArea>O)" p. 666, line 13: change "O" to "0" in "rightMask = O;" p. 670, top: add to make lint happy static scanline(); static incrementalize_y(); static incrementalize_x(); static increment(); p. 671, line 35: missing "{" at end of "while (y" (or strings.h) p. 727, line 11: remove ")" in "static double bigC,..." line p. 728, lines 21-23: change "cal_q_msq" to "calc_q_msq" lines 23,42: change "NULL" to "(double *)NULL" to make lint happy line 26: change "con_const" to "cone_const" in "bigC = m1sq + con_const * q1" last line: add a "}" to end albers_project procedure p. 730: missing inclusion of GraphicsGems.h. p. 734, line 4: change "exit();" to "exit(1);" p. 736, line 20: change "O" to "0" in "for (i=O;" p. 739, line 12: change "else if (D > 0)" to "else", since at this point D must be greater than 0; makes lint happy p. 757, line 4: change "{" to "[" in "sqrttab{" line 14: change "= &n" to "= (unsigned int *)&n" line 21: change "*num & = 0x7fffff:" to "*num &= 0x7fffff;" to fit ANSI C, and to fix error of ":" at end of line. line 22: change "| =" to "|=" line 27: change ":" to ";" p. 765, line 20,22: change "Matrix" to "Matrix4" p. 766, line 29: change "exit();" to "exit(1);" p. 774, line 2: missing ";" at end of "long *argx, *argy" p. 775: P, Q, and M need to be declared as externs p. 780, line 18: bad start of comment for "/ re-parameterization" p. 785, line 1: bad start-of-comment p. 789, lines 7,25: change both "NULL" to "(Point2 *)NULL" to make lint happy in ConvertToBezierForm: "t" is not used, can be deleted p. 791, line 24: remove "break;" after "return 0;"; unnecessary p. 793, ControlPolygonFlatEnough: "t" is not used, can be deleted p. 795, ComputeXIntercept: "T" and "Y" do not have to be computed, since the result "Y" is not returned. Note that there are many operations in this routine that are unnecessary (e.g. "0.0 - 0.0"). p. 797-807, throughout: change "V2ScaleII" to "V2ScaleIII" and "Bezier" to "BezierII" in order to avoid name collisions with the code on pages 787-796 (i.e. the same subroutine names are used in both, but with different argument types, etc). Important only if you link in both of these subroutine libraries. ----- The following are typographical errors in the comments: p. 687, line 3: "plottted" to "plotted" p. 701, line 26: change "interscetion" to "intersection" p. 728, line 10: "latitute" to "latitude" p. 729, line 8: "degress" to "degrees" p. 724, line 38: "seperated" to "separated" p. 725, lines 7-9: "componant" to "component" p. 730, line 17: "minium" to "minimum" p. 752, line 2: "positve" to "positive" p. 760, line 5: "interger" to "integer" p. 761, line 4: "preceed" to "precede" p. 766, throughout (5 times): "determinent" to "determinant" p. 781, lines 7,23: "demoninator" to "denominator" ----- Addenda: There is additional code for Kelvin Thompson's "Rendering Anti-Aliased Lines" gem in the online distribution of the code. ----- Concerning page 799, Philip Schneider's Bezier code: If you are operating in a dimensional system such that the desired error in the fitting process is a fraction (e.g., 0.01 inches) rather than a whole number (e.g., 2.0 pixels), then the line on page 799 reading iterationError = error * error; should be changed to iterationError = ERRFACTOR * error; where ERRFACTOR is #defined to some implementation-dependent value such as 4.0. If this is not done, then reparameterization will never occur. The result is not an erroneous curve, but a suboptimal one; the algorithm will always subdivide when the initial fit is too "loose." (from Earl Boebert, boebert@SCTC.COM)