This is a volume in
The Graphics Gems Series
A Collection of Practical Techniques
for the Computer Graphics Programmer
Series Editor
Andrew S. Glassner
Xerox Palo Alto Research Center
Palo Alto, Califomia
GRAPHICS
GEMS
II
edited by
JAMES ARVO
Program of Computer Graphics
Cornell University
Ithaca, New York
AP PROFESSIONAL
Boston
San Diego
NewYork
London Sydney Tokyo Toronto
Copyright (c) 1995 by Academic Press, Inc.
GRAPHICS GEMS copyright (c) 1990 by Academic Press, Inc.
GRAPHICS GEMS II copyright (c) 1991 by Academic Press, Inc.
GRAPHICS GEMS III copyright (c) 1992 by Academic Press, Inc.
QUICK REFERENCE TO COMPUTER GRAPHICS TERMS
copyright (c) 1993 by Academic Press, Inc.
RADIOSITY AND REALISTIC IMAGE SYNTHESIS
copyright (c) 1993 by Academic Press Inc.
VIRTUAL REALITY APPLICATIONS AND EXPLORATIONS
copyright (c) 1993 by Academic Press Inc.
All rights reserved.
No part of this product may be reproduced or transmitted in any form or by any
means, electronic or mechanical, including input into or storage in any information
system, other than for uses specified in the License Agreement, without permission
in writing from the publisher.
Except where credited to another source, the C and C++ Code may be used freely to
modify or create programs that are for personal use or commercial distribution.
Produced in the United States of America
ISBN 0-12-059756-X
About the Cover
The cover image is the second in the “Gems” theme that I began last year. Andrew
Glassner and I bounced some ideas back and forth, and the design solidified pretty
quickly. The gems themselves are the same as in last year ’s image.The picture was
generated at Pacific Data Images using their in-house software. All of the textures and
models are procedurally generated. The sand texture, the sand surface shape, the
woodgrain, the sea foam, and the starfish texture are all derived from fractal noise
patterns. I spent most of my time on the water, making it look all shiny and wet and
transparent, but not too transparent. The foam on the water ’s surface was also very timeconsuming. Another challenge was to get the gems to all pile on top of each other
convincingly. I wrote a program that dropped them, one at a time, and as they fell, they
were rotated to the angle that moved them the furthest down without intersecting
anything that was there already. This program took a couple of hours to run, but it was
much faster than trying to place them by hand. The picture was rendered with a raytracing program and took 50 hours on an Silicon Graphics 4D25 computer at a resolution
of 2250 × 3000 pixels with four samples per pixel.
♦
Thaddeus Beier
Silicon Graphics Computer Systems
When Andrew asked if I wanted to do the cover for Graphics Gems II, I said “Sure . .
. we can reuse the software we built last year for Graphics Gems.” While it wasn’t quite
that simple, it was much easier to produce this cover than the first one. As before, the
image was designed on a color monitor producing red, green and blue pixels. For
printing, we needed to convert these pixels to cyan, magenta, yellow, and black pixels
(printer color space). Once in this form, the image was processed commercially to
produce half-toned film suitable for printing. This final step was performed at KedieOrent, Sunnyvale, California, on their Crosfield digital prepress system.
As was the case with the first “Gems” picture, many of the original image colors could
not be exactly reproduced in print form. The colors had to be modified to map into the
set of colors that can be produced by the printer, its gamut. The trick is to do the
modification while maintaining the appearance of the image. In this picture, the colors
in the sand, shells, and water were mostly inside the printer gamut. However, some of
the gem colors, particularly the bright blue-greens, were far outside the gamut. The
transformation we applied was similar to the one we designed for Graphics Gems; colors
outside of the gamut were desaturated to colors of the same lightness while maintaining
the same hue. If one color of a particular hue needed to be desaturated, all colors of
the same hue would be desaturated to preserve shading detail. However, colors outside
of the gamut move more than colors inside of the gamut to maintain the overall
saturation.
The colors of the Graphics Gems II cover are lighter and more delicate than the cover
of Graphics Gems, and much more of the image lies in the interior of the printer gamut.
We tuned the transformation for this image to minimize the change to the less saturated
colors, preserving the subtle shading in the sand and water.
Thanks to Bill Wallace, who wrote the original gamut mapping software for Graphics
Gems, and to Ken Fishkin, who helped with the production of the cover this year.
Maureen Stone
Xerox Palo Alto Research Center
v
vi
C ONTENTS
The symbol C denotes gems that have accompanying C implementations on disk.
Foreword
By Andrew Glassner
xvii
Preface
xix
Mathematical Notation
xxi
Pseudo-Code
xxiii
Contributors
xxix
I
2 D GEOMETRY AND ALGORITHMS
Introduction
3
1. The Area of a Simple Polygon
Jon Rokne
2. Intersection of Line Segments
Mukesh Prasad
5
C
7
3. Distance from a Point to a Line
Jack C. Morrison
10
4. An Easy Bounding Circle
Jon Rokne
14
vii
CONTENTS
5. The Smallest Circle Containing the Intersection
of Two Circles
Jon Rokne
C
17
6. Appolonius’s 10th Problem
Jon Rokne
19
7. A Peano Curve Generation Algorithm
Ken Musgrave
C
25
8. Space-Filling Curves and a Measure of Coherence
Douglas Voorhies
C
9. Scanline Coherent Shape Algebra
26
31
Jonathan E. Steinhart
II
I MAGE PROCESSING
Introduction
49
1. Image Smoothing and Sharpening by Discrete
Convolution
Dale A. Schumacher
2. A Comparison of Digital Halftoning Techniques
Dale A. Schumacher
50
C
75
3. Color Dithering C
Spencer W. Thomas and Rod G. Bogart
72
4. Fast Anamorphic Image Scaling
Dale A. Schumacher
78
5. Real Pixels
Greg Ward
80
6. A Fast 90-Degree Bitmap Rotator
Sue-Ken Yap
C
84
viii
CONTENTS
7. Rotation of Run-Length Encoded Image Data
Jeff Holt
C
86
8. Adaptive Run-Length Encoding
Andrew S. Glassner
89
9. Image File Compression Made Easy
Alan W. Paeth
93
10. An Optimal Filter for Image Reconstruction
Nelson Max
101
11. Noise Thresholding in Edge Images
John Schlag
105
12. Computing the Area, the Circumference, and the Genus
of a Binary Digital Image C
Hanspeter Bieri and Andreas Kohler
107
III
F RAM
E BUFFER TECH
N IQUES
RAME
TECHN
Introduction
1. Efficient Inverse Color Map Computation
Spencer W. Thomas
115
116
C
2. Efficient Statistical Computations for Optimal Color
Quantization
Xiaolin Wu
3. A Random Color Map Animation Algorithm
Ken Musgrave
C
126
134
4. A Fast Approach to PHIGS PLUS Pseudo Color
Mapping
James Hall and Terence Lindgren
138
5. Mapping RGB Triples onto 16 Distinct Values
143
ix
CONTENTS
6. Television Color Encoding and “Hot” Broadcast
Colors C
David Martindale and Alan W. Paeth
147
7. An Inexpensive Method of Setting the Monitor
White Point
Gary W. Meyer
159
8. Some Tips for Making Color Hardcopy
Ken Musgrave
163
IV
3 D GEOMETRY AND ALGORITHMS
Introduction
169
1. Area of Planar Polygons and Volume of Polyhedra
Ronald N. Goldman
170
2. Getting Around on a Sphere
Clifford A. Shaffer
172
3. Exact Dihedral Metrics for Common Polyhedra
Alan W. Paeth
174
4. A Simple Viewing Geometry
Andrew S. Glassner
179
5. View Correlation
Rod G. Bogart
181
C
6. Maintaining Winged-Edge Models
Andrew S. Glassner
191
7. Quadtree/Octree-to-Boundary Conversion
Claudio Montani and Roberto Scopigno
202
8. Three-Dimensional Homogeneous Clipping
of Triangle Strips C
Patrick-Gilles Maillot
219
x
CONTENTS
9.
InterPhong Shading C
Nadia Magnenat Thalmann, Daniel Thalmann,
and Hong Tong Minh
232
V
R AY TRACING
Introduction
245
1.
Fast Ray–Convex Polyhedron Intersection
Eric Haines
2.
Intersecting a Ray with an Elliptical Torus
Joseph M. Cychosz
3.
Ray–Triangle Intersection Using Binary Recursive
Subdivision
Douglas Voorhies and David Kirk
247
C
C
251
257
4.
Improved Ray Tagging for Voxel-Based Ray Tracing
David Kirk and James Arvo
5.
Efficiency Improvements for Hierarchy Traversal
in Ray Tracing
Eric Haines
267
A Recursive Shadow Voxel Cache for Ray
Tracing C
Andrew Pearce
273
Avoiding Incorrect Shadow Intersections for Ray
Tracing
Andrew Pearce
275
A Body Color Model: Absorption of Light through
Translucent Media
Mark E. Lee and Samuel P. Uselton
277
More Shadow Attenuation for Ray Tracing Transparent
or Translucent Objects
Mark E. Lee and Samuel P. Uselton
283
6.
7.
8.
9.
264
xi
CONTENTS
Vl
R ADIOSITY
Introduction
1.
2.
293
Implementing Progressive Radiosity with UserProvided Polygon Display Routines C
Shenchang Eric Chen
295
A Cubic Tetrahedral Adaptation of the Hemi-Cube
Algorithm
Jeffrey C. Beran-Koehn and Mark J. Pavicic
299
3.
Fast Vertex Radiosity Update
Filippo Tampieri
4.
Radiosity via Ray Tracing
Peter Shirley
5.
Detection of Shadow Boundaries for Adaptive Meshing
in Radiosity
François Sillion
C
303
306
311
Vll
M ATRIX TECHNIQUES
Introduction
1.
Decomposing a Matrix into Simple
Transformations C
Spencer W. Thomas
319
320
2.
Recovering the Data from the Transformation Matrix
Ronald N. Goldman
324
3.
Transformations as Exponentials
Ronald N. Goldman
332
4.
More Matrices and Transformations: Shear and
Pseudo-Perspective
Ronald N. Goldman
338
xii
CONTENTS
5.
Fast Matrix Inversion
Kevin Wu
342
6.
Quaternions and 4 × 4 Matrices
Ken Shoemake
351
7.
Random Rotation Matrices
James Arvo
355
8.
Classifying Small Sparse Matrices
James Arvo
C
C
357
C
Vlll
N UMERICAL AND PROGRAMMING
T ECHNIQUES
Introduction
365
1.
Bit Picking
Ken Shoemake
366
2.
Faster Fourier Transform
Ken Shoemake
368
3.
Of Integers, Fields, and Bit Counting
Alan W. Paeth and David Schilling
4.
Using Geometric Constructions to Interpolate
Orientation with Quaternions
John Schlag
C
371
377
5.
A Half-Angle Identity for Digital Computation:
The Joys of the Halved Tangent
Alan W. Paeth
381
6.
An Integer Square Root Algorithm
Christopher J. Musial
387
7.
Fast Approximation to the Arctangent
Ron Capelli
C
389
xiii
CONTENTS
8. Fast Sign of Cross Product Calculation
Jack Ritter
392
C
9. Interval Sampling
Ken Shoemake
10. A Recursive Implementation of the Perlin Noise Function
Greg Ward
394
C
396
IX
C URVES AN
D SURFACES
AND
Introduction
1. Least-Squares Approximations to Bézier Curves
and Surfaces
Doug Moore and Joe Warren
2. Beyond Bézier Curves
Ken Shoemake
3. A Simple Formulation for Curve Interpolation
with Variable Control Point Approximation
John Schlag
405
406
412
417
4. Symmetric Evaluation of Polynomials
Terence Lindgren
420
5. Menelaus’s Theorem
Hans-Peter Seidel
424
6. Geometrically Continuous Cubic Bézier Curves
Hans-Peter Siedel
428
7. A Good Straight-Line Approximation of a Circular
Arc C
Christopher J. Musial
435
8. Great Circle Plotting
Alan W. Paeth
440
9. Fast Anti-Aliased Circle Generation
Xiaolin Wu
446
xiv
PSEUDO-CODE
.
PSEUDO-CODE
.
FOREWORD
F OREWORD
by Andrew Glassner
Welcome to Graphics Gems II, a new collection of practical techniques
and methods for the computer graphics programmer. This book is a
collection of contributions from many people, most of whom work independently of each other. Yet through these volumes we are able to share
our observations and insights with each other and our readers, and
together build a communal library of graphics programming techniques.
In the preface to the original Graphics Gems, I wrote that “This
book . . . concludes one turn of a cycle of discovery, documentation,
editing, publishing, and reading, which will in turn lead to new discoveries.” I am delighted that we have completed another loop around the
cycle, and emerged with another strong collection of programming techniques. As with its predecessor, the articles in this book are primarily not
research results; those can be found in the formal professional literature.
Rather, the Graphics Gems books are a conduit for practical information. Much of the detailed information in these volumes would be inappropriate for a technical paper, but is invaluable to the implementor.
This volume has been edited by Jim Arvo, who is well known in the
graphics community as a skilled researcher and teacher. Jim and I have
taught several courses together at SIGGRAPH conferences and other
venues, and I have always been impressed with his insight and eagerness
to share his knowledge. The fine selection and organization of material in
this volume demonstrates his abilities well.
There may be more volumes in the Graphics Gems series. We will
continue to solicit and collect contributions, and organize them into new
books, as long as the quality remains high and the results useful. Each
GRAPHICS GEMS II Edited by JAMES ARVO
xvii
FOREWORD
volume will be edited by a different individual, since I believe this will
help keep the results lively and fresh, and reflect the diversity that is part
of what makes computer graphics such an exciting field to work in.
One quality that I believe is shared by most engineers and scientists
is a desire for elegance. An elegant solution is one that is simple and direct,
and often provokes an “Aha!” reaction when first encountered. Often
such clean techniques depend on an insight derived from knowledge or
experience from another context. Many of the techniques in this book fit
this criterion for elegance, and enlarge the repertoire of tools upon which
we draw for solutions to new, unexpected challenges. Each time we learn
how another person solved an important problem, we grow as designers
and implementors.
It is in celebration of the twin spirits of growth and sharing that we
bring you this book. I hope you find it informative and useful.
GRAPHICS GEMS II Edited by JAMES ARVO
xviii
PREFACE
P REFACE
Continuing in the spirit of the inaugural Graphics Gems volume,
Graphics Gems II represents the collective expertise of a large and
diverse group of people. The common thread shared by all the contributors is that each has devised or refined useful ideas which can benefit
other computer graphics practitioners, and they have graciously agreed to
disseminate them. The resulting amalgam has a character quite distinct
from any text book on the subject, as it reflects ideas and approaches
every bit as diverse and unique as the people behind them.
In the field of computer graphics, as with almost any endeavor, there is
rarely a best way to do anything. Therefore, this volume shares a recurring theme with the original volume by presenting techniques for doing
well-known operations faster or easier. Some present a new way of
looking at an old problem while others provide useful mathematical
machinery with broad application.
There are several ways to use this book. First, it can be a source of
solutions to specific problems. If one of the gems in this collection
addresses a particular problem of interest to you, the idea can be
employed with little ado. This is facilitated by the program listings
provided with many of the gems. A second way to use this book is to
simply browse, learning clever solutions to problems you may not have
encountered or even considered yet. Often the ideas behind the gems can
be applied in contexts much broader than those shown, or they may serve
as the seeds to get you thinking along new lines. In any event, there is
much to be gained by looking over the shoulders of experienced graphics
programmers as they apply the subtle tricks of the trade.
The overall structure, mathematical notation and pseudo-code used
here are the same as in the first volume. The scope and names of some
GRAPHICS GEMS II Edited by JAMES ARVO
xix
PREFACE
parts have been changed slightly to best accommodate this new collection
of gems. In order to make this book as self-contained as possible we have
included several of the important sections verbatim from the first volume
for easy reference; there are the sections entitled “Mathematical Notation”, “Pseudo-Code”, and the listings “Graphics Gems C Header File”
and “2D and 3D Vector Library” in Appendix I. The last of these contains
several corrections and extensions. Only the part titled “Radiosity” has
no counterpart in the first volume. This new part has been added to
complement the part on ray tracing and to reflect current research trends.
The gems comprising each part all relate to some common theme.
Gems that share something more fundamental are linked via the “See
also” section at the end of each gem. Gems identified by gem number are
contained in this volume; gems identified by page number are in the first
volume of Graphics Gems. The mathematical background which is assumed in most of the gems is limited to elementary calculus and linear
algebra, the staples of computer graphics.
The C programming language has been used for all the program listings
in the appendix because it is widely used and is among the most portable
of languages. It is also a favorite among graphics programmers because
of its flexibility. These considerations made it the obvious choice. All the
C code in this book is in the public domain, and is yours to study, modify,
and use. As of this writing, all code listings are available via anonymous
ftp transfer from the machine “weedeater.math.yale.edu” (internet address 130.132.23.17). When you connect to this machine using ftp, log in
as “anonymous”, and give your own last name as the password. Then use
the “cd” command to move to the directory “pub/GraphicsGems”.
Download and read the file called README to learn about where the code
is kept, and how to report bugs.
Thanks are due to the many people who made this book possible. First
and foremost I’d like to thank all the gem contributors, whose expertise
and insight is what this book is all about. Also, I’d like to thank Andrew
Glassner for pioneering this whole adventure and for assisting in every
aspect along the way. Special thanks to Terry Lindgren for his
tremendously helpful input where it was most needed, and to Greg
Ward, John Francis, Paul Heckbert, and Eric Haines for their reviews,
expert opinions, and helpful suggestions. Finally, I’d like to thank Craig
Kolb for providing a safe haven for the public domain C code.
GRAPHICS GEMS II Edited by JAMES ARVO
xx
MATHEMATICAL NOTATION
M ATHEMATICAL
N OTATION
Geometric Objects
0
a, b, c
P, Q
l, m
A, B
M
θ, ϕ
the number 0, the zero vector, the point (0, 0), the
point (0, 0, 0)
the real numbers (lower–case italics)
points (upper-case italics)
lines (lower-case bold)
vectors (upper-case bold)(components A i)
matrix (upper-case bold)
angles (lower-case greek)
Derived Objects
A⊥
M -1
MT
M
*
|M|
det(M)
Mi,j
M i,
the
A⊥
the
the
vector perpendicular to A (valid only in 2D, where
= (−A y, A x)
inverse of matrix M
transpose of matrix M
−1
M∗
=
M
the adjoint of matrix M
det ( M )
determinant of M
same as above
element from row i, column j of matrix M (top-left is
(0, 0)
all of row i of matrix M
GRAPHICS GEMS II Edited by JAMES ARVO
xxi
MATHEMATICAL NOTATION
M ,j
∆ ABC
∠ ABC
all of column j of Matrix
triangle formed by points A, B, C
angle formed by points A, B, C with vertex at B
Basic Operators
+, −, /, ∗
⋅
×
standard math operators
the dot (or inner or scalar) product
the cross (or outer or vector) product
Basic Expressions and Functions
x
x
floor of x (largest integer not greater than x)
a|b
a mod b
Bni ( t )
ceiling of x (smallest integer not smaller than x)
modulo arithmetic; remainder of a ÷ b
same as above
n i
n−i
Bernstein polynomial = t (1 − t ) , i = 0Ln
i
n
i
binomial coefficient
n!
( n− i ) !i!
GRAPHICS GEMS II Edited by JAMES ARVO
xxii
PSEUDO-CODE
P SEUDO-CODE
Declarations (not required)
name: TYPE ← initialValue;
examples:
π :real ← 3.14159;
v: array [0..3] of integer ← [0, 1, 2, 3];
Primitive Data Types
array [lowerBound..upperBound] of TYPE;
boolean
char
integer
real
double
point
vector
matrix3
equivalent to:
matrix3: record [array [0..2] of array [0..2] of real;];
example: m:Matrix3 ← [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]];
m[2][1] is 8.0
m[0][2]← 3.3;
assigns 3.3 to upper-right corner of matrix
GRAPHICS GEMS II Edited by JAMES ARVO
xxiii
PSEUDO-CODE
matrix4
equivalent to:
matrix4: record [array [0..3] of array [0..3] of real;];
example: m: Matrix4 ← [
[1.0, 2.0, 3.0, 4.0],
[5.0, 6.0, 7.0, 8.0],
[9.0, 10.0, 11.0, 12.0],
[13.0, 14.0, 15.0, 16.0]];
m[3][1] is 14.0
m[0][3] ← 3.3; assigns 3.3 to upper-right corner of matrix
Records (Structures)
Record definition:
Box: record [
left, right, top, bottom: integer;
];
newBox: Box ← new[Box];
dynamically allocate a new instance of Box and return a pointer to it
newBox.left ←10;
this same notation is appropriate whether newBox is a pointer or
structure
Arrays
v: array [0..3] of integer ← [0, 1, 2, 3]; v is a four-element array of integers
v[2] ← 5;
assign to third element of v
Comments
A comment may appear anywhere–it is indicated by italics
GRAPHICS GEMS II Edited by JAMES ARVO
xxiv
PSEUDO-CODE
Blocks
begin
Statement;
Statement;
L
end;
Conditionals and Selections
if Test
then Statement;
[else Statement];
else clause is optional
result = select Item from
instance: Statement;
endcase: Statement;
Flow Control
for ControlVariable: Type ← InitialExpr, NextExpr do
Statement;
endloop;
until Test do
Statement;
endloop;
while Test do
Statement;
endloop;
loop; go directly to the next endloop
exit; go directly to the first statement after the next endloop
return[value]
return value as the result of this function call
GRAPHICS GEMS II Edited by JAMES ARVO
xxv