Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G....

140
Notes on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland. email: jonathan dot campbell (at) gmail.com, [email protected] URL:http://www.jgcampbell.com/msc2d3d/grmaths.pdf Report No: jc/08/0001/r Revision 2.3 (recompiled with tags / links) Revision 2.4 (new App.B since 2.2) Revision 2.5 (transformations bwteen frames added to chapter 7) 19th August 2008

Transcript of Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G....

Page 1: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Notes on Mathematics for 2D and 3D Graphics

Jonathan G. Campbell

Department of Computing,

Letterkenny Institute of Technology,

Co. Donegal, Ireland.

email: jonathan dot campbell (at) gmail.com, [email protected]

URL:http://www.jgcampbell.com/msc2d3d/grmaths.pdf

Report No: jc/08/0001/r

Revision 2.3 (recompiled with tags / links)

Revision 2.4 (new App.B since 2.2)

Revision 2.5 (transformations bwteen frames added to chapter 7)

19th August 2008

Page 2: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Contents

1 Introduction 1

1.1 Scope and Objective . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

1.2 Understanding Mathematics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

1.3 Recommended Additional Reading . . . . . . . . . . . . . . . . . . . . . . . . . . 2

1.4 Web and Other Resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

1.5 Outline of the Document . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2 Coordinate Geometry and Trigonometry 1

2.1 Coordinate Geometry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

2.2 Trigonometry . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.2.1 Sin, cos, coordinates and circles . . . . . . . . . . . . . . . . . . . . . . . 5

2.2.2 Sine and cosine functions . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.2.3 Inverse sin, cos, tan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

3 Vectors 1

3.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

3.2 Vector Algebra . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

3.3 Vector Basis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

3.3.1 Components and vector basis . . . . . . . . . . . . . . . . . . . . . . . . 2

3.3.2 Vector algebra using components . . . . . . . . . . . . . . . . . . . . . . 4

3.3.3 Linear Independence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

3.4 Scalar (dot) product . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

3.4.1 Vector length / magnitude . . . . . . . . . . . . . . . . . . . . . . . . . . 5

3.4.2 Direction, unit vector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

3.4.3 Angle between two vectors . . . . . . . . . . . . . . . . . . . . . . . . . . 6

3.4.4 Tests for Orthogonality and Parallelism . . . . . . . . . . . . . . . . . . . 6

3.4.5 Direction Cosines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

3.4.6 Scalar product and projection . . . . . . . . . . . . . . . . . . . . . . . . 8

3.5 Vector (cross) Product . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

3.6 Vector Space . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

4 Matrices and Linear Algebra 1

4.1 Linear Simultaneous Equations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

4.2 Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

4.3 Basic Matrix Arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

4.3.1 Matrix Multiplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

4.3.2 Multiplication by a Scalar . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

4.3.3 Addition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

4.4 Special Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

4.4.1 Identity Matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

0–1

Page 3: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

4.4.2 Orthogonal Matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

4.4.3 Diagonal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

4.4.4 Transpose of a Matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

4.5 Inverse Matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

4.6 Octave Matrix Calculator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

5 Vector Transformations 1

5.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

5.2 Linear Transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

5.3 Matrices as Linear Transformations . . . . . . . . . . . . . . . . . . . . . . . . . 3

5.4 Points and Vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

5.5 Anatomy of a Linear Transformation . . . . . . . . . . . . . . . . . . . . . . . . . 5

5.6 Examples of Linear Transformations . . . . . . . . . . . . . . . . . . . . . . . . . 9

5.6.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

5.6.2 Scaling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

5.6.3 Rotation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

5.6.4 Shear . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

5.6.5 Reflection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

5.6.6 Reflection as Negative Scaling . . . . . . . . . . . . . . . . . . . . . . . . 16

5.6.7 Projection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

5.6.8 Translation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

5.6.9 Window to Viewport Transformation . . . . . . . . . . . . . . . . . . . . 19

5.6.10 A Handy Shifting and Scaling Formula . . . . . . . . . . . . . . . . . . . . 21

5.6.11 Rigid Body Transformation . . . . . . . . . . . . . . . . . . . . . . . . . . 21

5.7 Pre-multiplication versus Post-multiplication of matrices . . . . . . . . . . . . . . 22

5.8 Memory Layout of Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

5.9 Complex Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

5.9.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

5.9.2 Complex Numbers as Real Number Pairs . . . . . . . . . . . . . . . . . . 25

5.9.3 Algebra of Complex Numbers . . . . . . . . . . . . . . . . . . . . . . . . 25

5.9.4 Hamilton’s Real Number Pairs . . . . . . . . . . . . . . . . . . . . . . . . 25

5.9.5 Complex Numbers as Algebra for Euclidean Geometry . . . . . . . . . . . 26

5.9.6 Translation and Dilative Rotation . . . . . . . . . . . . . . . . . . . . . . 27

5.9.7 Algebraic Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

5.9.8 Operator Character . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

5.9.9 Link with Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

6 Affine Transformations and Homogeneous Coordinates 1

6.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

6.2 Points and Vectors and Affine Spaces . . . . . . . . . . . . . . . . . . . . . . . . 2

6.3 Frames . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

6.4 Affine Transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

6.5 Homogeneous Coordinates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

6.5.1 Point at Infinity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

6.5.2 Vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

6.5.3 Points and Vectors in OpenGL . . . . . . . . . . . . . . . . . . . . . . . . 5

6.6 2D Affine Transformations in Homogeneous Coordinates . . . . . . . . . . . . . . 6

6.6.1 Translation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

6.6.2 Rotation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

0–2

Page 4: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

6.6.3 Scaling, Shearing, Reflection . . . . . . . . . . . . . . . . . . . . . . . . . 6

6.7 Composition of Homogeneous Transformations . . . . . . . . . . . . . . . . . . . 6

7 3D Transformations 1

7.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

7.2 3D Homogeneous Coordinates . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

7.3 3D Affine Transformations in Homogeneous Coordinates . . . . . . . . . . . . . . 2

7.3.1 Translation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

7.3.2 Rotation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

7.3.3 Scaling, Shearing, Reflection . . . . . . . . . . . . . . . . . . . . . . . . . 3

7.4 Transformations Between Frames . . . . . . . . . . . . . . . . . . . . . . . . . . 3

7.4.1 Rotation about other axes . . . . . . . . . . . . . . . . . . . . . . . . . . 6

7.4.2 Include Translation between Frames . . . . . . . . . . . . . . . . . . . . . 7

7.4.3 Transformation in the opposite direction . . . . . . . . . . . . . . . . . . . 7

7.4.4 Concatenation of Transformations between Frames . . . . . . . . . . . . . 7

8 Projections 1

8.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

8.2 Eyes and Cameras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

8.3 Perspective Transformation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

8.3.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

8.3.2 Geometry of Perspective . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

8.3.3 OpenGL glFrustum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

8.3.4 Derivation of Perspective Transformation . . . . . . . . . . . . . . . . . . 6

8.3.5 Orthographic Projection . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

9 Quaternions 1

9.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

9.2 The Algebra of Quaternions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

9.2.1 Addition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

9.2.2 Multiplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

9.2.3 Inverse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

9.2.4 Scalar Products — no inverse . . . . . . . . . . . . . . . . . . . . . . . . 4

9.2.5 Point as Quaternion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

9.2.6 Rotation Quaternion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

9.2.7 Rotation — an example . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

9.2.8 Multiplicative Absolute Value . . . . . . . . . . . . . . . . . . . . . . . . . 7

9.3 Why use Quaternions? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

9.4 Conversions to and from Quaternions etc. . . . . . . . . . . . . . . . . . . . . . . 8

9.5 Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

A Abstract Algebra on a Set S 1

B Vectors and 2D Transformations in Java 1

B.1 Vector2DH.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

B.2 Test Program for Vector2DH.java . . . . . . . . . . . . . . . . . . . . . . . . . . 8

B.3 Transform2D.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

B.4 Test for Transform2D.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

0–3

Page 5: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

C 3D Affine Transformations in Java 1

C.1 Homogeneous 3D Vector — Vector4D.java . . . . . . . . . . . . . . . . . . . . . 1

C.2 Test for Vector4D.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

C.3 Homogeneous 3D Vector Transformations — Transform4D.java . . . . . . . . . . 4

C.4 Test for Transform4D.java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

D 3D Affine Transformations in C++ 1

D.1 Homogeneous 3D Vector — Vector4D.h . . . . . . . . . . . . . . . . . . . . . . . 1

D.2 Homogeneous 3D Vector — Vector4D.cpp . . . . . . . . . . . . . . . . . . . . . 2

D.3 Test for Vector4D.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

D.4 Homogeneous 3D Vector Transformations — Transform4D.h . . . . . . . . . . . 4

D.5 Homogeneous 3D Vector Transformations — Transform4D.cpp . . . . . . . . . . 5

D.6 Test for Transform4D.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

E Quaternions in Java 1

E.1 Quaternion class — Quaternion.java . . . . . . . . . . . . . . . . . . . . . . . . . 1

E.2 Example Program using Quaternions . . . . . . . . . . . . . . . . . . . . . . . . . 5

0–4

Page 6: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Chapter 1

Introduction

1.1 Scope and Objective

The objectives of these Notes on Mathematics for Computer Graphics are threefold:

• to collect in one place a set of facts and formulas that surround the theoretical basis of

two-dimensional (2D) and three-dimensional (3D) computer graphics. It is aimed at two

course: BSc in Computer Games Development module games Programming 1, and MSc in

Computer Games Development module 2D and 3D Computer Graphics. It starts at a very

elementary level; whilst we would expect students to know trigonometry, there is no harm in

having a resource that collects together the necessary ideas and formulas. Again, you will

be attending separate mathematics courses, but still it is handy for me to be able to rely on

saying, see equation xyz on page P, and know that you will have it at your fingertips;

• to provide a possible learning path for the mathematics of 2D and 3D graphics; at least to

provide a set of notes upon which I can base lectures;

• perhaps the main objective is to provide a basis from which students teach themselves more

advanced mathematics, i.e. to get them ready to read books and papers on computer

graphics, virtual reality games, and the mathematics that underlie these topics.

1.2 Understanding Mathematics

Many users of this document will start off with a fear and loathing of mathematics. On the

other hand it is hard to get through a page of a book on computer graphics or computer games

without coming across some equation or other. In addition, mathematics provides such a succinct,

expressive, and effective language for communicating many of the ideas behind graphics and games

that alternatives are almost unthinkable. What to do then?

0. For a start, attend lectures and work hard at your mathematics courses; if you turn up your

nose and decide that I’m no good at this, then that surely will remain true.

1. Realise that mathematics is only a language. Be patient and learn the basics. For sure, the

mathematical language that we use is a lot more straightforward than any programming language.

1–1

Page 7: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

2. Give yourself a chance. Try to figure out what that difficult looking equation means. Don’t

give up immediately; don’t give up until you have tried a number of times; and even then don’t

give up — ask questions in lectures or tutorials or in practical classes.

3. In most cases a mathematical equation has associated with it

• an (abstract) equation; okay maybe that is difficult to start with;

• some numerical examples — concrete examples; maybe easier to get to grips with; and after

you’ve see a few (concrete) examples maybe the (abstract) equation will become understand-

able;

• a picture; e.g. of the graph of a function, or the result of a transformation; like numerical

examples, these can bring equations to life;

• computer programs and algorithms; maybe you think better in these ‘languages’; but they

are just another way to express equations.

So, equations have real meanings — try to find your way of grasping that meaning.

4. Don’t despair. Find out, from lecturers and others, what is really needed and what you can

avoid.

1.3 Recommended Additional Reading

A lot of the mathematics in computer graphics books is sloppy and careless; the authors feel

the need to include mathematics, but the don’t have the space to introduce it properly. Notable

exceptions are (Foley, van Dam, Feiner, Hughes & Phillips 1994) and (Foley, van Dam, Feiner &

Hughes 1990).

The books I used when writing this are chiefly (in order of greatest use): (Schneider & Eberly 2003),

(Dunn & Parberry 2002), (Hoffmann 1975/1966), (Lengyel 2004), (Vince 2001) and (vanVerth

& Bishop 2004). I could recommend purchase of any of those. Schneider and Eberly (Schneider

& Eberly 2003) build a firm foundation, but I the size of the book may deter some readers; I like

(vanVerth & Bishop 2004) and I would have used more of it had it come to hand sooner; Dunn

and Parberry (Dunn & Parberry 2002) excels for its diagrams and computer code side-by-side

with mathematics. Vince (Vince 2001) is succinct and thereby easier to read by the impatient.

Later you will note many references to Lengyel (Lengyel 2004). (Buss 2003) is nice with plenty of

graphics applications (using OpenGL).

The Geometry behind all of what we are discussing is well covered in (Brannan, Esplen & Gray

1999); the Open University origins of that book show up well because of the nice diagrams; for

more geometry, see (Coxeter 1969/1989).

For a top class general introductions to linear algebra (matrices etc.), see (Lipschutz & Lipson

1999) and (Strang 2003); see also (Spiegel 1959).

For readers who want to go (a lot) further, see the references in (Campbell 2005), (Kline 1972),

(Crowe 1985/1967). Felix Klein’s two books, (Klein 2004/1925b) and (Klein 2004/1925a), were

published in German in 1925, but, to my mind, contain some excellent explanations and insights.

1–2

Page 8: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

1.4 Web and Other Resources

The Usenet newsgroup comp.graphics.algorithms contains a very

high level of discussion on graphics mathematics; access via

http://groups.google.com/group/comp.graphics.algorithms?lnk=lr. There

is a collection of web links containing everything including the kitchen sink at:

http://www.jgcampbell.com/links/mathgr.html.

1.5 Outline of the Document

Chapter 2 contains an elementary and introductory treatment of coordinate geometry and

trigonometry. Chapter 3 introduces vectors and vector algebra. Chapter 4 gives a very brief

treatment of matrices and linear algebra. Chapter 5 introduces vector transformations (2D in this

chapter) and their implementation by matrices; if you profiled an average virtual reality animation

or game program, you would see that a vast percentage of the time (either software or on the

graphics hardware or both) is spent on matrix implementation of transformations; there is a section

on complex numbers at the end of chapter5. Chapter 6 extends linear transformations to affine

transformations and shows how affine transformations can be made implementable by matrix mul-

tiplication — important for their implementation in graphics hardware, and also important to allow

the neat mathematics of linear transformations. Chapter 7 extends the work of chapters 5 and 6

to 3D. Chapter 8 gives a brief treatment of projective transformations and shows again how these

may be implemented by our (now) beloved matrix multiplication. Chapter 9 describes quaternions

and how they provide an effective and efficient implementation of 3D rotation that is used in most

graphics end game engines.

There are Appendices on Abstract Algebra (brief introduction of the terminology) and on software

implementations of (a) 2D vectors and 2D transformations (in Java); (b) 3D homogeneous vectors

and their transformations (in Java); (c) 3D homogeneous vectors and their transformations (in

C++).

1–3

Page 9: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Chapter 2

Coordinate Geometry and Trigonometry

2.1 Coordinate Geometry

Normally, but not always, we use a rectangular coordinate system like that in Figure 2.1. In two

dimensions (2D), coordinates are distances from the origin, O: horizontal distance, x , and vertical

distance, y . The term Cartesian comes from the French mathematician and philosopher Rene

Descartes (1596-1650) who is widely accepted as having introduced the rectangular coordinate way

of looking at geometric problems. Thus, he originated analytic geometry which allows geometric

problems to be solved using algebraic methods; this was good news for people who thought that

geometry depended too much on diagrams an intuition.

Figure 2.1: Rectangular (Cartesian) coordinate system.

2–1

Page 10: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

When we move to considering three dimensions (3D), we’ll need to add a third coordinate, z . If

you wanted to put a z-axis on Figure 2.1, it would start at O and point out at you, perpendicular

to the page. In general, three dimensions, (x, y , z) are needed to specify the position of a point in

space.

Aside: Non-rectangular coordinate systems The Irish National Grid as used in Ordnance Survey

maps is rectangular, and two-dimensional. On the other hand, latitude and longitude are not

rectangular coordinates, but spherical. The coordinates are angles: latitude, angle North or South,

with zero at the equator; longitude, angle East or West, with zero at the Greenwich meridian.

Exercise. If we normally need three coordinates to specify a point in space, how can we get away

with two in the case of latitude and longitude?. Hints: (a) radius; (b) even though the Earth is

not flat (I think that’s correct?), on the surface of it we occupy a sort of 2D space.

You will come across spherical / angular coordinates often in virtual reality computer games. For

example, when panning a camera (rotating it horizontally), we talk of azimuth angle; and when

tilting it vertically, we talk of elevation angle.

Back to 2D. In Figure 2.1 we give the ‘address’ of a point as (x, y); (5, 3), x = 5, y = 3 is one

such point. X-coordinates to the left of the origin are negative; y-coordinates below the origin are

negative. Note points (−1,−2) and 3,−1.5) in the diagram.

Exercise. What are the coordinates of point P in Figure 2.1? Be careful not to mix up x , always

first, and y , always second. And please note that when we talk about rows and columns of images,

(r, c) it is the other way round; and similarly for matrices which we come to later.

Exercise. Draw Q (8, 2) on Figure 2.1.

Distances When points lie on the same horizontal line, as P and S in Figure 2.2 or on the same

vertical line, as P and T in Figure 2.2, computing the distance between them is easy; in the case

of PT you simply take dy = y3 − y1, and in the case of PS, the distance is dx = x3 − x1.

In general, however, to get the as the crow flies distance, you must combine the x and y displace-

ments. PQR is a right-angled triangle, so we can apply Pythagoras’s Theorem: the square on the

hypotenuse is equal to the sum of the squares on the other two sides. The hypotenuse is the side

opposite the right-angle, i.e. PQ. So, we have

PQ2 = PR2 +QR2, or, (2.1)

d2 = d2x + d2y , so that, (2.2)

d =√d2x + d2y . (2.3)

Gradient or Slope Another thing we might want is the gradient (or slope) of the line PQ. This

is measured as,

gpq = dy/dx = (y2 − y1)/(x2 − x1). (2.4)

The gradient of PR is (y1 − y1)/(x2 − x1) = 0/(x2 − x1) = 0 and the gradient of PT is (y3 −y1)/(x1 − x1) = (y3 − y1)/0 =∞ — so don’t try the latter on your calculator!

2–2

Page 11: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Figure 2.2: Distances in the Cartesian coordinate system.

Figure 2.3: Cartesian coordinate system.

2–3

Page 12: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Exercise. Examine Figure 2.3 and answer the questions below.

(a) Compute the distance between P and Q.

(b) Compute the distance between P and R.

(c) Compute the distance between P and S.

(d) Compute the distance between P and T (d1). This is the length of the diagonal in a square

whose sides are length 1; you should become familiar with this number d1 = ˙˙˙˙˙˙˙; also its

reciprocal 1/d1 = ˙˙˙˙˙˙˙˙˙˙.

(e) (i) Compute the distance between Q and P. (ii) What in general can we say about distances

AB and BA?

(f) What are the gradients of (i) PR, (ii) PQ (don’t use a calculator!), (iii) PS, (iv) PT ?

(g) What are the gradient of (i) RP , (ii) QP (again, don’t use a calculator!), (iii) SP , (iv) TP ?

(h) If you are going up, gradient is ˙˙˙ive; if you are going down, gradient is ˙˙˙ive; if you are

going along a horizontal line, the gradient is ˙˙˙.

(j) U is at (x = −1, y = −2); mark it on the diagram. Now, (i) compute the distance UP ; (ii)

compute the distance PU; (iii) distances are always ≥ ˙˙˙ ?.

(k) What is the gradient (slope) of UP? (j) What is the gradient of PU?

Games context In a 2D game, we often need to know if two objects have come close together

— for example, a character may collect a power up by touching a power up object; or the character

may become damaged by getting close to an enemy. A very crude way to do this, i.e. compute

proximity, or collision detection, is to compare the coordinates of the character (xc , yc) with the

coordinates of the enemy (xe, ye). In Java or C++:

if(xe == xc && ye == yc) do something;

else do nothing and carry on;

This is crude and may cause the game to appear unreal because object have to be right on top

of one another for contact to be registered; what we want is proximity, i.e. compute the distance

between the two objects and if it is less than some small distance, we have contact. In Java:

smallDistance = 1.25; // for example

dx = xe - xc; dy = ye - yc;

dxSquared = dx*dx; dySquared = dy*dy;

dSquared = dxSquared + dySquared;

d = Math.sqrt(dSquared);

if(d ¡ smallDistance) do something;

else do nothing and carry on;

Another method is bounding box ; here each object is considered to have a box surrounding it and

there is contact if the boxes touch or overlap.

2–4

Page 13: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

2.2 Trigonometry

When there is a right angle (90◦ or π/2 radians) in a triangle, the ratios of lengths of sides are

known and can be printed in books of tables and programmed into calculators. See Figure 2.4.

Figure 2.4: Trigonometry: sine, cosine and tangent.

The ratios are sine, cosine, and tangent, abbreviated, respectively: sin (spoken ‘sign’), cos, and

tan.

Thus, if you know the angle a and the length of PQ, the hypotenuse, you can compute RQ using

PR/PQ = sin a, so PR = PQ sin a.

Example. a = 30◦, PQ = 5, what is PR? A calculator or book of tables tells me that sin a = 0.5.

So, PR = PQ sin a = 5× 0.5 = 2.5. And what is RQ? Use cos. RQ/PQ = cos a; cos a = 0.866,

so RQ = PQ cos a = 5× 0.866 = 4.33.

2.2.1 Sin, cos, coordinates and circles

sin, cos, tan are often called circular functions as shown in Figure 2.5. If we have a point P on a

circle of unit radius (radius r = 1) and we rotate P anticlockwise from the x-axis by an angle a,

the x- and y-coordinates of P are cos a and sin a, respectively. This fact will crop up again and

again; if you don’t know much about sin, cos, tan, that diagram is a good way of figuring out the

relationships — much better than learning off formulas.

Note. All the important diagrams and formulas in this chapter will be given in an appendix of any

examination paper you do.

cos is cosine, meaning that it covaries with sine — as sine increases, so cosine decreases and

vice-versa.

From Figure 2.5 we can see from Pythagoras’s Theorem that

sin2 a + cos2 a = 1. (2.5)

2.2.2 Sine and cosine functions

Figure 2.6 shows graphs of cosine and sine for the angle range −π to 2π. angles.

2–5

Page 14: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Figure 2.5: Sin and cos and circlular movement.

Figure 2.6: Graphs of cos (left) and sin (right); angles from -PI to + 2*PI.

2–6

Page 15: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Some values. sin 0◦ = 0, sin 30◦ = 0.5, sin 60◦ =√

3/2 = 0.866, sin 90◦ = 1.

cos 0◦ = 1, cos 30◦ =√

3/2 = 0.866, cos 60◦ = 0.5, cos 90◦ = 0.

So, you can see that sine and cosine have the same shape, but sin a is 90◦ behind cos a as a

increases: cos a − 90◦ = sin a. You can verify this using Figure 2.5.

Radians Before we go on, we have to mention that many applications measure angles in radians;

a radian is about 57◦; it is the angle subtended by an arc of length r on a circle of radius r . Very

often you will see π/2 radians = 90◦, π radians = 180◦, 2π radians = 360◦, etc.

π = 3.141592635 . . ..

To convert degrees, d , to radians, r : r = (180/π)× d .

Cosine and sine are periodic over 360 degrees Cosine and sine repeat themselves after 2π

radians or 360◦.

Sine is odd, cosine is even Sine is an odd function: sin−a = − sin a.

Cosine is an even function: cos−a = cos a.

Armed with the latter two facts (periodic and odd / even), given cos a and sin a for a = 0 . . . π,

you can derive the cos a and sin a for any angle a.

2.2.3 Inverse sin, cos, tan

Sometimes we know that the cos of the angle is c , and we need to compute the angle? The inverse

function cos−1 gives the answer. We have also sin−1, and tan−1; like sin, cos, tan these are in books

of tables and in calculators. Other names for these inverse functions are arccos, arcsin, arctan. In

programming language mathematics libraries they have names like acos, asin, etc.

Useful equations

sin(a + b) = sin a cos b + cos a sin b, (2.6)

sin(a − b) = sin a cos b − cos a sin b, (2.7)

cos(a + b) = cos a cos b − sin a sin b, (2.8)

cos(a − b) = cos a cos b + sin a sin b. (2.9)

sin2 a + cos2 a = 1. (2.10)

sin2 a =1

2(1− cos 2a). (2.11)

2–7

Page 16: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

cos2 a =1

2(1 + cos 2a). (2.12)

cos 2a = cos2 a − sin2 a = 1− sin2 a = 2 cos2 a − 1. (2.13)

2–8

Page 17: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Chapter 3

Vectors

3.1 Introduction

Roughly speaking, vectors are objects with magnitude and direction. Figure 3.1 shows vectors u, v

and other vectors derived from them. Vectors are normally shown in bold-face, e.g. u, though

other symbolisms are used, for example, underscoring, or over-scoring with arrows.

Books often emphasise vectors as being made up from a set of components, i.e. where vectors

are referenced to a set basis vectors, normally orthogonal to one another, see section 3.3. The

components give the contribution (weight) of each of the basis vectors. Actually, however, vectors

exist without any basis being specified; on the other hand, when we get to computer programs,

we do need to resort to numerical components. It is not uncommon to see the components (with

respect to a basis) referred to as coordinates; but it is best to resist that temptation, for then we

may confuse vector and point; normally it is best to make a very clear distinction between vectors

(representing movement or displacement of points) and points themselves (representing location),

see chapter 6.

Vectors do not have locations, the three versions of u are the same vector; likewise the two versions

of v.

Often components (with respect to a basis) are called coordinates but, in spite of this name, note

again that a vector has no location.

In order to distinguish vectors from real numbers (which have magnitude and sign, but no direction),

in the vector context a real number is called scalar.

3.2 Vector Algebra

The basic operations on vectors are:

(a) Addition. In Figure 3.1 this is done using either (i) the head-to-tail triangle rule or (ii) the

parallelogram rule; they are equivalent and give the same result. There is a zero vector 0 for

which u + 0 = u.

3–1

Page 18: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Figure 3.1: Vectors in two dimensions.

(b) Multiplication by a scalar, (scaling the vector). For example, in Figure 3.1 see the effect of

multiplying vector u by 1.5; the direction stays the same, magnitude is multiplied by 1.5.

This is vector algebra in a nutshell; for a more formal and complete account see section 3.6 or

(Schneider & Eberly 2003) or any of the textbooks mentioned in Chapter 1.

3.3 Vector Basis

3.3.1 Components and vector basis

As we have said, in a computer program we must represent vectors using numeric components

measured according to a basis (plural bases). A basis is a set of linearly independent vectors from

which any general vector may be expressed as a linear combination of members of the basis.

The vectors in Figure 3.1 are now shown in Figure 3.2 along with one possible basis, the vectors

e1 and e2. e1 and e2 are perpendicular (orthogonal) to one another and they are unit vectors.

That makes e1, e2 an orthonormal basis — orthogonal and normalised, where normalised means

reduced to unit length, see section 3.4.1.

It is possible to have a valid basis whose vectors are neither orthogonal nor unit length — they only

have to be linearly independent, see section 3.3.3 — but orthonormal bases bring great advantages.

Note that I have deliberately excluded axes (x- or y-axes or otherwise) from Figure 3.2; axes such

as x- and y-axes in section 2.1 are used to determine location; let us repeat: vectors, unlike

points, do not have a location. We have shown one version of e1, e2 making what looks like x-

and y- axes — that is only for handiness; note the other e1, e2 which are quite equivalent. Also,

3–2

Page 19: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Figure 3.2: Vector Basis.

note that the grid lines in Figure 3.2 are there only to show vector magnitudes and to give some

guide as to vector directions.

We can now express vectors using their components:

u = (u1 u2) = (5 1); this states that u is composed of five units of e1 (the five added together,

resulting in 5e1) and one unit of e2, i.e. u = 5e1 + 1e2.

v = (v1 v2) = (1 4), which means v = 1e1 + 4e2.

It is more correct to write u(u1 u2)t , which means that the vector is transposed ; in matrix

terminology, see section 4.2, (u1 u2) is a row vector or a 1× 2 vector, one row by two columns;

transposing makes it a column vector — a 2 × 1 vector. Unless otherwise stated, a vector on n

components is n × 1. But, often where the meaning is clear, we write u as (u1 u2) or (u1 , u2).

It is useful to stick to the neutral e1, e2, rather than mention x and y . However, more often than

not e1 will be aligned with the x-axis and e2 will be aligned with the y-axis; quite often we will end

up using u = (ux uy)t and v = (vx vy)t . Obviously, in 3D, this extends to u = (u1 u2 u3)t =

(ux uy uz)t . In many textbooks, you will see i, j, k replacing e1, e2, e3.

Components, coordinates u1, u2 etc. are components of u with respect to the basis e1, e2. As

mentioned earlier, the term coordinate is sometimes used instead of component, but this is best

avoided if we want to be sure that we are talking about vectors (no location) rather than points

(location).

3–3

Page 20: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

3.3.2 Vector algebra using components

We can now do our basic vector operations by working on the individual components — as we

would have to do in a computer program:

(a) Add two vectors; u + v = (u1 + v1, uy + vy) = (5 + 1, 1 + 4) = (6, 5), which can be verified

by examining Figure 3.2;

(b) Multiply by a scalar; multiply each component by the scalar; example in Figure 3.2, −1u =

−u = (−5,−1);

(c) Zero vector, 0 = (0, 0).

3.3.3 Linear Independence

A set of n vectors V = {u1,u2, · · · ,un} is linearly dependent if any of the ui can be expressed as a

linear combination of the remaining vectors; that is, considering V = {u1,u2, · · · ,up} as a basis,

linearly dependence means that we have at least one redundant vector.

Formally, V = {u1,u2, · · · ,un} is linearly independent if

c1u1 + c2u2 + · · ·+ cnun = 0 (3.1)

if and only if c1 = 0, c2 = 0, · · · , cn = 0.

If the basis is linearly independent, then the representation of a vector using components (with

respect to the basis) is unique.

3.4 Scalar (dot) product

We’ve managed to add and (using × scalar −1) subtract vectors and multiply them by a scalar.

What about multiplying two vectors. Well sort of, as shown below. And we’ll cover another sort

of vector product in the next section. We say sort of because with multiplication normally comes

division, the inverse of multiplication. Neither of the two main vector products define an inverse

— there is no division.

Here we introduce scalar (or dot) product; you might see scalar product also called inner prod-

uct, but, take care, inner product is a more general term and you may come across other in-

ner products. Incidentally, if you ever want to explore the topic of vector products further, see

(Hoffmann 1975/1966), and (Crowe 1985/1967) for a history of vector analysis — which in fact

started with quaternions, see (Campbell 2005) and the references contained therein.

The scalar product is defined as

u · v = ‖u‖‖v‖ cos θ, (3.2)

where ‖ ‖ denotes magnitude and θ is the angle between u and v.

Eqn 3.2 immediately presents us with two significant problems, we know neither how to measure:

(a) angles (apart maybe from 0, 180◦, and possibly 90◦), nor (b) magnitudes. But all is not lost,

be patient.

3–4

Page 21: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

We’re going to state some properties of scalar product and vector addition; for proofs and discus-

sion, see (Schneider & Eberly 2003), pp. 90–91.

(i) Positive definiteness. u · u ≥ 0;

(ii) Commutativity of the scalar product. u · v = v · u;

(iii) Distributivity of the scalar product over vector addition. u · (v + w) = (u · v) + (u ·w);

(iv) Distributivity of vector addition over the scalar product. (u + v) ·w = u ·w + v ·w.

Now, substitute u = u1e1 + u2e2 and v = v1e1 + v2e2 in the left hand side of eqn. 3.2

u · v = (u1e1 + u2e2) · (v1e1 + v2e2). (3.3)

Employing the two distributivity properties,

u · v = (u1e1 + u2e2) · (v1e1 + v2e2) (3.4)

= u1v1e1 · e1 + u1v2e1 · e2 + u2v1e2 · e1 + u2v2e2 · e2.

We know that the angle between e1 and e2 is 90◦ and that the angles between e1 and e1 and e2and e2 is 0 and that cos 90◦ = 0 and cos 0◦ = 1; somewhere, we also defined e1 and e2 to be unit

magnitude vectors.

Thus, e1 · e1 = 1, e2 · e2 = 1, (because cos 90◦ = 1 and e2 and e2 are unit length); also e1 · e2 = 0

and e2 · e1 = 0 (because cos 0 = 0).

Hence,

u · v = 1u1v1 + 0u1v2 + 0u2v1 + 1u2v2 = u1v1 + u2v2. (3.5)

so that, for vectors defined in terms of their components in an orthogonal basis of unit vectors

u · v = u1v1 + u2v2. (3.6)

Using an orthogonal basis of unit vectors (an orthonormal basis), we now have a method of

computing magnitude (length) and angle between vectors.

The scalar product is defined for any dimension, 2D, 3D, and indeed n-dimensional space, but we’ll

only use it in 2D and 3D.

The following subsections cover topics which are strongly related to scalar product.

3.4.1 Vector length / magnitude

In the context of vectors magnitude and length are equivalent terms.

Since the angle between a vector and itself is zero,

u · u = ‖u‖‖u‖ = ‖u‖2, (3.7)

3–5

Page 22: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

so

‖u‖ =√

u · u, (3.8)

and u · u = u21 + u22 from eqn 3.6.

If we think of a vector as a displacement, eqn. 3.8 should be no surprise; recall distances in

section 2.1, and Pythagoras’s theorem, where, please note, the coordinate system is Cartesian, i.e.

the x- and y-axes are orthogonal and unit lengths along the axes are equal. We reemphasise that

‖u‖ =

√u21 + u22 , (3.9)

holds only for components with respect to an orthonormal basis. However, eqn 3.9 is so neat that

the orthonormal bases are almost universally used.

3.4.2 Direction, unit vector

Often we want just the direction of a vector; one way to achieve this is to normalise the vector to

unit length:

u = u/|u|. (3.10)

u has length 1.

Exercise. (a) u = (u1, u2) = (3, 4), what is the length |u|; (b) compute u = u/|u|; (c) verify that

|u| = 1, i.e. that it is properly normalised and is a unit vector; (d) draw u and use that to verify

your answer. Note, these are easy numbers, no need for a calculator.

Exercise. (a) u = (u1, u2) = (1.732, 1), what is the length |u|; (b) compute u = u/|u|; (c) verify

that |u| = 1, i.e. that it is properly normalised and is a unit vector; (d) draw u and use that to

verify your answer. Note: 1.732 =√

3 = 2 cos 30◦, 1 = 2 sin 30◦.

3.4.3 Angle between two vectors

Eqn. 3.6 allows us to compute u · v without knowing cos θ. Then we use eqn. 3.2 to obtain

cos θ = u · v/‖u‖‖v‖, (3.11)

and

θ = cos−1(u · v/‖u‖‖v‖). (3.12)

3.4.4 Tests for Orthogonality and Parallelism

Orthogonality If for any two vectors u and v, u · v = 0 and ‖u‖ 6= 0, and ‖v‖ 6= 0, then u is

orthogonal to v — they are perpendicular to one another, i.e. cos θ = 0 in eqn. 3.11, so

θ = 90◦.

Parallelism If u · v = ‖u‖‖v‖ then cos θ = 1 in eqn. 3.11, so θ = 0.

3–6

Page 23: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

3.4.5 Direction Cosines

The components of a unit vector are its direction cosines, i.e. the cosines of the angles it makes

with the e1 and e2, respectively. This fact is shown in Figure 3.3, where u is a unit vector. Since

e1 and e2 are orthogonal; angle b = 90◦ − a; thus cos b = cos(90◦ − a) = sin a.

Alternatively, if u is not a unit vector, but has length r , then the components are multiplied by r :

r cos a, r sin a.

Note again that I’ve tried to show that Figure 3.3 has no coordinate axes. e1 and e2 are vectors;

where they meet is not an origin — remember, vectors do not have locations, except when people

draw diagrammatic representations of them!

This direction cosines insight will be a big help when we come to 2D and 3D transformations.

Figure 3.3: Direction cosines.

Figure 3.4 allows us to do some exercises with scalar products. For ease of working and to stress

a point about the projection role of scalar product, all the vectors in Figure 3.4 are unit vectors.

Exercise. Verify that u = (0.866 , 0.5), v = (0.5 , 0.866),p = (0 , 1),q = (0 , 1), t =

(0.866 ,−0.5) are all unit vectors, i.e. they have length 1.

Exercise. Verify that the components of u = (0.866 , 0.5), v = (0.5 , 0.866),p = (0 , 1),q =

(0 , 1), t = (0.866 ,−0.5) are indeed their direction cosines.

Exercise. Using eqn 3.6, compute: (a) u · v = (u1v1 + u2v2); (b) v · u = (v1u1 + v2u2); (c) using

the result of (b), what can you conclude about the relationship between u · v and v · u.

Exercise. Using eqn 3.6, compute: (a) u · q = (u1q1+ u2q2); (b) v · q; (c) v · p; (d) u · p; (e) v · t;

(f) p · q.

In this last exercise we are seeing that u · q is the projection of u onto e1.

In general, the scalar product of a vector u with a vector q gives the projection of u onto q.

3–7

Page 24: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Figure 3.4: Dot products.

Exercise. Projections can be onto vectors other than axes vectors. (a) What is the projection of

u onto v? Use eqn 3.6; note the dotted line in Figure 3.4 showing the projections. (b) What is

the projection of v onto u?

Exercise. (i) Using your knowledge of sin and cos, compute the angles a, b, c , e, f , g. (ii) What

is odd about f ? A. It is negative. (iii) Why is f negative? A. Remember anticlockwise is positive,

clockwise negative; (iv) b is also negative — the angle from y-axis to v.

Ans. a = 30◦; b = 30◦, −30◦, if we take sign into account; c = 30◦; e = 90◦; f = 30◦, −30◦, if

we take sign into account; g = 60◦.

Exercise. Using eqn 3.2 and the results of the previous exercise, compute: (a) u·v = ‖u‖‖v‖ cos c ;

(b) v · u; (c) using the result of (b), what can you again conclude about the relationship between

u · v and v · u.

Exercise. Using eqn 3.2, compute: (a) u · q; (b) v · q; (c) v · p; (d) u · p; (e) v · t; (f) p · q.

3.4.6 Scalar product and projection

As we have seen, the scalar product of any vector u with a unit vector q gives the projection of u

onto q. In the case of u · q, we have u projected onto the e1. q = (1 , 0) = 1.e1 + 0.e2 = e1.

Although projection seems a bit trivial here, projections are fundamental to 3D graphics: we

must project 3D vectors onto some 2D plane (so that we can display on a 2D screen); often we

project u = (ux , uy , uz) onto the x-y plane; if the projection is orthographic, we just throw away

the z-component, (ux , uy , uz) 7→ (ux , uy). If the projection is perspective, we modify the x- and

y-components according to their z value: (ux , uy , uz) 7→ (u′x , u′y).

3–8

Page 25: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

3.5 Vector (cross) Product

Here we introduce the vector product, sometimes called cross product (cross simply because the

symbol× is used to denote it. Unlike the scalar product, section 3.4, the result of the vector product

is a vector. Also unlike the scalar product, the vector product is defined only in three dimensional

vector space. We’ll cover vector product briefly and refer interested readers to (Schneider &

Eberly 2003) pp. 92–93.

The vector product w = u× v has a direction perpendicular to both u and v and has magnitude

‖u‖‖v‖ sin θ, where θ is the angle between u and v.

As shown in Figure 3.5, the sign of the vector product depends on the sign of sin θ; Figure 3.5

shows the normal right-handed convention.

Figure 3.5: Vector product.

Figure 3.6 shows another interpretation of the vector product — as the area of the parallelogram

formed by u and v and with the direction as stated above.

Figure 3.6: Vector product.

3.6 Vector Space

When speaking of mathematical objects and operations involving them, mathematicians often use

the term space; this almost nothing to do with the space that we, and the moon and the stars,

occupy, except that we could call the latter a space of points.

We sometime speak of the space of real numbers, which is composed of (a) all the real numbers

and (b) the operations we can do on and with them to produce other real numbers.

A vector space is made up of:

3–9

Page 26: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

(a) Vectors. The set of all vectors possible in that space; we might for example restrict to 2D

or 3D vectors;

(b) Vector addition. If you add two vectors, you get another vector. Addition is associative and

commutative.

(i) Addition is associative, i.e. if u, v,w are vectors, (u + v) + w = u + (v + w).

(ii) Addition is commutative. u + v = v + u.

(c) Zero vector. There is a zero vector 0; u + 0 = 0 + u = u;

(d) Inverse of vector addition (subtraction). For every vector u we have a vector u′ so that

u + u′ = u′ + u = 0; obviously u′ = −u;

Items (a) . . . (d) make the vectors an Abelian group, see Appendix A.

(e) A set of scalars — the real numbers, e.g. a.

(f) Multiplication of vectors by scalars, for any vector u, au is a vector;

(i) Multiplication by a scalar is distributive over vector addition: a(u + v) = au + av;

(ii) Multiplication by a scalar is distributive over scalar addition: (a + b)u = au + bu;

(iii) Multiplication of a vector by a scalar is associative with scalar-scalar multiplication:

a(bu) = (ab)u.

3–10

Page 27: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Chapter 4

Matrices and Linear Algebra

A good deal of virtual reality graphics involves moving objects round the virtual reality world,

resizing them, rotating them, etc. Most of these operations involve sets of simultaneous equations

like eqns. 4.1 and 4.2. The algebra used in manipulating and solving such equations is called

linear algebra. Matrix algebra is central to linear algebra. The application of matrices to graphics

and games does not become properly apparent until Chapter 5 and section 5.6.3 which derives the

transformation matrix for rotation.

Hence we must cover some linear algebra, including matrix algebra. That’s what this chapter

does — introduces matrices. Chapter 3 has introduced vector algebra. Chapter 5 describes the

application of matrix algebra to vector transformations (rotation, etc.). Finally chapter 6 on

affine transformations pulls everything together and gives us the full mathematical apparatus for

manipulating objects in 2D and 3D space.

4.1 Linear Simultaneous Equations

Eqns. 4.1 and 4.2 are a pair of linear simultaneous equations,

v1 = 3u1 + 1u2, (4.1)

v2 = 2u1 + 4u2. (4.2)

Practically, these equations could express the following:

Price of an apple = u1, price of an orange = u2 (both unknown). Person A buys 3 apples, and 1

orange and the total bill is 5c (v1). Person B buys 2 apples and 4 oranges and the total bill is 10c

(v2).

Now, what is u1, the price of apples, and u2, the price of oranges? We want to solve for the

unknowns u1, u2. Matrix algebra gives us a nice technique for solving such problems, see section 4.5,

but first well see how to solve it without matrices.

Substitute v1 = 5 and v2 = 10 into eqns. 4.1 and 4.2:

5 = 3u1 + 1u2, (4.3)

10 = 2u1 + 4u2. (4.4)

4–1

Page 28: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Eqn. 4.3 gives u2 = 5− 3u1, which, substituted into eqn. 4.4 gives:

10 = 2u1 + 4(5− 3u1),

10 = 2u1 + 20− 12u1,

−10 = −10u1,

u1 = 1.

Now, substitute u1 = 1 into eqn. 4.3:

5 = 3 + u2,

u2 = 2.

We have determined our unknowns u1 = 1 and u2 = 2.

Ex. Substitute u1 = 1 and u2 = 2 into eqns. 4.3 and 4.4 to check the correctness of the result.

4.2 Matrices

Eqns. 4.1 and 4.2 can be written in matrix form as

v = Au (4.5)

where A is a 2 row × 2 column matrix, A =

[3 1

2 4

], v is a one column two row matrix,

representing a tuple, v =

[v1v2

]and u is another one column two row matrix, u =

[u1u2

].

Here we are being careful to call objects like u and v tuples. We are tempted to use the term

vector for tuple, but, strictly, that would be incorrect. Vectors can be represented using tuples of

components, see section 3.3, that is the connection. But all tuples are not vectors. Generally a

tuple containing n elements is called n-tuple; 2-tuple = pair, 3-tuple = triple, etc.

Generally, a system of m equations, in n variables, u1, u2, . . . , un,

v1 = a11u1 + a12u2 · · ·+ a1nun (4.6)

v2 = a21u1 + a22u2 · · ·+ a2nun

. . .

vr = ar1u1 + ar2u2 · · ·+ arnun

. . .

vm = am1u1 + am2u2 · · ·+ amnun

can be written in matrix form as

v = Au, (4.7)

4–2

Page 29: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

where v is an m-tuple or m × 1 matrix,

v =

v1v2.

.

vm

,u is an n-tuple or n × 1 matrix,

u =

u1u2.

.

un

,and A is an m-row × n-column matrix

A =

a11 a12 a1na21 a22 a2n.. .. .. ..

.. arc .. ..

.. .. .. ..

am1 am2 .. amn

.

That is, the matrix A is a rectangular array of numbers whose element in row r , column c is arc .

The matrix A is said to be m × n, i.e. m rows, n columns.

Eqn. 4.7 can be interpreted as the definition of a function which takes n arguments (u1, u2, . . . , un)

and returns m variables (v1, v2 . . . vm). Such a function is also called a transformation: it transforms

n-tuples of real numbers to m-tuples of real numbers.

Such equations are linear transformations because there are no terms in u2r or higher, only in

ur = u1r , and no numbers like 5 (5u0r = 5× 1 = 5).

4.3 Basic Matrix Arithmetic

4.3.1 Matrix Multiplication

We may multiply two matrices A, m × n, and B, q × p, as long as n = q. Such a multiplication

produces an m × p result. Thus,

C = A B.

m × p m × n n × p (4.8)

Method: The element at the r th row and cth column of C is the product (sum of componentwise

products) of the r th row of A with the cth column of B. There are similarities between these sum

of componentwise products and the vector componentwise scalar product of eqn. 3.6. Pictorially:

4–3

Page 30: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

n p p

---------------- ---------- -----------

—----¿ — — — — — —

— A — — B — — = — C —

— — — — — — —

m — — — — — n — — m

---------------- — V — -----------

— —

----------

C = AB

,

A =

[a11 a12a21 a22

],

B =

[b11 b12b21 b22

],

so, the product

C =

[a11b11 + a12b21 a11b12 + a12b22a21b11 + a22b21 a21b12 + a22b22

].

Example. Consider Eqn. 4.7, v = Au. Thus the product of A(m × n) and u(n × 1) is

v1 = a11u1 + a12u2 · · ·+ a1nun, · · · vm = am1u1 + am2u2 · · ·+ amnun.

In summation notation, vr =∑c=n

c=1 arcuc .

The product is (m × n)× (n × 1) so the result is (m × 1), which checks okay, for v is (m × 1).

4.3.2 Multiplication by a Scalar

As with vectors (when represented as components), we simply multiply each component by the

scalar,

c

[a11 a12a21 a22

]=

[ca11 ca12ca21 ca22

].

4.3.3 Addition

As with vectors (when represented as components), we add componentwise,

[a11 a12a21 a22

]+

[b11 b12b21 b22

]=

[a11 + b11 a12 + b12a21 + b21 a22 + b22

].

Clearly, the matrices must be the same size, i.e. row and column dimensions must be equal.

4–4

Page 31: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

4.4 Special Matrices

4.4.1 Identity Matrix

I =

[1 0

0 1

]i.e. produces no transformation effect. Thus, IA = A

We can define the matrix inverse as follows, if AB = I then B = A−1, see section 4.5.

4.4.2 Orthogonal Matrix

A matrix which satisfies the property:

AAt = I

i.e. the transpose of the matrix is its inverse, see section 4.5.

Another way of viewing orthogonality in matrices is:

For each row of the matrix (ar1ar2....arn), the scalar product with itself is 1, and with all other

rows, 0. I.e. ∑nc=1 arcapc = 1 for r = p,

= 0 otherwise.

4.4.3 Diagonal

Later, in section 5.6.2, we will come across a scaling matrix, so called because it scales the individual

components of a column tuple (which will be used to represent vector components) multiplied by

it.

A =

[Sx 0

0 Sy

]is diagonal, i.e. the only non-zero elements are on the diagonal.

The inverse of a diagonal matrix [a11 0

0 a22

]is [

1/a11 0

0 1/a22

]

4–5

Page 32: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

4.4.4 Transpose of a Matrix

At, spoken ‘A-transpose’.

If

A =

[a11 a12a21 a22

]then

At =

[a11 a21a12 a22

]i.e. replace column 1 with row 1 etc.

The transpose is sometimes AT or A′.

4.5 Inverse Matrix

Only for square matrices (m = n). Consider again Eqns. 4.1 and 4.2:

v1 = 3u1 + 1u2

v2 = 2u1 + 4u2

i.e. v = Au.

A =

[3 1

2 4

].

Apply this to

x =

[1

2

],

to get

v1 = 3.1 + 1.2 = 5,

v2 = 2.1 + 4.2 = 10.

What if you know v = (5 10)t and you want to retrieve u = (u1 u2)t? In other words, can

matrices help us solve for u1, u2 as we did in section 4.1?

The answer is yes. Find the inverse of A = A−1 and then apply the inverse transformation to v,

that is, multiply v by the inverse of the matrix,

u = A−1v. (4.9)

4–6

Page 33: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

In the case of a 2 × 2 matrix

A =

[a11 a12a21 a22

]

A−1 =1

| A |

[a22 −a12−a21 a11

](4.10)

where the determinant of the array, A, is | A |= a11a22 − a12a21

If | A |= 0, then A is not invertible, it is singular.

Inverse matrices give us the equivalent of division. If | A |= 0, attempting to find the inverse is

the equivalent to calculating 1/0.

Thus for

A =

[3 1

2 4

]we have | A |= 3× 4− 2× 1 = 10 so

A−1 = (1/10)

[4 −1

−2 3

]=

[0.4 −0.1

−0.2 0.3

]

Therefore, apply A−1 to

[5

10

]We find: A−1y =

[0.4 −0.1

−0.2 0.3

].

[5

10

]=

[5× 0.4 + 10×−0.1

5×−0.2 + 10× 0.3

]=

[1

2

]which is the answer we got in section 4.1. In fact, in section 4.1 what we did was something very

similar to how one inverts a matrix in a computer program.

4–7

Page 34: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

4.6 Octave Matrix Calculator

Octave (a free version of Matlab) is handy for doing lengthy matrix mathematics. Octave is

available in room 2213 machines; if you want it for your own machine, Google ¡GNU Octave¿. Or,

install Cygwin.

Here is an interactive Octave session corresponding to some of the mathematics in the previous

section.

octave:1¿ A = [3, 1; 2, 4]

A =

3 1

2 4

octave:2¿ B = inv(A)

B =

0.400000 -0.100000

-0.200000 0.300000

octave:6¿ v= [5;10]

v =

5

10

octave:7¿ B*v

ans =

1.0000

2.0000

Much easier than using a calculator! If you want Octave for your personal machine search for

it using Google. Octave is a free version of Matlab; if you have Matlab, fine; but Matlab costs

gazillions per annum for a licence.

4–8

Page 35: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Chapter 5

Vector Transformations

5.1 Introduction

In chapter 3 we have discussed adding vectors and multiplying them by scalars. We are now going

to extend the range of operations, though all the time noting that the new operations are composed

of addition of vectors and scalar multiplication of vectors — after all that is all we can legally do

with vectors.

Before you go further, make sure you are familiar with at least the basics of matrices, see sec-

tion 4.2. Transformation of a vector all about making a new vector by altering the values of

the components that made up the old vector. Hence the relevance of simultaneous equations in

section 4.1.

Most of this chapter is taken from (Schneider & Eberly 2003) and (Dunn & Parberry 2002), with

a little from (Strang 2003). See also (Vince 2001) for a nice succinct coverage, (Lengyel 2004)

and either of the Foley-vanDam books: (Foley et al. 1994) or (Foley et al. 1990).

5.2 Linear Transformations

A vector transformation, T (u), is a function or map which maps a vector, u, (belonging to one

vector space — see section 3.6) to another vector,v, (belonging to the same vector space, or to

a different one),

T (u) 7→ v, (5.1)

where we use the 7→ deliberately to show that T takes u and makes v out of it — transforms u to

v. In the language of computer programming, T is a function, u is the input, and v is the output.

In computer graphics, normally, but not always, the vector spaces involved are normally the space

of 2D or 3D displacement vectors. The input and output vector spaces need not be the same.

If the vector spaces are U and V , we say T : U 7→ V . If we carry the analogy with computer

program functions further, we are saying that T is a function whose type is V T(U), just like the

signature/type int f1(double);.

Any linear transformation, T , preserves the two operations that involve vectors, namely vector

addition and scalar-vector multiplication (section 3.6):

5–1

Page 36: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

(i)

T (u + v) = T (u) + T (v); (5.2)

(ii)

T (au) = aT (u); (5.3)

(iii) Consequently, combining (i) and (ii), we see that T preserves linear combinations of vectors,

T (au + bv) = aT (u) + bT (v). (5.4)

We can further see that composition of linear transformations, R = S◦T , (a linear transformation,

T , followed by another linear transformation, S) is yet again a linear transformation because. To

see this,

S(T (au + bv)) = S(aT (u) + bT (v)) = aS(T (u)) + bS(T (v)); (5.5)

that is,

R(au + bv) = aR(u) + bR(v), (5.6)

where R = S ◦ T ; eqn 5.6 shows that eqn 5.4 is satisfied by R = S ◦ T and so S ◦ T is a linear

transformation.

Corresponding to any linear transformation T , there is an inverse transformation T−1 such that

I = T ◦ T−1, (5.7)

and

I(u) = u. (5.8)

These last few facts mean that linear transformations form a group, see A, where composition, ◦,replaces + and where the identity transformation, I, replaces 0.

We note also that, like group operations, linear transformations are associative, i.e.

(T1 ◦ T2) ◦ (T3) = (T1) ◦ (T2 ◦ T3). (5.9)

What eqn. 5.9 boils down to is that we can take a vector, u and transform it v′ = T1(u) and then

transform v′ as v′′ = T2(v′) and then v′′′ = T3(v′′) and so on . . . , v(n) = Tn(v(n−1) we can replace

all this with R = T1 ◦ T2 ◦ · · · ◦ Tn, and v(n) = R(v).

Note: alternative terms for composition are concatenation (or catenation) and compounding.

Why did we go to the trouble of building up to and stating this last sentence? Simply because it is

key to much of virtual reality computer graphics. Typically, between being created by a computer

program in a virtual 3D world and being rendered onto a 2D screen for viewing, computer graphics

objects (e.g. points, triangles) undergo a sequence of transformations, T1, T2, · · · , Tn, in the so

called graphics pipeline. If we can see to it that the transformations in the sequence are all linear,

then it means that we can compose them, R = T1 ◦T2 ◦ · · · ◦Tn; the composition needs to be done

just once, and the composite R applied to each object (maybe hundreds of thousands of them). If

n = 10, say, this is a huge saving and a crucial factor in the speed of modern graphics accelerators

and systems like OpenGL and DirectX.

Figure 5.1 (Figure 3-2 of (Shreiner, Woo, Neider & Davis 2006)) shows the transformation stages

that vertexes undergo in an OpenGL rendering pipeline; DirectX differs only in minor detail.

5–2

Page 37: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Figure 5.1: Vertex transformation pipeline.

In Figure 5.1, object coordinates are the raw vertex coordinates that appear in an OpenGL program.

Depending of the depth of nesting of objects — think world, robot, robot-arm, arm-hand, hand-

finger, finger-joint, . . . and large number of transformations may be contained in (via composition)

the modelview matrix.

The linear in linear transformation is highly restrictive. For example, if T simply adds another

vector to the first,

T (u) = u + t, (5.10)

T is not linear. To see this, we’ll work out the two sides of eqn. 5.2. First, the left hand side,

T (u + v) = u + v + t. (5.11)

Now the right hand side,

T (u) + T (v) = u + t + v + t = u + v + 2t, (5.12)

and we have a problem because the basic requirement of linearity, eqn. 5.2, is violated.

Shock horror, linear transformations cannot do vector addition! Worse still, we know that when

we come to moving objects (their points) around in a virtual world, vector addition is how we do

it. Given what we said about the crucial advantages of linearity in the last paragraph but one, we

seem to have a problem. All is not lost, Chapter 6 will show us that there is a simple way to make

eqn. 5.10 act linear.

5.3 Matrices as Linear Transformations

If as in section 3.3, we represent vectors as components with respect to a basis, then we can use

matrices and matrix arithmetic, section 4.3.1, to implement linear transformations. To see that

this is true, let us express a vector u in terms of a weighted sum of basis vectors,

u = u1e1 + u2e2, (5.13)

and then apply eqn. 5.2,

T (u) = T (u1e1 + u2e2), (5.14)

= u1T (e1) + u2T (e2).

5–3

Page 38: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Now, we know, see section 3.3 that any vector can be expressed as a linear combination of the

basis vectors, and that includes transformed basis vectors such as T (e1 and T (e2. So, we can

write

T (e1) = a1e1 + b1e2, (5.15)

and

T (e2) = a2e1 + b2e2. (5.16)

So, substitute these last two equations into eqn. 5.15 to get

T (u) = u1a1e1 + u1b1e2 + u2a2e1 + u2b2e2, (5.17)

= (u1a1 + u2a2)e1 + (b1u1 + b2u2)e2.

If we name T (u) as v) = T (u), and write v as v = v1e1 + v2e2, then collecting the e1 and e2,

coefficients, we have,

v1 = a1u1 + b1u2, , (5.18)

v2 = b1u1 + b2u2.. (5.19)

Now refer back to eqns. 4.1 and 4.2 in section 4.1, and you will see the same pattern as eqns. 5.18

and 5.19. In section 4.2 we showed how to express eqns. 4.1 and 4.2 using matrices. Thus,

eqns. 5.18 and 5.19 can be written in matrix form as

v = Au. (5.20)

A is a 2 row × 2 column matrix, A =

[a1 b1a2 b2

], v is a one column two row matrix, containing

a tuple of vector components, i.e. v is a two-dimensional vector, v =

[v1v2

]and u is another a

two-dimensional vector, u =

[u1u2

].

Vectors as Matrices We note again that instead of v = (v1, v2), we are now going to apply the

convention that vectors are columns rather than rows, v =

[v1v2

].

As already mentioned, v is a 2 × 1 matrix, 2 rows by one column; again, as before, because the

column representation above can take up too many lines, we often write, v = (v1, v2)t , where t

denotes transposition or just v = (v1, v2). Transpose takes an n ×m matrix and makes it m × n;

here, we have 1× 2→ 2× 1.

5–4

Page 39: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

5.4 Points and Vectors

In Section 2.1 we dealt with points, e.g. P = (Px , Py), and in Section 3 dealt with vectors, e.g.

v = (v1v2)t . You could be excused for confusing points and vectors. The difference is rather

subtle. When we say that P above can be represented by a vector p = (p1, p2), what we mean is

that P can be represented by the directed line (vector) OP = p, where O is the origin — a point,

P = O + p.

You can add a vector to a point to get a point. — if you get the point! We will formalise this

in chapter 6.

In the remainder of this chapter, we are going to be transforming points (P), but remember, we

are really transforming vectors OP = p.

5.5 Anatomy of a Linear Transformation

[I’m not sure whether this section should be before or after section 5.6. Maybe have a quick look

at section 5.6 and then return here.]

Recall what we are doing; we are transforming the vector u by multiplying it by the 2 × 2 matrix

A to get a new vector v.

v← Au, (5.21)

where

A =

[a11 a12a21 a22

]. (5.22)

Here I’m using the ← to emphasise what would be going on in a computer program, we are taking

an input vector, u, multiplying it by A to get a new vector which we assign to v.

We are quite aware that what really is going on, namely equations 5.23 and 5.24:

v1 ← a11u1 + a12u2, (5.23)

v2 ← a21u1 + a22u2. (5.24)

Alternatively, [vxvy

]=

[a11 a12a21 a22

]·[uxuy

]. (5.25)

What happens if we use transform the basis vector (1, 0)t using A? We get[a11 a12a21 a22

]·[

1

0

]=

[a11a21

]. (5.26)

And (0, 1)t? [a11 a12a21 a22

]·[

0

1

]=

[a12a22

]. (5.27)

5–5

Page 40: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

So, the first column of A is the vector that results in transforming (1, 0)t , and the second column

of A the vector that results in transforming (0, 1)t .

Let us see this in action. We will use the example of a unit rectangle whose bottom left hand

corner is at the origin, see Figure 5.2. X- and y-axes are shown and grid lines are shown every 0.5

units.

Figure 5.2: 2D Rectangle. (1, 0) and (0, 1) are marked as solid points.

Scaling See section 5.6.2.

We transform using

[2 0

0 1.5

]. Sure enough, we get (1, 0) → (2, 0) and (0, 1) → (0, 1.5), see

Figure 5.3(a), just as we expected.

Next transform using

[1 0

0 2

]. We get (1, 0) → (1, 0) and (0, 1) → (0, 2), see Figure 5.3(b),

again as expected.

Rotation See section 5.6.3.

We transform using

[cos 30◦ − sin 30◦

sin 30◦ cos 30◦

]=

[0.866 −0.5

0.5 0.866

]. Sure enough, we get (1, 0) →

(0.866, 0.5) and (0, 1)→ (−0.5, 0.866), see Figure 5.4(a), just as we expected.

Next transform using

[cos 45◦ − sin 45◦

sin 45◦ cos 45◦

]=

[0.707 −0.707

0.707 0.707

].

We get (1, 0)→ (0.707, 0.707) and (0, 1)→ (−0.707, 0.707), see Figure 5.4(b), just as expected.

5–6

Page 41: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Figure 5.3: Scaling. (a) scale x by 2, y by 1.5; (b) scale x by 1, y by 2.

The approach we have just described can be used for either of two purposes:

• we can fully determine the components of a transformation matrix if, after the transformation,

we can somehow see how (1, 0) and (0, 1) are transformed;

• if we need to know how to construct a transformation matrix for a particular transformation

task, e.g. rotate by 30◦, we can enquire: (a) where do we want (1, 0) to go to? This gives

the first column; then, (b) where do we want (0, 1) to go to? This gives the second column.

I think you will agree that it would be possible to use this method to derive the rotation

matrices above.

5–7

Page 42: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Figure 5.4: Rotation. (a) 30 degrees; (b) 45 degrees.

5–8

Page 43: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

5.6 Examples of Linear Transformations

5.6.1 Introduction

[Minor repetition in this introduction of stuff from section 5.5.]

Let us repeat eqns. 5.21 and 5.22. We are transforming the vector u by multiplying it by the 2×2

matrix A to get a new vector v,

v = Au, (5.28)

where

A =

[a11 a12a21 a22

]. (5.29)

We are quite aware that what really is going on, namely equations 5.30 and 5.31:

v1 = a11u1 + a12u2, (5.30)

v2 = a21u1 + a22u2. (5.31)

We will use the example of a simplified 2D house whose bottom left hand corner is at the origin,

see Figure 5.5. X- and y-axes are shown and grid lines are shown every 50 units (world units);

width is 150 units and height 150 units.

Figure 5.5: 2D House.

5–9

Page 44: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

5.6.2 Scaling

Scaling is easy to think about; we want to expand or contract independently along one or both of

the axes; so, we need multiplication factors on the diagonal of the matrix as in eqn. 5.32:[vxvy

]=

[sx 0

0 sy

] [uxuy

]. (5.32)

ux is expanded (sx > 1) or contracted (sx < 1) to give vx and the same for the second component

by sy along the y axis. Eqn. 5.32 leads to eqns. 5.33 and 5.34:

vx = sxux , (5.33)

vy = syuy .. (5.34)

If you want uniform scaling, sx = sy . Figure 5.6 shows two examples of non-uniform scaling; the

original house is shown (stippled) for comparison.

Figure 5.6: Scaling. Left: sx = 2, sy = 1.5; right: sx = 0.75, sy = 2.

Exercise. Analyse and describe the scaling matrix using the methods of section 5.5.

Exercise. What is the inverse, S−1, of the scaling matrix S =

[sx 0

0 sy

]?

(a) Think. How would you cancel the multiplication of something by sx ; ditto sy ;

(b) Use the formula in section 4.5;

(c) Make sure to check your answer — that S ·S−1 = I; I is the identity matrix, see section 4.4.1.

5–10

Page 45: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

5.6.3 Rotation

Rotation is a little more difficult; in general, both of the new components vx , vy will contain some

of ux , uy . With the assistance of Figure 5.7, we can derive the coefficients of eqns. 5.33 and 5.34.

Figure 5.7: Derivation of rotation matrix.

u = (ux , uy)t of magnitude (length) r is at an angle a with the x-axis (recall positive angles mean

anticlockwise rotation); we want to rotate u by an angle b to the x-axis, to form v = (vx , vy)t .

We note that v is at an angle (a+b) with the the x-axis, and, since rotation does not alter length,

its length is still r , so, trigonometry gives us

vx = r cos(a + b), (5.35)

vy = r sin(a + b). (5.36)

From Chapter 2, we have eqns. 2.9 and 2.7, repeated here as eqns. 5.37 and 5.38,

cos(a + b) = cos a cos b − sin a sin b, (5.37)

sin(a + b) = sin a cos b + cos a sin b. (5.38)

We can use these to expand eqns. 5.35 and 5.36 as

vx = r cos a cos b − r sin a sin b, (5.39)

vy = r sin a cos b + r cos a sin b.. (5.40)

More simple trigonometry gives us r cos a = ux and r sin a = uy ; substituting these into eqns. 5.39

and 5.40 gives the rotation equations,

vx = ux cos b − uy sin b, (5.41)

vy = uy cos b + uxa sin b. (5.42)

Hence the matrix equation is [vxvy

]=

[cos b − sin b

sin b cos b

] [uxuy

]. (5.43)

5–11

Page 46: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

This transformation rotates u anticlockwise by the angle b about the origin O.

Figures 5.8 to 5.8 show examples of rotations for 30◦, 60◦, 90◦, 180◦, 270◦; the original house is

shown (stippled) for comparison. Rotating by 360◦ gets us back to the original.

Figure 5.8: Rotation. left: 30◦; right: 60◦.

Exercise. Analyse and describe the rotation matrix using the methods of section 5.5.

Exercise. What is the inverse, R−1, of the rotation matrix R =

[cos b − sin b

sin b cos b

]?

(a) Think. How would you cancel a rotation by angle b? Rotate by −b?

(b) Use the formula in section 4.5;

(c) Make sure to check your answer — that R ·R−1 = I; I is the identity matrix, see section 4.4.1.

Note that cos(−b) = cos b and sin(−b) = − sin b.

Exercise. Rotate the point [0.707

0.707

]anticlockwise (positive) by 45 degrees. Check your answer with a drawing.

Note: sin 45◦ = 0.707 = 1/√

2 = cos 45◦; 0.707× 0.707 = 0.5 .

Exercise. Rotate the point [0

1

]anticlockwise by 90◦. Check your answer with a drawing.

5–12

Page 47: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Figure 5.9: Rotation. left: 90◦; right: 180◦.

Figure 5.10: Rotation. 270◦.

5–13

Page 48: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Exercise. What is the effect of applying a rotation matrix twice? That is, what is

R(c) · R(d)

[uxuy

]where R(c) =

[cos c − sin c

sin c cos c

]and R(d) =

[cos d − sin d

sin d cos d

].

Just multiply R(c) ·R(d) and see what you get; there should be no need to apply the result to u.

The following formulas will be useful:

sin(a + b) = sin(a) cos(b) + cos(a) sin(b)

cos(a + b) = cos(a) cos(b)− sin(a) sin(b)

Exercise. What is the effect of applying the negative rotation, −θ, to a point that has already

been rotated by +θ. That is, what is

R(−b)R(b)

[uxuy

]?

Again, just multiply R(c) · R(d) and see what you get — see section 4.4.1.

5–14

Page 49: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

5.6.4 Shear

Shear is not something we would do deliberately — except maybe in creating an it italic font. But

shear effects do appear in certain projections.

The following equation shears along the x axis,[vxvy

]=

[1 a

0 1

] [uxuy

], (5.44)

and this one along the y axis, [vxvy

]=

[1 0

b 1

] [uxuy

]. (5.45)

If we multiply out eqn. 5.44, we see that

vx = ux + auy

vy = uy .

Note that in this case y-coordinates are not affected, while in the eqn. 5.45, the x-coordinates are

not affected.

Figure 5.11 shows examples of shear.

Figure 5.11: Shear. Left: x-axis, a = 1.5; right: y-axis, b = 1.5.

Exercise. Analyse and describe the shearing matrices using the methods of section 5.5.

5–15

Page 50: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

5.6.5 Reflection

The following equation reflects about the y axis (x-coordinates are negated),[vxvy

]=

[−1 0

0 1

] [uxuy

], (5.46)

and this one about the x axis (y-coordinates are negated),[vxvy

]=

[1 0

0 −1

] [uxuy

]. (5.47)

If we multiply out eqn. 5.46, we see that

vx = −ux ,vy = uy .

Figure 5.12 shows examples of reflections.

Figure 5.12: Reflection. Left: y-axis; right: x-axis.

Exercise. Analyse and describe the reflection matrices using the methods of section 5.5.

5.6.6 Reflection as Negative Scaling

If you compare eqn. 5.46 with eqn 5.32 you will see that reflection about the y-axis (eqn. 5.46) can

be expressed as a negative scaling of x , sx = −1. Likewise reflection about the x-axis (eqn. 5.47)

can be expressed as a negative scaling of y , sy = −1.

5–16

Page 51: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

5.6.7 Projection

Projection onto x-axis: [vxvy

]=

[1 0

0 0

] [uxuy

]. (5.48)

Projection onto the y-axis: [vxvy

]=

[0 0

0 1

] [uxuy

]. (5.49)

If you compare eqn. 5.48 with eqn 5.32 you will see that projection onto the x-axis can be expressed

as a zero scaling of y , sy = 0 with unity scaling of x , sx = 1. Likewise projection onto the y-axis

(eqn. 5.49) can be expressed as a zero scaling of x , sx = 0 with unity scaling of y , sy = 1.

5.6.8 Translation

Translation (displacement, movement) is given by eqn. 5.50.[vxvy

]=

[txty

]+

[uxuy

]. (5.50)

Notice that translation does not, in this form, involve a matrix. In fact, translation is not a linear

transformation; but we would like all our graphics transformations to be linear (and implemented

with matrices)! Chapter 6 shows how translation can be made linear and implementable by a

matrix multiplication.

Figure 5.13 shows an example of translation.

5–17

Page 52: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Figure 5.13: Translation. x-axis by 60; y-axis by 80.

5–18

Page 53: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

5.6.9 Window to Viewport Transformation

The window to viewport transformation is an affine transformation one that crops up a lot in

computer graphics, though often behind the scenes and away from programmer control. It takes

part of (a window ) a 2D picture in world coordinates and transforms the points in the window to

screen coordinates. Note that in this context the term window means window on the world, the

sort of view one would have looking at a view through a window. Note also that both window and

viewport are 2D entities — the world may be 3D but that 3D world has been projected onto the

window.

Let us assume you have a drawing of a house and surroundings and the drawing uses real-world

units (metres say). The drawing would use world coordinates xw , yw . Now we want to take part

of that drawing and display it on a graphics display; the part of the world we call a window —

window on the world.

In general you may want to display it as part of the screen; the part of the screen we call a viewport.

Thus, the window selects what part of the world is to be displayed.

To do the drawing on the screen we need to convert from world coordinates xw , yw to screen or

device coordinates xd , yd . This is done using the window to viewport transformation:

xd = (Vxr−Vxl )(Wxr−Wxl )

(xw −Wxl) + Vxl ,

yd =(Vyt−Vyb)(Wyt−Wyb)

(yw −Wyb) + Vyb. (5.51)

The two coordinate systems are shown in Figure 5.14.

The window to viewport transformation is an affine transformation, i.e. contains shifting (transla-

tion) and scaling. Note that the scaling may be negative, in other words, it can handle the situation

in which the world y-axis points up and the screen y-axis points down — as is the case in Java

Graphics2D. We derive a general formula for shifting an scaling in section 5.6.10 below.

Exercise. Verify that eqn. 5.51 is an affine transformation, see eqn. 6.1.

Partial answer. Multiply out eqn. 6.1,

vx = a11ux + a12uy + tx

vy = a21ux + a22uy + ty , (5.52)

and change variable names vx → xd , vy → yd , ux → xw , uy → ye.

(a) What are a11, a12, a21, a22 in eqn. 5.51?

(b) What are tx , ty in eqn. 5.51?

5–19

Page 54: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Figure 5.14: Window to Viewport transformation.

5–20

Page 55: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

5.6.10 A Handy Shifting and Scaling Formula

It is a common requirement to have to have to do a simple linear mapping u 7→ v based on

u0 7→ v0, u1 7→ v1; actually, it’s affine rather than linear, but it’s linear apart from the shift

(translation). We define the mapping formula as a scaling (a) plus a shift (b).

v = au + b. (5.53)

We have two pairs of points from which to derive a, b, namely, u0 7→ v0, u1 7→ v1; from these we

have two equations,

v0 = au0 + b, and, (5.54)

v1 = au1 + b; (5.55)

Eqn. 5.54 gives b in terms of a:

b = v0 − au0; (5.56)

substituting eqn. 5.56 into eqn. 5.55 gives

v1 = au1 + v0 − au0, (5.57)

so

a =v1 − v0u1 − u0

. (5.58)

Substituting eqn. 5.58 into eqn. 5.56 gives

b = v0 − u0v1 − v0u1 − u0

; (5.59)

Eqn. 5.53 becomes

v =v1 − v0u1 − u0

u + v0 − u0v1 − v0u1 − u0

, (5.60)

which, reorganised, becomes:

v = (u − u0)v1 − v0u1 − u0

+ v0. (5.61)

Thus, (i) shift u so that u0 corresponds to zero, (ii) scale by the required range divided by the old

range, (iii) add v0 to bring zero up to v0.

5.6.11 Rigid Body Transformation

When, in a linear or affine transformation, we have a matrix corresponding to a rotation, see

eqn 5.43, including zero rotation — the identity matrix, we have what is called a rigid body

transformation — the transformation does not change the shape of the object, just the orientation

angle and position.

The key to rigid body transformations is that the matrix is special orthogonal.

Look again at eqn. 5.43 repeated here as eqn. 5.62.

5–21

Page 56: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

[vxvy

]=

[cos b − sin b

sin b cos b

] [uxuy

], (5.62)

i.e., naming the rotation matrix R, v = Ru.

If we consider the rows of R as vectors, i.e. [cos b − sin b] and [sin b cos b], we find that the pair

of vectors and R have the following four properties:

(i) each is a unit vector; for example, the length of [cos b − sin b] is√[cos b − sin b] · [cos b − sin b] =

√cos2 b + sin2 b = 1; (we know that cos2 b+ sin2 b = 1);

and the same is true for the second row;

(ii) they are orthogonal (perpendicular to one another); [cos b − sin b]·[sin b cos b] = cos b sin b−sin b cos b = 0; so, u and v are orthogonal (perpendicular to one another), see section 3.4.4;

(iii) the determinant of R is +1; |R| = cos b cos b + (− sin b)(− sin b) = cos2 b + sin2 b = 1;

(iv) the inverse of R is its transpose, see section 4.4.4. For example, R =

[cos b − sin b

sin b cos b

], so,

R−1 =

[cos b sin b

− sin b cos b

].

Notice that reflection matrices, section 5.6.5, satisfy properties (i) and (ii), but the determinant

is -1.

5.7 Pre-multiplication versus Post-multiplication of matrices

In these notes we use pre-multiplication of vectors by matrices; thus, in eqn. 5.63, the matrix A

appears on the left. [vxvy

]=

[a11 a12a21 a22

]·[uxuy

]. (5.63)

As we know, eqn. 5.63 is matrix-speak for eqns. 5.64 and 5.65:

v1 = a11u1 + a12u2, (5.64)

v2 = a21u1 + a22u2. (5.65)

In eqn. 5.63 we are multiplying a 2× 2 matrix by a 2× 1 vector (a column vector) to get a 2× 1

vector.

Many textbooks, for example (Schneider & Eberly 2003) and (Dunn & Parberry 2002) express the

same thing using post-multiplication, i.e. they consider vectors to be row vectors and so 1× 2 or

1 × 3. In this case the matrix is on the right and, in the 2D case, matrix multiplication becomes

1 × 2 vector (a row vector) by a 2 × 2 matrix to produce a 1 × 2. When post-multiplication is

the standard, any matrix involved is the transposed version of the matrix that would be used in

pre-multiplication. The result (the individual vector components) is identical, but if you are not

aware of it, you can become very confused when switching between standards.

5–22

Page 57: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

To check that everything is okay, let use rewrite eqn. 5.63 in post-multiplication, row vector form:

[vx vy ] = [ux uy ] ·[a11 a21a12 a22

]. (5.66)

Noting that we transposed the matrix in eqn. 5.66, we see that when we multiply out eqn. 5.66 to

eqns. 5.67 and 5.68:

v1 = a11u1 + a12u2, (5.67)

v2 = a21u1 + a22u2, (5.68)

we see that the resulting equations are identical to eqns. 5.64 and 5.65. Note, however, that the

2× 2 matrix in eqn. 5.66 is a transposed version of that in eqn. 5.63.

5.8 Memory Layout of Matrices

In section 5.7 we noted the use in many textbooks of matrix post-multiplication and consequently

of row vectors (rather that our pre-multiplication of column vectors). This may be partly due

to the fact that DirectX uses so called column major representation of matrices. According to

(vanVerth & Bishop 2004) OpenGL does the same, in spite of the OpenGL documentation which

uses pre-multiplication of column vectors and which would imply a row major representation.

This is a potential source of significant confusion. Beware. If in OpenGL we read the con-

tents of a matrix into a 16 element array using glGetDoublev, see below, we need to be care-

ful to write it out using the indexing given by i= r + c*cLen; //*. That is the matrix data

are store in memory as m[0][0], m[1][0], m[2][0], m[3][0], m[0][1], “ldots and not

m[0][0], m[0][1], ... as might naively be expected.

void matPrint(int nmat, char *msg)–

double mat[16]; int r, c; int nc= 4, nr= 4, i, cLen= 4;

glGetDoublev(nmat, mat);

printf(”%s“n”, msg); printf(”[”);

for(r= 0; r¡ nr; r++)–

printf(”(”);

for(c= 0; c¡ nc; c++)–

i= r + c*cLen; //*

printf(”%.4f”, mat[i]);

if(c == nc-1) printf(”)“n”); else printf(”, ”);

˝

˝ printf(”]“n”);˝

5.9 Complex Numbers

[This section is here because it is peripherally related to 2D transformations. It is also a little

untidy and there may be repetition.]

5–23

Page 58: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

5.9.1 Introduction

Complex numbers arose out of determination of solutions to awkward quadratic and cubic poly-

nomial equations. They involve√−1 and as you know, there is no real number which squared

become −1; this, initially they were called imaginary numbers.

A general complex number may be represented by a pair of numbers that represent the coordinates

(x, y) of points in a plane,

z = x + iy

where i =√−1.

As such, a complex number is rather like a two-dimensional vector and, indeed, the mathematics

of complex numbers provides a complete apparatus for the manipulation of 2D vectors and pairs

of coordinates.

The modulus of the complex number (which may be interpreted as the distance between the origin

and (x, y) ) is given by:

| z | = | x + iy | =√

(x × x + y × y)

i.e. using Pythagoras’s Theorem

The angle, or argument, which may be interpreted as the angle between the line (0, 0) to (x, y)

and the x-axis, is given by:

arg z = arctan y/x

i.e. the angle whose tangent (opposite/adjacent) is y/x .

Addition of complex numbers is as follows: If

z = x + iy , w = u + iv

then

z + w = x + u + i(y + v)

A graphical interpretation of addition of complex numbers is,

– draw a line from (0,0) to (x, y),

– using (x, y) as the origin, draw a line to (u, v),

– the point reached is (x + u, y + v).

I.e. vector addition.

Multiplication of complex numbers is as follows:

If

z = x + iy , w = u + iv

5–24

Page 59: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

then

z.w = (x + iy).(u + iv) = x.u + i .i .y .v + i .(y .u + x.v)

We use i .i = −1 (i.e.√−1√−1 = −1) This gives:

z.w = (x.u − y .v) + i .(y .u + x.v)

Note: if complex numbers have zero imaginary parts, the rules given here collapse to the rules of

normal arithmetic for real numbers.

Exercise Verify the last statement, i.e. set y , v = 0 in addition and multiplication of complex

numbers.

The complex conjugate of a complex number, c = a + ib is

c∗ = a − ib

5.9.2 Complex Numbers as Real Number Pairs

Here we follow (Eves 1965/1990a), p. 119.

5.9.3 Algebra of Complex Numbers

Addition

(a + ib) + (c + id) = (a + c) + i(b + d). (5.69)

Multiplication

(a + ib)(c + id) = ac + iad + ibc + i2bd (5.70)

= (ac − bd) + i(ad + bc).

It is easy to show that addition and multiplication are commutative and associative; also multipli-

cation is distributive over addition, see appendix A.

5.9.4 Hamilton’s Real Number Pairs

Between 1833 and 1837, while he was already on the trail of quaternions, Hamilton worked on a

representation of a complex number as a pair of reals, (a, b).

Addition

(a, b) + (c, d) = (a + c, b + d). (5.71)

5–25

Page 60: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Multiplication

(a, b)(c, d) = (ac − bd) + i(ad + bc). (5.72)

Embedding of Real numbers

(a, 0) + (b, 0) = (a + b, 0), (5.73)

(a, 0)(b, 0) = (ab, 0).

Units

(a, b) = (a, 0) + (0, b) (5.74)

= (a, 0) + (b, 0)(0, 1)

= a + bi ,

where i = (0, 1) and (1, 0) = 1 are units.

Eqn. 5.72 leads to

i2 = (0, 1)(0, 1) = (−1, 0) = −1. (5.75)

5.9.5 Complex Numbers as Algebra for Euclidean Geometry

Here we follow (Needham 1997), chapter 1.

Every similarity (transformation) is the composition of a scaling rotation and a translation. Note:

in most books, the term dilative rotation is used instead of scaling rotation.

Figure 5.15 shows the familiar Argand diagram representation of a complex number.

Figure 5.15: Complex number as a point on the x − y plane.

5–26

Page 61: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Figure 5.16: Addition – translation; multiplication – rotation + scaling.

5.9.6 Translation and Dilative Rotation

Figure 5.16 shows that complex addition provides translation and complex multiplication provides

dilative rotation.

v =| v | e ib, u =| u | e ia. (5.76)

uv =| u || v | e i(a+b), (5.77)

uv is v dilated by | u | and rotated by b.

If we apply a further dilative rotation, w =| w | e ic , we find

w(uv) =| w || u || v | e i(a+b+c). (5.78)

5.9.7 Algebraic Properties

It is easy to verify that the algebra of complex numbers has the following properties, see Appendix A.

Closure i.e. the composition of two dilative rotations is another dilative rotation;

Associativity of multiplication w(uv) = (wu)v , etc. because of the associativity of real number

addition and multiplication;

Associativity of addition ;

5–27

Page 62: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Commutativity of multiplication uv = vu, again because of the commutativity of real number

addition and multiplication; in operator language: U ◦ V = V ◦ U;

Commutativity of addition

Unique Inverse of Multiplication (Division)

u−1 =ux

u2x + u2y− i

uyu2x + u2y

, (5.79)

=ux − iuyu2x + u2y

,

which is defined except in the case of ux = 0, uy = 0; the inverse property is more easily seen

if | u |= 1 and so u, as an operator, represents a pure rotation:

1

u=ux − iuy

1= ux − iuy ;

the angle −θ of ux − iuy is obviously the negative of the angle θ of ux + iuy , so division

reverses rotation.

Finally, looking ahead to quaternions, Chapter 9, we have:

Multiplicative absolute value

| s | = | uv |=| u || v |, so, squaring each side, (5.80)

(s2x + s2y ) = (u2x + u2y )(v 2x + v 2y ).

5.9.8 Operator Character

We note that a number can now be considered not only as an entity in itself, but also as an

operator. In the case of complex numbers and dilative rotation, the operator character becomes

obvious.

5.9.9 Link with Matrices

The corresponding matrix representation of rotation; if u is a rotation, | u |= 1, i.e. no scaling,

and u = e ia.

s = uv (5.81)

= e iav

= (cos a + i sin a)(vx + ivy)

= (vx cos a − vy sin a) + i(vx sin a + vy cos a)

= sx + i sy ,

where we have used Euler’s formula: e iθ = cos θ + i sin θ.

Eqn. 5.81 is readily recognisable in the matrix form of eqn 5.43:

[sxsy

]=

[cos a − sin a

sin a cos a

] [vxvy

]. (5.82)

5–28

Page 63: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Chapter 6

Affine Transformations and HomogeneousCoordinates

6.1 Introduction

This chapter has two major objectives:

• a brief and informal introduction of points to the vector and transformation story;

• introduction of homogeneous coordinates and showing how, if we use homogeneous coordi-

nates, affine transformations behave like linear transformations, i.e. we can compose them

and combine many transformations into one.

You should note that homogeneous coordinates are not only about a convenience in the handling

of points and affine transformations. In fact, homogeneous coordinates allow us also to han-

dle projective transformations in a ‘linear’ manner — now that’s a big deal, because projective

transformations are really ugly beasts.

We will leave the following topics to Chapter 8.

• mention of the role of affine transformations in parallel projection;

• introduction of perspective projection and the corresponding perspective transformation;

• showing how perspective transformation ‘becomes linear’ if we use homogeneous coordinates.

Thus, we will arrive at a situation when most of the transformations that take place in the graphics

pipeline are made ‘linear’ (in homogeneous coordinate space) and so can all be composed into one

single matrix. This has great savings, not just because graphics hardware is fine tuned to do fast

matrix operations, but because we can compose eight or ten matrices into one (once only) and so

end doing just one matrix multiplication — on a great many points. Hence the significance of going

to homogeneous coordinates and ‘linear’ transformations which, as we have seen in section 5.2,

form a group and so, with associativity of composition, multiples of them can be combined into

one.

6–1

Page 64: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

6.2 Points and Vectors and Affine Spaces

In section 5.4 we briefly introduced the idea of a point, P , as a vector OP from the origin, 0, to

P . That was fine, but what we kept quiet about is that vector spaces (section 3.6) have no notion

of points. We’re going to tidy up things here, but briefly.

Informally, we know what points are: for example, the point marked (P say) by the centre of the

piece of chewing gum beside where you parked your car this morning, the point marked by the

Letterkenny/Port Road corner of the main building outside the canteen (Q say), etc. We know

about vectors (as displacements), for example walk north-west 100 metres — here we’re assuming

agreement about two orthogonal basis vectors North and West.

Staying informal, we can then combine points and vectors, for example, start at point P (see

above) and move 10 metres west (the latter in italics a vector (u, say) and you will find the gold

(at point G, say).

In mathematical language: G = P + u — add a vector to a point and you get another point.

Similarly, what is the instruction (displacement) to get from P above (the corner) to Q (your car)?

We subtract P from Q; the vector v that you need to travel is given by v = P −Q. Sort of like if

you have p Euro already, and needed q Euro to buy a car, how many Euro do you need to borrow?

— q − p Euro.

An affine space comprises:

(a) A vector space, see 3.6; typical vectors are u, v, . . . ;

(b) A set of points; typical points are P,Q, . . . .

What mathematical operations are possible on the vectors and points?

(i) All the operations involving the vector space (vectors and scalars), see section 3.6;

(ii) Add a vector to a point to get a point: Q+ v = P ; if we add the zero vector to a point, we

get the same point: Q+ 0 = Q (move zero from Q and you remain at Q);

(iii) Subtract points to get a vector: v = P −Q;

As regards the vector space, we’re going to assume that a set of basis vectors, for example,

e1, e2, e3 (or i, j, k) for a three dimensional vector space, have been agreed upon.

We are nearly there. Notice that all our talk above about points was relative — how to get from

Q to P or from P to G. I don’t know if we have an Ordnance Survey (OS) map users in the class,

but the forgoing discussion was rather like (in a set of instructions to climb Errigal mountain): ‘on

the R789, find a road sign marked Dunlewey (point P , say), walk North-West 523 metres and look

for a derelict building (point Q, say); climb 239 metres North-East . . . ’.

Not good! What we need is a frame of reference like the OS uses (they call it a grid, we want

to be able to attach numbers (coordinates) to arbitrary points. Thus, ‘stop on the R251 at the

bridge at grid point 969 219 (East = 969 North = 219) . . . ’.

6–2

Page 65: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

6.3 Frames

To get from the affine space of the previous section with its points and vectors (including the basis

vectors e1, e2, e3, all we need to do is agree on some chosen point as the origin, O. Now we can

reference all our points with respect to O and the basis vectors. Thus, (East = 969, North = 219)

means the point, P , made by adding to the origin O the vector, p (vector in lower case), made up

of 969 units of the East unit vector and 219 units of the North unit vector, P = 0 + p.

Note, incidentally, that a full grid reference has numbers before the 969 and 219, and also letters

giving zones; as far as I know, the origin of the Irish national grid is somewhere in the sea south of

Cork.

Since we have made the basis vectors are orthogonal, we have a Cartesian frame.

6.4 Affine Transformations

Already in sections 5.6.8 and 5.6.9 we have encountered affine transformations and have noted

that they are not linear and so cannot be implemented using (plain) matrices.

An affine transformation has the form of eqn. 6.1,

[vxvy

]=

[a11 a12a21 a22

] [uxuy

]+

[txty

], (6.1)

That is it contains a matrix multiplication and a vector addition — the latter a translation.

It is called affine because objects (e.g. a triangle or rectangle or straight line, . . . ) before transfor-

mation have an affinity with those after the transformation; affinity means something like ‘similar

in shape’, but please note that similar has a specific meaning in geometry.

After affine transformation:

• straight lines remain straight lines;

• parallel lines remain parallel.

Linear Transformation If, in eqn. 6.1, we remove the translation vector,

[vxvy

]=

[a11 a12a21 a22

] [uxuy

], (6.2)

we have a linear transformation. In a linear transformation vx and vy contain only linear combina-

tions of ux and uy , no (quadratic) terms in u2x or u2y for example, and no constant terms like the

translation terms tx and ty .

Incidentally, similar, see above means something different — angles and relative distances are

preserved, for example, a rectangle becomes a rectangle, whereas in linear or affine transformations,

a rectangle can change into a parallelogram.

6–3

Page 66: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

6.5 Homogeneous Coordinates

For the reasons already stated in the introduction, section 6.1, we want to be able to express all

transformations (or as many as possible) as a matrix multiplication, see eqn. 6.2. There is a neat

trick that allows us to convert eqn. 6.1 to something that looks like eqn. 6.2.

Use of homogeneous coordinates allow us to express translation, as well as rotation and scaling,

as a matrix multiplication.

All we have to do is extend [vxvy ]t with a third coordinate vw ,

[vxvy

]→

vxvyvw

. (6.3)

In most cases, vw = 1, and if it isn’t we correct the vector so that it is; this is done by dividing

each component by vw — vw/vw = 1, unless vw = 0, in which case, see section 6.5.1.

In homogeneous coordinates, eqn. 6.1 becomes,

vxvyvw

=

a11 a12 txa21 a22 ty0 0 1

uxuyuw

. (6.4)

Let us multiply out eqn. 6.4, after setting uw = 1,

vx = a11ux + a12uy + tx

vy = a21ux + a22uy + ty

vw = 1. (6.5)

In other words, after we discard vw , the result is the same as for eqn. 6.1. Magic!

Figure 6.1 shows one way of thinking about of the homogeneous coordinates trick, which, isn’t a

trick at all, but has a proper mathematical basis; see (Schneider & Eberly 2003) for one approach,

(Dunn & Parberry 2002) and (Foley et al. 1994) and (Foley et al. 1990) for a treatment similar

to that given here; (Maxwell 1946) gives another more mathematical treatment.

The xy plane is now on the horizontal with the w axis pointing up vertically out of it. The plane at

w = 1 is the xy plane raised up one unit; think of the parallelogram in Fig. 6.1 as a sheet of glass

parallel to the x-y plane, but raised one unit of w above it (the x-y plane). Instead of representing

a point (vx , vy) as OP on the xy plane, we represent it as a line (vx , vy , vw) in three dimensional

xyw space, see OP ′ in Figure 6.1.

If, after a calculation on points, we have (vx , vy , vw) and vw 6= 1, we simply divide each component

by vw , to get (v ′x = vx/vw , v′y = vy/vw , 1); (v ′x , v

′y) now corresponds to the point P on the vw = 1

plane; now throw away vw(= 1) and (v ′x , v′y) is your desired result.

6–4

Page 67: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Figure 6.1: xyw Homogeneous Coordinates.

6.5.1 Point at Infinity

What if vw = 0? Dividing by (vw = 0) is a no-no. Well, the simple answer is that you should never

get vw = 0.

However, (vx , vy , vw = 0) is a neat way of representing the point at infinity. Later when you get

on to 3D projections, this will come in handy.

6.5.2 Vectors

Another interpretation of (vx , vy , vw = 0) is a vector, rather than a point. For example, let us

have point p = (px , py , pw = 1) and q = (qx , qy , qw = 1) and we subtract to get a vector,

p− q = px − qx , py − qy , 1− 1 = 0); i.e. the w component of the vector is 0.

6.5.3 Points and Vectors in OpenGL

Let us jump to 3D for a moment. If you want to specify a point (vertex) in OpenGL, one way

is to write glVertex2d(x, y);. Because OpenGL is 3D at heart and needs three coordinates,

x, y , z , for a vertex, it (OpenGL, automatically) makes z = 0 to that we have (x, y , z = 0). Next,

it creates a 4D homogeneous vector by augmenting (x, y , z = 0) with w = 1, i.e. we end up with

(x, y , z, w = 1).

In OpenGL all points (vectors) are represented by four homogeneous coordinates (x, y , z, w) and

all transformation matrices are 4× 4.

This may worry some programmers who may be concerned about performance implications —

why do 4 × 4 matrix multiplications when we could often get away with 3 × 3 or even 2 × 2?

Think of all those extra multiplications and additions. Relax. Don’t worry. For a start, if you

have a decent graphics card, most of the transformations will be done on very fast hardware with

parallelism; second, if it needs to be done in software, it doesn’t take a very clever compiler to

be able to optimise out calculations that always give the same result, or are irrelevant. Even for

programmers, the benefits of homogeneous coordinates greatly justify the costs.

6–5

Page 68: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

6.6 2D Affine Transformations in Homogeneous Coordinates

6.6.1 Translation

See eqn. 6.4.

vxvyvw

=

1 0 tx0 1 ty0 0 1

uxuyuw

. (6.6)

i.e. we have the 2× 2 identity matrix in the top left 2× 2 submatrix, (tx , ty) as the top right-hand

2× 1 column, and finally, the bottom row of (0, 0, 1).

Just to reinforce the point, let us, as in section 6.5, multiply out eqn. 6.6, with uw = 1,

vx = ux + tx

vy = uy + ty

vw = 1. (6.7)

In other words, after we discard vw , the result is the same as for eqn. 5.50.

6.6.2 Rotation vxvyvw

=

cos b − sin b 0

sin b cos b 0

0 0 1

uxuyuw

. (6.8)

I hope it is obvious that with uw = 1 and after discarding the vw(= 1) this is the same as eqn. 5.43.

6.6.3 Scaling, Shearing, Reflection

Given what we have seen in sections 6.6.1 and 6.6.2 it should be obvious that we can create

the appropriate homogeneous representation by replacement of the top lefthand 2 × 2 matrix in

eqn. 6.8 by the matrices from eqns. 5.32 (scaling), 5.45 (shear), 5.46 (reflection about y-axis),

and 5.47 (reflection about x-axis).

6.7 Composition of Homogeneous Transformations

In section 5.2 we made a big song and dance about the fact that we could compose any number of

linear transformations, Tcomp = T1 ◦T2 ◦ · · · ◦Tn and similarly any number of matrix multiplications

that implement linear transformations and end up with the same overall transformation as if we

had applied the n transformations, successively, one at a time. We noted the savings that accrued

from this ability to compose once (n matrix multiplications) to get Tcomp, and then apply Tcompto M vectors (n multiplications followed by M matrix-vector multiplications), rather than applying

6–6

Page 69: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

each of T1, T2, · · · , Tn to each of M points (n×M multiplications). That is, n+M as opposed to

n ×M — potentially a big saving.

Alright, does this work for homogeneous transformations. Obviously it does! But let us demon-

strate. We will rotate by angle θ and the translate by (tx , ty). The rotation matrix is

R =

cos θ − sin θ 0

sin θ cos θ 0

0 0 1

. (6.9)

The translation matrix is

T =

1 0 tx0 1 ty0 0 1

. (6.10)

Multiplying, we get

TR =

1 0 tx0 1 ty0 0 1

· cos θ − sin θ 0

sin θ cos θ 0

0 0 1

=

cos θ − sin θ txsin θ cos θ ty

0 0 1

, (6.11)

which is what we expected.

6–7

Page 70: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Chapter 7

3D Transformations

7.1 Introduction

In Chapter 5 we derived and discussed a number of linear transformations; then we introduced the

translation affine transformation; we noted that affine transformations cause us problems because

graphics hardware and software can take advantage of the composability of linear transformations,

i.e. we can create a composite transformation (matrix) that combines a whole raft of transforma-

tions. That means the hardware (or software) need perform just one application of a transformation

(a matrix multiplication) instead of the afore mentioned whole raft of them. When we have a great

many vertexes (points) this has a hugely beneficial effect on performance — we can display more

frames per second, or, for a chosen fixed frame rate rate, we can handle more complex and hence

more realistic virtual reality scenes.

Here we cover 3D transformations. Given what we already know about 2D transformations, this

will be relatively easy. We will be extending the 2D stuff we covered in section 6.6, so make sure

you are comfortable with what is in that section.

7.2 3D Homogeneous Coordinates

As with 2D, use of 3D homogeneous coordinates allow us to express translation, as well as rotation

and scaling, as a matrix multiplication. We start off with three coordinates [vxvyvz ]t and all we

have to do is extend [vxvyvz ]t with a fourth coordinate vw ,

vxvyvz

→vxvyvzvw

. (7.1)

As with 2D, in most cases, vw = 1, and if it isn’t we correct the vector so that it is; this is done

by dividing each component by vw — vw/vw = 1, unless vw = 0, in which case it is the point at

infinity, see section 6.5.1, or a vector, see section 6.5.2.

We have already pointed out how OpenGL represents vertexes (points), see section 6.5.3. If you

want to specify a 3D point (vertex) in OpenGL, one way is to write glVertex3d(x, y, z);.

7–1

Page 71: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

OpenGL creates a 4D homogeneous vector by augmenting (x, y , z) with w = 1, i.e. we end up

with (x, y , z, w = 1).

As already stated, in OpenGL all points (vertexes) and vectors are represented by four homogeneous

coordinates (x, y , z, w) and all transformation matrices are 4× 4.

7.3 3D Affine Transformations in Homogeneous Coordinates

7.3.1 Translation vxvyvzvw

=

1 0 0 tx0 1 0 ty0 0 1 tz0 0 0 1

uxuyuzuw

. (7.2)

i.e. we have the 3×3 identity matrix in the top left 3×3 submatrix, (tx , ty , tz) as the top right-hand

3× 1 column, and finally, the bottom row of (0, 0, 0, 1).

7.3.2 Rotation

Rotation about the z-axis Rotation about the z-axis is in fact what we have been doing in

2D rotations. Consequently, the matrix is easy to write down; it should operate on the x- and

y-cordinates as before, and leave the z-coordinate untouched (multiplied by 1); if you rotate about

an axis, all coordinates along that axis are unaltered — make sure this is demonstrated in class.

The translation elements are zero.

Rz(b) =

cos b − sin b 0 0

sin b cos b 0 0

0 0 1 0

0 0 0 1

. (7.3)

At this stage it may be worthwhile to refer back to section 5.5 and its way of looking at transfor-

mation matrices, i.e. column 1 tells us what e1 = (1, 0, 0)t is transformed to, column 2 tells us

what e2 = (0, 1, 0)t is transformed to, and column 3 tells us what e3 = (0, 0, 1)t is transformed

to. In the cases of e1 and e2, the answer is the same as given before, for example in eqn. 5.43. In

the case of e3 = (0, 0, 1)t we see that it is transformed to itself.

Rotation about the x-axis Rotation about the x-axis should work on the y- and z-coordinates

and leave the x-coordinate alone — column 1, the x column, should be (1, 0, 0, 0)t . As always

with pure rotation matrices (about the origin), the translation elements are zero.

Rx(b) =

1 0 0 0

0 cos b − sin b 0

0 sin b cos b 0

0 0 0 1

. (7.4)

7–2

Page 72: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Rotation about the y-axis

Ry(b) =

cos b 0 sin b 0

0 1 0 0

− sin b 0 cos b 0

0 0 0 1

. (7.5)

7.3.3 Scaling, Shearing, Reflection

Given what we have seen in sections 7.3.1 and 7.3.2 it should be obvious that we can create the

appropriate homogeneous transformations by appropriate replacement of the top lefthand 3 × 3

matrix in eqn. 7.4.

7.4 Transformations Between Frames

In Chapter 5 we discussed how to move points around (i.e. transform their equivalent vectors).

Very often we need to do something very similar, we need to move frames around; we introduced

frames in section 6.3, i.e. a affine space which have points and vectors and notably a vector basis

and a chosen point called the origin.

Say we have a point p in world coordinates (defined in the coordinates of the world frame, for

instance a the centre point of an object in a game. Now say we have a camera with its own

camera frame and we want to know the coordinates of p in this frame.

The problem is rather similar to the transformation of points and has a rather similar solution, but

it helps to build a more sophisticated notation than we used in Chapter 5.

The situation is shown in Figure 7.1.

We have a world frame, e1w, e2w, e3w, Ow , and a camera frame e1w, e2w, e3w, Oc ; the camera frame

is rotated (counterclockwise, so the angle is positive) by an angle a and translated by the vector

d = (d1 d2)T = Oc −Ow .

But we’ll start solving the problem by considering the case where there is just rotation between

the frames, see Figure 7.2.

The notation used is one introduced by (Craig 1986) and used in books on computer vision such

as (Shapiro & Stockman 2001) and (Forsyth & Ponce 2003); as the latter books say, the notation

looks complicated at first, but once used become simple and rewards with the lack of confusion of

some apparently easier notations.

7–3

Page 73: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

e2c

e1c

a

g

Oc Ow

e2w

e1w

e3w = e3c

e3c

p

e2e1

OcOw = Oc − Ow = (d1 d2 0)T

OwOc = Ow − Oc = (e1 e2 0)T

(vectors, so position

is irrelevant)

d1

d2

d2

d1

Figure 7.1: Transformation from world to camera coordinates.

e2w

e2c

e1w

e1c

a

e3z = e3c

Oc = Ow

d

g

f

e

Figure 7.2: Transformation from world to camera coordinates, rotation only.

7–4

Page 74: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Considering now only rotation as in Figure 7.2, we state without proof — but see Chapter 5 where

we discussed the anatomy of point transformation matrices.

Because we consider only rotation, we can avoid homogeneous coordinates to start with, but we

include them later when we include translation.

The transformation from world to camera is contained in the matrix cwR,

cwR =

e1w · e1c e2w · e1c e3w · e1ce1w · e2c e2w · e2c e3w · e2ce1w · e3c e2w · e3c e3w · e3c

. (7.6)

You will note that scalar (dot) product eiw · ejc gives the projection of the world basis vector eiw onto

the camera basis vector ejc, see section sec:scalar-prod-projection which discusses the projection

role of scalar product. Because both eiw and ejc are unit vectors, then the scalar product is just

the cosine of the angle between them. Note also that eiw · ejc = ejc · eiw; an easy way of justifying

this is that cos−a = cos a for any angle.

We may shed further light on eqn. 7.6 by noting that the first column of cwR is comprised of the

coordinates of e1w in the camara (c) basis; likewise the second column of cwR is comprised of the

coordinates of e2w in the camara (c) basis, etc.

The third row of cwR is comprised of the coordinates of e2c in the world (w) basis.

We write the transformation of the world coordinates (wp) of a point p to camera coordinates (cp)

as

cp = cwR wp. (7.7)

Note carefully that the subscript in cwR must be match the superscript in wp and that the superscript

in cwR must match the superscript in cp.

Discussion Examine Figure 7.2; the camera from is related to the world frame by a rotation

about the z-axis; this is the simeple planar rotation that we considered in Chapterch:vtrans.

Let us repeat eqn. 7.6 as

cwR =

e1w · e1c e2w · e1c e3w · e1ce1w · e2c e2w · e2c e3w · e2ce1w · e3c e2w · e3c e3w · e3c

, (7.8)

and use trigonometry to fill in the components,

cwR =

cos a sin a 0

− sin a cos a 0

0 0 1

. (7.9)

How does this perform when we apply eqn. 7.7,

7–5

Page 75: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

cp = cwR wp?

We have

cp1cp2cp3

=

cos a sin a 0

− sin a cos a 0

0 0 1

wp1wp2wp3

, (7.10)

and expanding we get

cp1 = cos a wp1 − sin a wp2 + 0 wp3, (7.11)

cp3 = − sin a wp1 + cos awp2 + 0 wp3, (7.12)

cp3 = 0 wp10wp2 + 1 wp3. (7.13)

If we consider the basis vector e1w = (1 0 0)T , we see that eqn. 7.11, gives

cp1 = cos a × 1− sin a × 0 + 0× 0 = cos a × 1 = d, (7.14)

see in Figure 7.2 that this is correct, and the rest check out similarly.

Compare with point transformation If we compare the matrix in eqn. 7.10 with the point

rotation transformation in section 5.6.3, eqn. 5.43, we find

[vxvy

]=

[cos b − sin b

sin b cos b

] [uxuy

]. (7.15)

All this means is that rotating a point by an angle b is the same as rotating the frame of reference

by an equal negative angle — pretty obvious.

7.4.1 Rotation about other axes

As a consequence of what was said in the previous paragraph, we can say that the rotation part (top

left 3 × 3 matrix) of a homogeneous matrix transform (from one frame of reference to another)

is of the same form as those in eqns. 7.3, 7.4 and 7.5 with appropriate negation of the angle.

Remember sin−b = − sin b, but cos−b = cos b, so you change only the sin b terms.

7–6

Page 76: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

7.4.2 Include Translation between Frames

When there is translation between the frames we need to resort to homogeneous coordinates as

in eqns. 7.3, 7.4 and 7.5; so, to cwR in eqn. 7.8, we need to add a fourth row 0 0 0 1 and a fourth

column, the first three elements of which represent the position of the world (w) origin, Ow , in

camera coordinates.

Hence, see Figure 7.1,

cwR =

e1w · e1c e2w · e1c e3w · e1c d1e1w · e2c e2w · e2c e3w · e2c d2e1w · e3c e2w · e3c e3w · e3c d3

0 0 0 1

. (7.16)

Here, d = (d1 d2 d3)T , gives the coordinates of Ow in camera coordinates.

7.4.3 Transformation in the opposite direction

Transformation in the opposite direction (i.e. in the example, camera coordinates to world coordi-

nates) is simple, we just use the inverse of the matrix:

wc R = c

wR−1

.

We know that the inverse of the rotation part is given by its transpose, so we have,

wc R =

e1w · e1c e1w · e2c e1w · e3c e1e2w · e1c e2w · e2c e2w · e3c e2e3w · e1c e3w · e2c e3w · e3c e3

0 0 0 1

. (7.17)

Here, e = (e1 e2 e3)T , gives the coordinates of Oc in world coordinates.

7.4.4 Concatenation of Transformations between Frames

In many cases we may need to concatenate transformations between frames, e.g. sub-model to

model (as in a game character with sub-parts, model to world, the world to camera, etc. The

possibilities are maybe even greater in machine vision or robotics.

The good news is that we can simply compose transformations as

adR = a

bRbcR

cdR. (7.18)

And that’s really good news!

7–7

Page 77: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Chapter 8

Projections

8.1 Introduction

Three dimensional graphics defines a 3D virtual world; but display screens are 2D, hence the need

for projection — the 3D scene must be projected onto a 2D screen or window. There are two major

types of projection: (a) orthographic projection in which the projecting light rays travel parallel to

one another and to the viewing direction; (b) perspective projection in which the projecting light

rays meet at a point called the eye point.

Orthographic projection does not involve any perspective distortion — on the display, objects close

to the viewer look the same size as similarly sized objects far away from the viewer. Orthographic

projection does have its uses, but to put the reality in virtual reality we need perspective.

Perspective projection acts like a human eye, or a camera. Objects close to the viewer look larger

than similarly sized objects far away from the viewer. In camera work, the degree of perspective

distortion is determined by the field of view (FOV) angle; a wide angle lens (wide FOV and small

focal length) produces a lot of distortion, which is why it is not recommended to do portrait

photography using a wide angle lens. On the other hand, a telephoto lens (narrow field of view

and large focal length) produces the opposite effect — because in that case perspective distortion

is much less that we are used to with our eyes and so distances seem smaller; the latter telephoto

effect is called foreshortening.

On a normal 35mm SLR camera, a 50mm lens gives about the same perspective as our eyes.

Early paintings (1400s and 1500s) had very limited perspective or none at all; consequently the

paintings looked flat and unreal. By the 1600s painters (and mathematicians) began to work out

the perspective trick and in from the late 1600s to 1900 and lot or mathematical energy was

devoted to the topic, see (Kline 1967), (Kline 1972), (Stillwell 2002), (Eves 1990b), (Katz 1998).

I’m going to be brief in this chapter. For more on cameras, see (Dunn & Parberry

2002) and (Angel 2005), (Shreiner et al. 2006) (or the online version, see my web links

http://www.jgcampbell.com/links/opengl.html). For better diagrams see (Shreiner et al.

2006) (or the online version, see above) or any of the computer graphics books mentioned in the

main bibliography.

8–1

Page 78: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

8.2 Eyes and Cameras

[This section could do with better diagrams and description]

Figure 8.1 (from (Gonzalez & Woods 2002)) shows a simplified cross section of a human eye.

Note the lens and the light sensitive retina — a camera also has a lens and has light sensitive

sensors or film.

Figure 8.1: Cross section of the human eye.

Figure 8.2 (from (Gonzalez & Woods 2002)) shows image formation in a a human eye. A camera

operates similarly, replacing the retina with light sensitive sensors or film. Notice the centre of

projection in the lens where the projected rays all meet. A pinhole camera has no lens, but the

pinhole is the centre of projection.

Figure 8.2: Image formation in a human eye.

8–2

Page 79: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

A general camera-based digital image sensing arrangement is shown in Figure 8.3 ((Gonzalez &

Woods 2002)). The scene element, some distance from the camera lens, is projected onto the

image plane. At the image plane there is a mosaic of light sensitive sensors; these have the effect

of transforming the two- dimensional continuous image lightness function, fi(y , x), into a discrete

function, f ′[r, c ], where r(ow) and c(olumn) are the discrete spatial coordinates; eventually, f ′[.]

gets digitised to yield a digital image, f [r, c ].

Figure 8.3: Image acquisition system (camera).

8.3 Perspective Transformation

8.3.1 Introduction

We implement perspective projection using a perspective transformation. Here we describe the

perspective transformation used by OpenGL; DirectX uses a slightly different version, we mention

that. This section follows (Lengyel 2004); (vanVerth & Bishop 2004) has a comparable coverage

with more diagrams.

In its raw form, perspective transformation involves division; it is decidedly neither linear, see

section 5 nor affine, see section 6, and looks rather ugly, and so might not be expected to be

implementable by our beloved matrices. However, owing again to the marvel of homogeneous

coordinates, we are able to make it implementable by a matrix.

The essence of perspective projection is shown in Figure 8.4(a); a line PQ in the 3D world is

projected onto P’Q’ on the projection plane. C is the centre of projection. In orthographic

(parallel) projection, Figure 8.4(b) the rays PP’ and QQ’ are parallel to one another and to the

line of sight; being parallel they do not meet at a point.

Note: in cameras and in eyes, the projection plane is behind the centre of projection. In our virtual

camera in OpenGL or DirectX we can place the camera in front of the centre of projection; there

is no difference in the effect — except that now image objects do not appear upside down.

8–3

Page 80: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Figure 8.4: Projections: (a) perspective; (b) orthographic (parallel).

8.3.2 Geometry of Perspective

Figure 8.5 shows a horizontal cross-section of geometry of perspective projection; the vertical

cross-section would look similar and would show the x-axis in place of the y-axis. The z-axis is

pointing in the negative direction — in OpenGL the centre of projection is always at the origin and

pointing along the negative z-axis.

The projective plane is at a distance e in front of the centre of projection. A point P = (px , py , pz)

is projected onto (x, y ,−e).

Figure 8.5: Perspective projection, cross-section.

By similar triangles we have

y = −epy/pz . (8.1)

If we imagine a similar diagram for x , we have

x = −epx/pz . (8.2)

Also,

z = −e, (8.3)

8–4

Page 81: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

that is all z values get reduced to −e, rather like the simple orthographic projections in section 5.6.7

where projection onto the x-axis simply reduces the y value to 0 and projection onto the y-axis

reduces the x value to 0. Later, we’ll see that OpenGL does not squash z coordinates to one value,

and that it transforms them into a set of values that are useful for determining hidden surfaces

during rendering.

8.3.3 OpenGL glFrustum

The chief method of defining a perspective projection in OpenGL is to define a frustum of a pyramid

using glFrustum, see Figure 8.6; note it’s frustum, not frustrum.

Figure 8.6: Perspective view frustum volume defined by glFrustum.

glFrustum takes six arguments:

void glFrustum(GLdouble left, GLdouble right,

GLdouble bottom, GLdouble top,

GLdouble near, GLdouble far).

Respectively, these the left and right (x-axis), and the bottom and top (y-axis) extents of the field

of view; −near is the z position of the projection plane. In addition, rendering is limited to the

frustum defined by lef t, r ight, bottom, top, near, f ar ; anything outside is not rendered and these

form a 3D clipping region. In Figure 8.6 these are abbreviated l , r, b, t, n, f .

OpenGL maps the frustum given by l , r, b, t, n, f to the homogeneous clip space cube shown in

Figure 8.7. It maps: l 7→ −1, r 7→ +1, b 7→ −1, t 7→ +1

Also, to use in hidden surface removal, it retains mapped z coordinates; it maps z coordinates

thus: n 7→ −1, f 7→ +1; notice that this reverses the direction of the z axis.

8–5

Page 82: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Figure 8.7: Homogeneous clip space cube.

8.3.4 Derivation of Perspective Transformation

In Figure 8.6 the e of Figure 8.5 becomes n; consequently the simple raw projection eqns. 8.1 and

8.2 become

y = −npy/pz . (8.4)

For x , we likewise have

x = −npx/pz . (8.5)

Now, as noted in the previous subsection, OpenGL maps x = l 7→ x ′ = −1, x = r 7→ x ′ = +1

and y = b 7→ y ′ = −1, y = t 7→ y ′ = +1, see Figure 8.7. We can use a previously derived handy

formula, namely eqn. 5.61 repeated here as eqn. 8.6,

v = (u − u0)v1 − v0u1 − u0

+ v0, (8.6)

which maps u0 7→ v0 and u1 7→ v1, i.e. in the present case x = l 7→ x ′ = −1 and x = r 7→ x ′ = +1

and likewise for y , y ′.

For the x mapping, eqn. 8.6 gives

x ′ = (x − l)1− (−1)

r − l − 1, (8.7)

= (x − l)2

r − l − 1,

=2(x − l)− r + l

r − l ,

x ′ =2x − 2l − r + l

r − l .

So,

x ′ =2x − (r + l)

r − l . (8.8)

8–6

Page 83: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Substituting eqn. 8.5 into eqn. 8.8 gives,

x ′ =2n(−px

pz)− (r + l)

r − l , (8.9)

and there is a similar equation for y ′,

y ′ =2n(

−pypz

)− (t + b)

t − b . (8.10)

Thinking ahead to the required form, eqns. 8.9 and 8.10 can be rewritten

− x ′pz =2npx + (r + l)pz

r − l , (8.11)

and,

− y ′pz =2npy + (t + b)pz

t − b . (8.12)

Now pz has to be mapped; the problem here is that the rasterisation stage needs the reciprocal of

pz ( 1pz

) rather than pz so that we need z ′ = a( 1pz

) + b. Eqn. 8.6 is still usable if we define s = 1pz

and define the mappings s = −1n7→ z ′ = −1 and s = −1

f7→ z ′ = +1, so eqn. 8.6 gives

z ′ =( 1pz

+ 1n

)(1 + 1)

(−1f

+ 1n

)− 1, (8.13)

=2 f npz

+ 2f

−n + f− 1,

=−2f n

(−1pz

)+ 2f

f − n ,

−z ′pz =−2f n − 2f pz + pz f − pzn

f − n + pz ,

and finally,

− z ′pz =−pz(f + n)− 2f n

f − n . (8.14)

The coefficients of our projective transformation are in eqns. 8.11, 8.12 and 8.14, where we have

avoided the division by pz .

From the projected 3D point p′ = (x ′, y ′, z ′) (the mapped image of (px , py , pz)) we now create the

‘homogeneous’ coordinates p′ = (−x ′pz ,−y ′pz ,−z ′pz ,−pz); note the −pz in the w component.

Then summarise eqns. 8.11, 8.12 and 8.14 as

− x ′pz =2n

r − l px +r + l

r − l pz , (8.15)

− y ′pz =2n

t − bpy +t + b

t − bpz , (8.16)

and

− z ′pz = −f + n

f − npz −2nf

f − n . (8.17)

8–7

Page 84: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

The whole projective transformation can now be written in terms of a matrix multiplication and

homogeneous coordinates,−x ′pz−y ′pz−z ′pzw ′

=

2nr−l 0 r+l

r−l 0

0 2nt−b

t+bt−b 0

0 0 − f+nf−n −

2nff−n

0 0 −1 0

pxpypz1

. (8.18)

Recall glFrustum, where we now use the same symbols as in eqn. 8.18:

void glFrustum(GLdouble l, GLdouble r,

GLdouble b, GLdouble t, GLdouble n, GLdouble f).

Figure 8.8 (Figure 3-2 of (Shreiner et al. 2006)) shows the final transformation stages in full

context.

Figure 8.8: Vertex transformation pipeline.

8–8

Page 85: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

8.3.5 Orthographic Projection

In an orthographic or parallel projection, the projection rays are parallel to one another and to

the camera viewing direction. In addition lack of perspective distortion means that (in OpenGL)

true z coordinates can be interpolated linearly (rather than reciprocal (1/z) values). This from

(Lengyel 2004).

Consequently all that needs to be done for x and y is a mapping as given by eqn. 8.8 for x ,

x ′ =2x − (r + l)

r − l , (8.19)

=2x

r − l −r + l

r − l , (8.20)

and the same for y ,

y ′ =2x

t − b −t + b

t − b . (8.21)

The z coordinate mapping is −f → −1,−n → +1, so,

z ′ =−2z

f − n −f + n

f − n . (8.22)

We note that eqns. 8.20, 8.21 and 8.22 represent an affine transformation, i.e. scale plus

translate. Their matrix representation is given by eqn. 8.23; this is the projection matrix generated

by OpenGL function glOrtho:

void glOrtho(GLdouble left, GLdouble right,

GLdouble bottom, GLdouble top,

GLdouble near, GLdouble far).

x ′

y ′

z ′

w ′

=

2r−l 0 0 − r+l

r−l0 2

t−b 0 − t+bt−b

0 0 − 2f−n −

f+nf−n

0 0 0 1

pxpypz1

. (8.23)

8–9

Page 86: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Chapter 9

Quaternions

[This chapter is a bit long winded; this is because it is taken from an article written as an account

of the origins of quaternions, (Campbell 2005).]

9.1 Introduction

Quaternions are are an example hypercomplex numbers, i.e. they are an extension of complex

numbers, see section 5.9. Just as complex numbers give us a neat formula for rotating 2D vectors

and points, see eqn. 5.82, quaternions provide a neat way to rotate 3D vectors and points.

Hamilton’s treatment of complex numbers as pairs of reals, see section 5.9, led him automatically

to triples.

Figure 9.1 shows that triples are fine for describing position, e.g. P = (x1, y1, z1), and fine for

translation, Q = (x1 + tx , y1 + ty , z1 + tz). And this works in any dimensional space, three-, four-,

. . . four-dimensional space.

But what about our dilative rotation that was provided by complex multiplication?

In itself, 3D dilative rotation is fine, see (Needham 1997) p. 43 for a discussion and references;

we have closure. Problems start to arise when we consider commutativity ; dilations (scalings) and

translations do commute, but (in 3D) rotations do not commute; in operator language U ◦ V 6=V ◦ U.

For example, Ry(45o) ◦Rx(90o) 6= Rx(90o) ◦Ry(45o). On the other hand, as we will see, absence

of commutation could be tolerated.

However, applying glorious hindsight, there is another obstacle. In spite of the fact that specifica-

tion of a point in 3D requires just three numbers, a triple, a dilative rotation in 3D requires four

numbers: one for the scaling, one for the angle of rotation, and two to specify the axis of rotation

(the latter not obvious, but think latitude and longitude). On the other hand maybe the scaling

part could somehow be discarded to lose one of the degrees of freedom.

Another difficulty, the impossibility of the multiplicative absolute value property for triples, see

section 9.2.8, definitely meant that Hamilton’s work during 1830–1843 along the lines of triples

was doomed to failure.

9–1

Page 87: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Figure 9.1: Triples for 3D. Position, P = (x1, y1, z1); can be used for translation, Q = (x1+tx , y1+

ty , z1 + tz).

Eventually on 16th October 1843 as he was walking along the Royal Canal, it dawned on Hamilton

that he needed not triples but quadruples — quaternions.

Moving quickly to terminology and symbolism that emerged later, a quaternion q is defined as:

q = [w, v] = [w + x i + y j + zk]. (9.1)

Here v is a vector and w a scalar, both these terms were introduced by Hamilton.

9.2 The Algebra of Quaternions

Here we mostly follow (Vince 2001) which gives a nice concise treatment; in spite of being written

80 years ago, (Klein 2004/1925a) is equally easy to follow.

9.2.1 Addition

Like complex numbers and vectors we add q1 = [w1, v1] = [w1+x1i+y1j+z1k] and q2 = [w2, v2] =

[w2 + x2i + y2j + z2k],

as

q1 + q2 = [w1 + w2 + (x1 + x2)i + (y1 + y2)j + (z1 + z2)k]. (9.2)

9–2

Page 88: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

9.2.2 Multiplication

Just like we need multiplication tables for 1, i in complex numbers (1 ·1 = 1, 1 · i = i , i ·1 = i , i · i =

−1), Hamilton needed multiplication tables for 1, i, j, k:

i2 = j2 = k2 = ijk = −1, (9.3)

jk = −kj = i,

ki = −ik = j,

ij = −ji = k.

It was anti-commutativity, e.g. jk = −kj that Hamilton accepted with most reluctance. As he

passed, Hamilton scrawled eqns. 9.4 on Broombridge; today, a plaque on the bridge commemorates

the event, see Fig. 9.2.

Figure 9.2: Plaque on Broombridge (Royal Canal, Dublin).

q1q2 = [w1 + x1i + y1j + z1k][w2 + x2i + y2j + z2k] (9.4)

= [(w1w2 − (x1x2 + y1y2 + z1z2)

+ (w1x2 + w2x1 + y1z2 − y2z1)i

+ (w1y2 + w2y1 + z1x2 − z2x1)j

+ (w1z2 + w2z1 + x1y2 − x2y1)k,

which can be written in terms of vector scalar and cross products as

p = q1q2 (9.5)

= [wp, vp]

= [(w1w2 − v1 · v2, w1v2 + w2v1 + v1 × v2].

If we set the w1, w2 (scalar parts) to zero leaving us with x1i + y1j + z1k and x2i + y2j + z2k, we

have

9–3

Page 89: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

p = q1q2 (9.6)

= [−v1 · v2 + v1 × v2],

that is the negative of the scalar product of v1, v2, see section 3.4, and the vector product of

v1, v2, see section 3.5.

It was the latter two parts that interested Gibbs (and later Heaviside) and led him during 1880–

1900 to extract vector analysis from quaternion algebra — much to the consternation of the

quaternionists.

The scalar product of two vectors v1 and v2 is given by

v1 · v2 = x1x2 + y1y2 + z1z2, (9.7)

and the cross product by

v1 × v2 = (y1z2 − y2z1)i + (z1x2 − z2x1)j + (x1y2 − x2y1)k. (9.8)

9.2.3 Inverse

q = [w, v] = [w + x i + y j + zk]. (9.9)

q−1 =[w − (x i + y j + zk)]

(| q |)2 =q∗

(| q |)2 , (9.10)

where | q |=√w 2 + x2 + y 2 + z2, and we term q∗ = [w − (x i + y j + zk)] the conjugate of q. The

similarity with inverse complex number and complex conjugate, eqn. 5.79 is clear.

This gives us unique inverse of multiplication — division.

9.2.4 Scalar Products — no inverse

We can contrast vector scalar product u ·v which as no unique inverse. In Fig. 9.3 we see u ·v = a

for a whole family of v, v′, . . . . Hence a/u is satisfied by any of an infinity of v, v′ . . . that project

onto u an amount a.

9.2.5 Point as Quaternion

If we represent the point P = (x, y , z) as a position vector, we can represent it as the quaternion

p = [0 + x i + y j + zk]. (9.11)

9–4

Page 90: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Figure 9.3: No unique inverse of u · v = a.

9.2.6 Rotation Quaternion

The quaternion which represents a rotation of φ about the axis n = (n1 n2 n3)T is given by

q = [cosφ

2+ sin

φ

2(n1i + n2j + n3k)] = [cos

φ

2+ sin

φ

2n]. (9.12)

q is a unit quaternion so | q |= 1; also n is a unit vector.

See (Campbell 2005) for a discussion of the origins of eqn. 9.12.

Eqn. 9.13 gives the equation for quaternion rotation, rotated point is p′,

p′ = qpq−1. (9.13)

9.2.7 Rotation — an example

From (Vince 2001).

We want to rotate the point P = (0, 1, 1) by 90o about the y-axis, see Fig. 9.4.

1. The point P is p = [0 + 0i + 1j + 1k];

2. The axis of rotation (y -axis) is given by n = 0i + 1j + 0k) = (0 1 0)T ;

3. The rotation quaternion is q = [cos 45o + sin 45on1i + sin 45on2j + sin 45on3k]

= [cos 45o + 0i + sin 45o j + 0k]

= [cos 45o + sin 45o j];

9–5

Page 91: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Figure 9.4: Rotation of the point P = (0, 1, 1) by 90o about the y-axis (0i + 1j + 0k); the result

is P ′ = (1, 1, 0).

4. Likewise, the inverse rotation quaternion is q−1 = [cos 45o − sin 45o j]; since a rotation

quaternion is unit, the denominator of eqn. 9.10 is 1;

5. Compute p′ = qpq−1:

(a)

qp = [cos 45o + sin 45o j]

×[0 + 0i + 1j + 1k]

= [cos 45o j + cos 45ok

+ sin 45o j2 + sin 45o jk

= [− sin 45o + sin 45o i + cos 45o j + cos 45ok],

recalling the multiplication rules for j2 = −1 and jk = i in eqn. 9.4;

(b)

(qp)q−1 = [− sin 45o + sin 45o i + cos 45o j + cos 45ok]

×[cos 45o − sin 45o j]

= − sin 45o cos 45o + sin 45o sin 45o j

+ sin 45o cos 45o i− sin 45o sin 45o ij

+ cos 45o cos 45o j− cos 45o sin 45o j2

+ cos 45o cos 45ok− cos 45o sin 45okj

= (− sin 45o cos 45o + cos 45o sin 45o)

+(sin 45o cos 45o + cos 45o sin 45o)i

+(sin 45o sin 45o + cos 45o cos 45o)j

+(cos 45o cos 45o − sin 45o sin 45o)k

= [0, (1, 1, 0)],

9–6

Page 92: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

again noting multiplication rules for j2 = −1, ij = k, and kj = −i and sin 45o =

cos 45o = 1√2

.

6. So P ′ = (1, 1, 0). Fig. 9.4 shows that this is the correct answer.

9.2.8 Multiplicative Absolute Value

(Stillwell 2002) p. 389, (Klein 2004/1925a), p. 66.

Recall eqn. 5.80 on the multiplicative absolute value of complex numbers. Quite correctly, Hamilton

was guided by this goal for what turned out to be his quaternions — but what for many years he

hoped to be triples.

If we take eqn. 9.5:

p = q1q2 (9.14)

= [wp, vp]

= [(w1w2 − v1 · v2, w1v2 + w2v1 + v1 × v2],

the equation corresponding to eqn. 5.80 for quaternions is

(w 21 + x21 + y 21 + z21 )(w 22 + x22 + y 22 + z22 ) = w 2p + x2p + y 2p + z2p (9.15)

= (w1w2 − x1x2 − y1y2 − z1z2)2

+(w1x2 + x1w2 + y1z2 − z1y2)2

+(w1y2 − x1z2 + y1w2 + z1x2)2

+(w1z2 + x1y2 − y1x2 + z1w2)2.

Euler (in 1748) had proved this (that the product of sums of four squares is a sum of four squares)

and he and Legendre has used it. Legendre had proved that the same for triples is in general

impossible (in general the product of sums of three squares is not a sum of three squares).

It was only in 1844 that Hamilton’s friend Graves realised the impact of this proof. So, the search

for a solution based on triples was certainly futile. It seems that the property is valid only for

dimensionalities 1, 2, 4, and 8.

Incidentally, Hamilton introduced the term tensor for the sums of squares contained in eqn. 9.15.

9.3 Why use Quaternions?

See (Dunn & Parberry 2002).

9–7

Page 93: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

• Four real numbers specify a rotation; nine required for a rotation matrix; on the other hand

Euler angle three. Maybe not a big issue these days, but consider a five minute animation of

an object with 20 rotating parts and the animation needing updating every 25th of a second:

5 × 60 × 20 × 25 × n = 150, 000 × n real numbers where n = 4 for quaternions and n = 9

for rotation matrices;

• Smooth interpolation — probably the greatest reason for using quaternions;

• Fast concatenation of rotations; rotation matrix concatenation is easy too, but not Euler

angles;

• Fast inversion of rotations; rotation matrix inversion is easy too, but not Euler angles;

• No gimbal lock? Opinion is divided — maybe gimbal lock reappears when we apply the

rotation to real actuators?

9.4 Conversions to and from Quaternions etc.

• Euler angles to and from rotation matrices;

• Quaternions to and from rotation matrices;

• Quaternions to and from Euler angles.

See (Dunn & Parberry 2002) and Appendix E.

9.5 Software

Appendix E contains software implementations in Java.

9–8

Page 94: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Appendix A

Abstract Algebra on a Set S

Thanks to Ken Adams (Adams 2005) for this. See also (Eves 1965/1990a) and (MacLane &

Birkoff 1999). The properties are cumulative.

Semi-group

Closed under + a, b ∈ S, a + b ∈ S,

Associative + (a + b) + c = a + (b + c).

Monoid

Identity ∃0 ∈ S, a + 0 = 0 + a = a.

Group

Inverse ∀a ∈ S, ∃a′, a + a′ = a′ + a = 0.

Abelian Group

Commutative + a + b = b + a.

Ring

Closed under multiplication (·) a, b ∈ S, a · b ∈ S,

Multiplication is associative (a · b) · c = a · (b · c),

Multiplication is distributive over addition a · (b + c) = a · b + a · c ,

Addition is distributive over multiplication (a + b) · c = a · c + b · c .

Integral Domain

Multiplication is commutative a · b = b · a,

Multiplicative identity ∃1 ∈ S, 1 · a = a · 1 = a,

No divisors of 0 a · b = 0⇒ a = 0 or b = 0; hence, a · b = a · c ⇒ b = c .

Field

Multiplication inverse ∀a 6= 0 ∃a−1 · a = a · a−1 = 1; hence division ab

= a · b−1.

Note: a field is a ring where S/{0} is a multiplicative group under ·.

A–1

Page 95: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Appendix B

Vectors and 2D Transformations in Java

B.1 Vector2DH.java

/**

* Vector2DH.java

* 3D homogeneous vector

* @author j.g.c.

* version 1.0; 2008-01-08, from Vector2D.java

* based on Vector4D.java

*/

import java.io.*; import java.awt.geom.*;

import javax.swing.*;

import java.awt.*;

public class Vector2DH –

double[] d; // package visible

public static final double EPS = 1.0E-20; // very small

public static final int N = 3;

/**

* void constructor

*/

public Vector2DH()–

d= new double[N];

˝

/**

* Constructor from double array

* @param d array

*/

public Vector2DH(double[] dd)–

this();

int n = dd.length;

d[2] = 1.0; // unless overridden by dd

if(n¿ N)n = N;

B–1

Page 96: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

for(int i= 0; i¡ n; i++)d[i]= dd[i];

˝

/**

* Constructor from two values

* @params components

*/

public Vector2DH(double x, double y)–

this();

d[0]= x; d[1]= y; d[2] = 1.0;

˝

/**

* Constructor from two values

* @params components

*/

public Vector2DH(double x, double y, double w)–

this();

d[0]= x; d[1]= y; d[2] = w;

˝

/**

* from length and angle

* cannot make constructor, conflicts with

* public Vector2DH(double x, double y)

* @params length, angle

*/

public static Vector2DH fromLengthAngle(double len, double ang)–

double x = len*Math.cos(ang);

double y = len*Math.sin(ang);

return new Vector2DH(x, y);

˝

/**

* sets all elements to parameter

* @param value

*/

public void setAll(double val)–

for(int i= 0; i¡ N; i++)d[i]= val;

˝

/**

* sets element index i to parameter

* @param val value

* @param index index

*/

public void set(int i, double val)–

d[i]= val;

˝

/**

B–2

Page 97: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

* sets element 0 to parameter

* @param val value

*/

public void setX(double val)–

d[0]= val;

˝

/**

* sets element 1 to parameter

* @param val value

*/

public void setY(double val)–

d[1]= val;

˝

/**

* sets element 2 to parameter

* @param val value

*/

public void setW(double val)–

d[2]= val;

˝

/**

* gets element index i

* @param index index

*/

public double get(int i)–

return d[i];

˝

/**

* gets element index 0

* @return value of X

*/

public double getX()–

return d[0];

˝

/**

* gets element index 1

* @return value of Y

*/

public double getY()–

return d[1];

˝

/**

* returns sum of this and parameter

B–3

Page 98: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

* @param v vector to be added to this

* @return sum

*/

public Vector2DH add(Vector2DH v)–

Vector2DH v1= new Vector2DH();

for(int i= 0; i¡ N; i++)v1.d[i]= this.d[i] + v.d[i];

return v1;

˝

/**

* adds parameter to this

* @param v vector to be added

*/

public void addTo(Vector2DH v)–

for(int i= 0; i¡ N; i++)this.d[i]= this.d[i] + v.d[i];

˝

/**

* static add

* @param v1, v2 vectors to be added

* @return sum

*/

public static Vector2DH add(Vector2DH v1, Vector2DH v2)–

System.out.println(”v1 = ”+ v1);

System.out.println(”v2 = ”+ v2);

Vector2DH v= new Vector2DH(v1.d[0], v1.d[1], v1.d[2]);

v.addTo(v2);

System.out.println(”v = ”+ v);

return v;

˝

/**

* static scalar/dot product; note: w ignored

* @param v1, v2 vectors to be scalar multiplied

* @return sum

*/

public static double dot(Vector2DH v1, Vector2DH v2)–

return v1.d[0]*v2.d[0] + v1.d[1]*v2.d[1];

˝

/**

* static angle (between two vectors)

* @param v1, v2 vectors to be scalar multiplied

* @return sum

*/

public static double angle(Vector2DH v1, Vector2DH v2)–

double len1 = v1.length();

double len2 = v2.length();

B–4

Page 99: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

assert len1 ¿ EPS;

assert len2 ¿ EPS;

return Math.acos(dot(v1, v2)/(len1*len2));

˝

/**

* static add of Point2D and Vector2DH

* @param p, v Point2D and Vector2DH to be added

* @return p + v

*/

public static Point2D add(Point2D p, Vector2DH v)–

return new Point2D.Double(p.getX() + v.getX(),

p.getY() + v.getY() );

˝

/**

* make a Point2D from a Vector2DH

*/

public Point2D toPoint2D()–

return new Point2D.Double(getX(), getY() );

˝

/**

* returns difference of this and parameter

* @param v vector to be subtracted this

* @return difference

*/

public Vector2DH sub(Vector2DH v)–

Vector2DH v1= new Vector2DH();

for(int i= 0; i¡ N; i++)v1.d[i]= this.d[i] - v.d[i];

return v1;

˝

/**

* returns this scaled by s

* @param s scale

* @return scaled result

*/

public Vector2DH scale(double s)–

Vector2DH v1= new Vector2DH();

for(int i= 0; i¡ N; i++)v1.d[i] = s*this.d[i];

return v1;

˝

/**

* returns length of vector; note: ignores w

* @return length

*/

public double length()–

B–5

Page 100: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

double len= 0.0;

len= d[0]*d[0] + d[1]*d[1];

return Math.sqrt(len);

˝

/**

* returns angle of vector

* @return angle

*/

public double angle()–

double ang = Math.atan2(d[1], d[0]);

if(ang ¡ 0.0) ang = ang + Math.toRadians(360.0);

return ang;

˝

/**

* creates formatted String; note: ignores w

* @return string

*/

public String toString()–

StringBuffer s= new StringBuffer(”(”);

for(int i= 0; i¡ N-1; i++)–

s.append(String.format(”%5.1f”, d[i]) );

if(i!= N-2)s.append(”, ”);

else s.append(”)”);

˝

return s.toString();

˝

/**

* creates formatted String (polar format)

* @return string

*/

public String toStringPolar()–

StringBuffer s= new StringBuffer(”[”);

s.append(String.format(”%5.1f”, length()) );

s.append(”, ”);

s.append(String.format(”%5.1f”, Math.toDegrees(angle() ) ) );

s.append(”]”);

return s.toString();

˝

public void draw(Point2D ps, Color c, Graphics2D g2,

String s, int dx, int dy)–

RenderingHints hPrev = g2.getRenderingHints();

RenderingHints hints = new RenderingHints(

B–6

Page 101: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

RenderingHints.KEY˙ANTIALIASING,

RenderingHints.VALUE˙ANTIALIAS˙ON);

g2.setRenderingHints(hints);

Point2D pe = new Point2D.Double(ps.getX() + getX(), ps.getY() + getY());

Line2D line = new Line2D.Double(ps, pe);

Color cPrev = g2.getColor();

g2.setColor(c); // exactly the same as setPaint

g2.draw(line);

// arrowhead

Vector2DH va1 = Vector2DH.fromLengthAngle(

6.0, angle() + Math.toRadians(160.) );

Point2D pe1 = Vector2DH.add(pe, va1);

Vector2DH va2 = Vector2DH.fromLengthAngle(

6.0, angle() + Math.toRadians(200.) );

Point2D pe2 = Vector2DH.add(pe, va2);

Line2D l1 = new Line2D.Double(pe, pe1);

g2.draw(l1);

Line2D l2 = new Line2D.Double(pe, pe2);

g2.draw(l2);

// draw text, first must invert axes

AffineTransform at = new AffineTransform();

at.scale(1, -1); /* and flip y axis back again for text

also note the ’-’ on the y below */

g2.transform(at);

// text beyond arrowpoint of vector

double ang = angle();

double dang = Math.abs(Math.toDegrees(angle()) );

int offset = 0;

if(dang ¿ 150.0 && dang ¡ 210.0) offset = 15;

Vector2DH va3 = Vector2DH.fromLengthAngle(5.0, ang);

Point2D pe3 = Vector2DH.add(pe, va3);

g2.drawString(s, (int)pe3.getX() - offset + dx,

-((int)pe3.getY() + dy));

// and transform back again

g2.transform(at);

g2.setColor(cPrev);

g2.setRenderingHints(hPrev);

˝

public void draw(Point2D ps, Color c, Graphics2D g2, String s)–

draw(ps, c, g2, s, 0, 0);

˝

public void draw(Point2D ps, Color c, Graphics2D g2)–

draw(ps, c, g2, ””, 0, 0);

˝

B–7

Page 102: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

˝

B.2 Test Program for Vector2DH.java

/**

* Vector2DHT1.java

* tests Vector2DH

* @author j.g.c.

* version 1.0; 2008-01-07, from Vector2DT1

*/

import java.io.*;

public class Vector2DHT1 –

/**

* Constructor

*/

public Vector2DHT1()–

double[] d= –1.0, 2.0˝;

Vector2DH x1= new Vector2DH(d);

System.out.println(”Vector2DHT1”);

System.out.println(”x1 = ”+ x1.toString());

Vector2DH x2= new Vector2DH();

x2.setAll(10.0);

System.out.println(”x2 = ”+ x2.toString());

Vector2DH x3 = x2.add(x1);

System.out.println(”x3 = x2.add(x1): ”+ x3.toString());

Vector2DH x4 = x3.scale(0.25);

System.out.println(”x4 = x3.scale(0.25): ”+ x4.toString());

double len = x1.length();

System.out.println(”len = x1.length(): ”+ len);

˝

/** The main method constructs the test

*/

public static void main(String[] args)

– new Vector2DHT1(); ˝

˝

B–8

Page 103: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

B.3 Transform2D.java

/**

* Transform2D.java

* Affine transforms for 2D vector

* @author j.g.c.

* version 2.0; 2008-01-06; now uses homogeneous form

* version 1.0; 2005-10-08

* based partly on Transform4D.java

*/

import java.io.*;

public class Transform2D –

private double[][] m; // transform matrix

public static final int N = 3;

private static final double eps = 1.0e-20;

/**

* void constructor

*/

public Transform2D()–

m = new double[N][N];

setIdentity();

˝

/**

* copy constructor

*/

public Transform2D(Transform2D other)–

m = new double[N][N];

for(int r = 0; r¡ N; r++)–

for(int c = 0; c¡ N; c++)–

m[r][c] = other.m[r][c];

˝

˝

˝

/**

* Constructor from double arrays

* @param mm matrix array

* @param tt translation array

*/

public Transform2D(double[][] mm)–

this();

for(int r = 0; r¡ N; r++)–

B–9

Page 104: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

for(int c = 0; c¡ N; c++)–

m[r][c]= mm[r][c];

˝

˝

˝

/**

* sets all elements to parameter

* @param val

*/

public void setAll(double val)–

for(int r = 0; r¡ N; r++)–

for(int c = 0; c¡ N; c++)–

m[r][c] = val;

˝

˝

˝

/**

* sets identity matrix and zero translation

*/

public void setIdentity()–

setAll(0.0);

for(int i = 0; i¡ N; i++)–

m[i][i] = 1.0;

˝

˝

/**

* sets translation transform

* @param t translation as a vector

*/

public void setTrans(Vector2DH tt)–

setIdentity();

m[0][2] = tt.getX();

m[1][2] = tt.getY();

˝

/**

* sets translation

* @params tx x tx component

* @params ty y tx component

*/

public void setTrans(double tx, double ty)–

setIdentity();

m[0][2] = tx;

m[1][2] = ty;

˝

B–10

Page 105: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

/**

* sets rotation

* @param theta angle (radians)

*/

public void setRot(double theta)–

setIdentity();

double cos = Math.cos(theta);

double sin = Math.sin(theta);

m[0][0] = cos;

m[0][1] = -sin;

m[1][0] = sin;

m[1][1] = cos;

// zero translation

m[0][2] = 0.0;

m[1][2] = 0.0;

˝

/**

* sets scaling

* @param s scale components as a vector

*/

public void setScale(Vector2DH s)–

setIdentity();

for(int i= 0; i¡ N; i++)m[i][i]= s.get(i);

˝

/**

* sets scaling

* @params sx x scale component

* @params sy y scale component

*/

public void setScale(double sx, double sy)–

setIdentity();

m[0][0]= sx;

m[1][1]= sy;

˝

/**

* returns pre-multiplication of this*parameter

* @param a a vector to be multiplied by this

* @return product v = this*u

*/

public Vector2DH apply(Vector2DH u)–

Vector2DH v = new Vector2DH();

double dot;

for (int r = 0; r ¡ N; r++) –

dot = 0.0;

for (int c = 0; c ¡ N; c++) –

B–11

Page 106: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

dot += m[r][c]*u.d[c];

˝

v.set(r, dot);

˝

return v;

˝

public Vector2DH transform(Vector2DH u)–

return apply(u);

˝

/**

* composition

* returns pre-multiplication of parameter*this

* right translations rotated and added to left translations

* *** 2005-10-08 check

* @param a transform to be composed with this

* @return product b = a*this

*/

public Transform2D compose(Transform2D a)–

Transform2D b = new Transform2D();

double dot;

for (int r = 0; r ¡ N; r++) –

for (int c = 0; c ¡ N; c++) –

dot = 0.0;

for (int i = 0; i ¡ N; i++) –

dot += a.m[r][i]*this.m[i][c];

˝

b.m[r][c] = dot;

˝

˝

return b;

˝

/**

* static multiplication

* @param a transform

* @param b transform

* @return product a*b

*/

public static Transform2D mult(Transform2D a, Transform2D b)–

Transform2D e = new Transform2D();

double dot;

for (int r = 0; r ¡ N; r++) –

for (int c = 0; c ¡ N; c++) –

dot = 0.0;

for (int i = 0; i ¡ N; i++) –

dot += a.m[r][i]*b.m[i][c];

˝

e.m[r][c] = dot;

B–12

Page 107: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

˝

˝

return e;

˝

/**

* creates formatted String

* @return string

*/

public String toString()–

StringBuffer s= new StringBuffer(”[”);

for(int r= 0; r¡ N-1; r++)–

s.append(”(”);

for(int c= 0; c¡ N; c++)–

s.append(String.format(”%8.3f”, m[r][c]) );

if(c!= N-1)s.append(”, ”);

else s.append(”)”);

˝

if(r!= N-2)s.append(”“n”);

˝

s.append(”]“n”);

return s.toString();

˝

˝

B.4 Test for Transform2D.java

/**

* Transform2DT1.java

* tests Transform2D and Vector2DH

* @author j.g.c.

* version 1.1; 2005-10-08, 2008-01-06

* version 2.0; 2008-01-06, homogeneous vectors Vector2DH

* from Transform4DT1.java

*/

import java.io.*;

public class Transform2DT1 –

/**

* Constructor

*/

public Transform2DT1()–

System.out.println(”Transform2DT1”);

B–13

Page 108: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

double[] d= –1.0, 2.0˝;

Vector2DH va= new Vector2DH(d);

System.out.println(”va = ”+ va.toString());

Transform2D f = new Transform2D();

f.setIdentity();

System.out.println(”f.setIdentity(): “n”+ f.toString());

Transform2D g = new Transform2D();

g.setIdentity();

System.out.println(”g.setIdentity(): “n”+ g.toString());

Transform2D fg= Transform2D.mult(f,g);

System.out.println(”fg= Transform2D.mult(f,g) (g identity): “n”+ fg.toString());

Vector2DH vb = f.transform(va);

System.out.println(”vb = f.apply(va): ”+ vb.toString());

double[] d1= –0.0, 1.0˝;

Vector2DH v0= new Vector2DH(d1);

System.out.println(”v0 = ”+ v0.toString());

double[] dt= –2.0, 3.0˝;

Vector2DH t= new Vector2DH(dt);

System.out.println(”t = ”+ t.toString());

Transform2D h = new Transform2D();

h.setTrans(t);

System.out.println(”h.setTrans(t): “n”+ h.toString());

Vector2DH v1 = h.transform(v0);

System.out.println(”v1 = h.transform(v0): “n”+ v1.toString());

//90 degree rotation of (1,0) should make (0,1)

Transform2D R90 = new Transform2D();

R90.setRot(Math.toRadians(90.0));

System.out.println(”R90.setRot(Math.toRadians(90.0)): “n”+ R90.toString());

Vector2DH v10 = new Vector2DH(1.0, 0.0);

System.out.println(”v10 = ”+ v10.toString());

v1= R90.transform(v10);

System.out.println(”v1 = R90.transform(v10): “n”+ v1.toString());

System.out.println(”“n“n---- Rotation followed by translation ...”);

Transform2D R30 = new Transform2D();

R30.setRot(Math.toRadians(30.0));

System.out.println(”R30.setRot(Math.toRadians(30.0)): “n”+ R30.toString());

Vector2DH v21 = new Vector2DH(2.0, 1.0);

System.out.println(”v21 = ”+ v21.toString());

B–14

Page 109: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

v1= R30.transform(v21);

System.out.println(”v1 = R30.transform(v21): “n”+ v1.toString());

Transform2D T12 = new Transform2D();

T12.setTrans(new Vector2DH(1.0, 2.0));

System.out.println(”T12.setTrans(new Vector2DH(1.0, 2.0)): “n”

+ T12.toString());

Vector2DH v2 = T12.transform(v1);

System.out.println(” v2 = T12.transform(v1): ”+ v2.toString());

System.out.println(”“n“n-- Multiplying translation * rotation ...”);

// for incorrect order see Transform4DT1

Transform2D TR = new Transform2D();

TR = Transform2D.mult(T12, R30); // this is T12*R30

System.out.println(”RT = Transform2D.mult(T12, R30): “n”+ TR.toString());

System.out.println(”v21 = ”+ v21.toString());

Vector2DH v3 = TR.transform(v21);

System.out.println(” v3 = g.transform(v21): ”+ v3.toString());

System.out.println(”“n“n---- Translation followed by rotation...”);

System.out.println(”T12 : “n”

+ T12.toString());

System.out.println(”v21 = ”+ v21.toString());

Vector2DH v4 = T12.transform(v21);

System.out.println(”v4 = T12.transform(v1): ”+ v4.toString());

R30 = new Transform2D();

R30.setRot(Math.toRadians(30.0));

//Vector2DH v21 = new Vector2DH(2.0, 1.0);

System.out.println(”v4 = ”+ v4.toString());

Vector2DH v5= R30.transform(v4);

System.out.println(” v5 = R30.transform(v4): ”+ v5.toString());

System.out.println(”“n“n-- Multiplying rotation * translation ...”);

// for incorrect order see Transform4DT1

Transform2D RT = new Transform2D();

RT = Transform2D.mult(R30, T12); // this is T12*R30

System.out.println(”RT = Transform2D.mult(R30, T12): “n”+ RT.toString());

System.out.println(”v21 = ”+ v21.toString());

Vector2DH v6 = RT.transform(v21);

System.out.println(” v6 = g.transform(v21): ”+ v6.toString());

˝

/** The main method constructs the test

*/

public static void main(String[] args)

– new Transform2DT1(); ˝

B–15

Page 110: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

˝

B–16

Page 111: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Appendix C

3D Affine Transformations in Java

C.1 Homogeneous 3D Vector — Vector4D.java

package com.jgcampbell.graphicsmaths;

/**

* Vector4D.java

* 4D homogeneous components vector

* @author j.g.c.

* version 1.0; 2005-03-20

* based partly on Brackeen, Developing Games in Java, p. 340 ...

* and Lengyel, Mathematics for 3D Game Programming and Computer

* Graphics, 2nd ed.

*/

import java.io.*;

public class Vector4D –

double[] d; // package visible

public static final int N = 4;

/**

* void constructor

*/

public Vector4D()–

d= new double[N];

˝

/**

* Constructor from double array

* @param d array

*/

public Vector4D(double[] dd)–

this();

for(int i= 0; i¡ N; i++)d[i]= dd[i];

C–1

Page 112: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

˝

/**

* Constructor from double array

* @params components

*/

public Vector4D(double x, double y, double z, double w)–

this();

d[0]= x; d[1]= y; d[2]= z; d[3]= w;

˝

/**

* sets all elements to parameter

* @param value

*/

public void setAll(double val)–

for(int i= 0; i¡ N; i++)d[i]= val;

˝

/**

* returns sum of this and parameter

* @param v vector to be added to this

* @return sum

*/

public Vector4D add(Vector4D v)–

Vector4D v1= new Vector4D();

for(int i= 0; i¡ N; i++)v1.d[i]= this.d[i] + v.d[i];

return v1;

˝

/**

* returns difference of this and parameter

* @param v vector to be subtracted this

* @return difference

*/

public Vector4D sub(Vector4D v)–

Vector4D v1= new Vector4D();

for(int i= 0; i¡ N; i++)v1.d[i]= this.d[i] - v.d[i];

return v1;

˝

/**

* returns this scaled by s

* @param s scale

* @return scaled result

*/

public Vector4D scale(double s)–

Vector4D v1= new Vector4D();

for(int i= 0; i¡ N; i++)v1.d[i] = s*this.d[i];

C–2

Page 113: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

return v1;

˝

/**

* returns length of vector

* @return length

*/

public double length()–

double len= 0.0;

for(int i= 0; i¡ N; i++)len+= d[i]*d[i];

return Math.sqrt(len);

˝

/**

* creates formatted String

* @return string

*/

public String toString()–

StringBuffer s= new StringBuffer(”(”);

for(int i= 0; i¡ N; i++)–

s.append(String.format(”%8.3f”, d[i]) );

if(i!= N-1)s.append(”, ”);

else s.append(”)”);

˝

return s.toString();

˝

˝

C.2 Test for Vector4D.java

package com.jgcampbell.graphicsmaths;

/**

* Vector4DT1.java

* tests Vector4D

* @author j.g.c.

* version 1.0; 2005-10-29

*/

import java.io.*;

public class Vector4DT1 –

/**

* Constructor

*/

C–3

Page 114: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

public Vector4DT1()–

double[] d= –1.0, 2.0, 3.0, 4.0˝;

Vector4D x1= new Vector4D(d);

System.out.println(”Vector4DT1”);

System.out.println(”x1 = ”+ x1.toString());

Vector4D x2= new Vector4D();

x2.setAll(10.0);

System.out.println(”x2 = ”+ x2.toString());

Vector4D x3 = x2.add(x1);

System.out.println(”x3 = x2.add(x1): ”+ x3.toString());

Vector4D x4 = x3.scale(0.25);

System.out.println(”x4 = x3.scale(0.25): ”+ x4.toString());

double len = x1.length();

System.out.println(”len = x1.length(): ”+ len);

˝

/** The main method constructs the test

*/

public static void main(String[] args)

– new Vector4DT1(); ˝

˝

C.3 Homogeneous 3D Vector Transformations — Trans-

form4D.java

package com.jgcampbell.graphicsmaths;

/**

* Transform4D.java

* transform for 4D homogeneous vector

* @author j.g.c.

* version 1.0; 2005-03-20

* version 1.1; 2005-07-13, adding axis-angle rotation

* based partly on Brackeen, Developing Games in Java, p. 340 ...

* and Lengyel, Mathematics for 3D Game Programming and Computer

* Graphics, 2nd ed.

* see also Foley-VanDam, Introduction to Computer Graphics, p180 ...

*/

import java.io.*;

C–4

Page 115: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

public class Transform4D –

double[][] m;

public static final int N = 4;

private static final double eps = 1.0e-20;

/**

* void constructor

*/

public Transform4D()–

m = new double[N][N];

˝

/**

* Constructor from double array

* @param mm array

*/

public Transform4D(double[][] mm)–

this();

for(int r = 0; r¡ N; r++)–

for(int c = 0; c¡ N; c++)–

m[r][c]= mm[r][c];

˝

˝

˝

/**

* sets all elements to parameter

* @param value

*/

public void setAll(double val)–

for(int r = 0; r¡ N; r++)–

for(int c = 0; c¡ N; c++)–

m[r][c] = val ;

˝

˝

˝

/**

* sets identity matrix

*/

public void setIdentity()–

setAll(0.0);

for(int i = 0; i¡ N; i++)m[i][i] = 1.0;

˝

/**

* sets translation transform

* @param t translation as a vector

*/

C–5

Page 116: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

public void setTrans(Vector4D t)–

setIdentity();

int n= N-1;

for(int c = 0; c¡ n; c++)m[c][n] = t.d[c]; // x, y, z

˝

/**

* sets rotation-about-z transform

* @param theta angle (radians)

*/

public void setRotZ(double theta)–

setIdentity();

double cos = Math.cos(theta);

double sin = Math.sin(theta);

m[0][0] = cos;

m[0][1] = -sin;

m[1][0] = sin;

m[1][1] = cos;

˝

/**

* sets rotation-about-x transform

* @param theta angle (radians)

*/

public void setRotX(double theta)–

setIdentity();

double cos = Math.cos(theta);

double sin = Math.sin(theta);

m[1][1] = cos;

m[1][2] = -sin;

m[2][1] = sin;

m[2][2] = cos;

˝

/**

* sets rotation-about-y transform

* @param theta angle (radians)

*/

public void setRotY(double theta)–

setIdentity();

double cos = Math.cos(theta);

double sin = Math.sin(theta);

m[0][0] = cos;

m[0][2] = sin;

m[2][0] = -sin;

m[2][2] = cos;

˝

/**

C–6

Page 117: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

* sets rotation-about-arbitrary axis transform

* see Hill, Computer graphics using OpenGL, 2nd ed. p. 241.

* @param theta angle (radians)

* @param u axis

*/

public void setRotAxis(double theta, Vector4D u)–

setIdentity();

double c = Math.cos(theta);

double s = Math.sin(theta);

double cc = 1.0 - c;

double ux = u.d[0], uy = u.d[1], uz = u.d[2];

m[0][0] = c + cc*ux*ux;

m[0][1] = cc*uy*ux - s*uz;

m[0][2] = cc*uz*ux + s*uy;

m[1][0] = cc*ux*uy + s*uz;

m[1][1] = c + cc*uy*uy;

m[1][2] = cc*uz*uy - s*ux;

m[2][0] = cc*ux*uz - s*uy;

m[2][1] = cc*uy*uz + s*ux;

m[2][2] = c + cc*uz*uz;

˝

/**

* gets angle and axis from

* rotation-about-arbitrary axis transform

* see Hill, Computer graphics using OpenGL, 2nd ed. p. 241.

* @param theta angle (radians)

* @param u axis

*/

public double getRotAxis(Vector4D u)–

double theta = Math.acos(0.5*(m[0][0] + m[1][1] + m[2][2] - 1.0));

double s2 = 2.0*Math.sin(theta);

if(Math.abs(theta) ¿ eps)–

u.d[0] = (m[2][1] - m[1][2])/s2;

u.d[1] = (m[0][2] - m[2][0])/s2;

u.d[2] = (m[1][0] - m[0][1])/s2;

u.d[3] = 0.0;

˝

return theta;

˝

/**

* sets scaling

* @param s scale components as a vector

*/

C–7

Page 118: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

public void setScale(Vector4D s)–

setIdentity();

int n= N-1;

for(int i= 0; i¡ n; i++)m[i][i]= s.d[i];

˝

/**

* returns pre-multiplication of this*parameter

* @param v a vector to be multiplied by this

* @return product b = this*v

*/

public Vector4D mpy(Vector4D a)–

Vector4D b = new Vector4D();

double dot;

for (int r = 0; r ¡ N; r++) –

dot = 0;

for (int c = 0; c ¡ N; c++) –

dot += m[r][c]*a.d[c];

˝

b.d[r] = dot;

˝

return b;

˝

/**

* returns pre-multiplication of parameter*this

* @param a transform to be multiplied by this

* @return product b = a*this

*/

public Transform4D mpy(Transform4D a)–

Transform4D b = new Transform4D();

double dot;

for (int r = 0; r ¡ N; r++) –

for (int c = 0; c ¡ N; c++) –

dot = 0.0;

for (int i = 0; i ¡ N; i++) –

dot += a.m[r][i]*this.m[i][c];

˝

b.m[r][c] = dot;

˝

˝

return b;

˝

/**

* creates formatted String

* @return string

*/

C–8

Page 119: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

public String toString()–

StringBuffer s= new StringBuffer(”[”);

for(int r= 0; r¡ N; r++)–

s.append(”(”);

for(int c= 0; c¡ N; c++)–

s.append(String.format(”%8.3f”, m[r][c]) );

if(c!= N-1)s.append(”, ”);

else s.append(”)”);

˝

if(r!= N-1)s.append(”“n”);

else s.append(”]”);

˝

return s.toString();

˝

˝

C.4 Test for Transform4D.java

package com.jgcampbell.graphicsmaths;

/**

* Transform4DT1.java

* tests Transform4D

* @author j.g.c.

* version 1.0; 2005-03-20

* version 1.1; 2005-07-13

*/

import java.io.*;

public class Transform4DT1 –

/**

* Constructor

*/

public Transform4DT1()–

System.out.println(”Transform4DT1”);

double[] d= –1.0, 2.0, 3.0, 4.0˝;

Vector4D xa= new Vector4D(d);

System.out.println(”xa = ”+ xa.toString());

Transform4D f = new Transform4D();

f.setIdentity();

System.out.println(”f.setIdentity(): “n”+ f.toString());

C–9

Page 120: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Transform4D g = new Transform4D();

g.setIdentity();

System.out.println(”g.setIdentity(): “n”+ g.toString());

Transform4D fg= f.mpy(g);

System.out.println(”fg = f.mpy(g) (g identity): “n”+ fg.toString());

Vector4D xb = f.mpy(xa);

System.out.println(”xb = f.mpy(xa): ”+ xb.toString());

double[] d1= –0.0, 0.0, 0.0, 1.0˝;

Vector4D x0= new Vector4D(d1);

System.out.println(”x0 = ”+ x0.toString());

double[] dt= –1.0, 2.0, 3.0, 0.0˝;

Vector4D t= new Vector4D(dt);

System.out.println(”t = ”+ t.toString());

Transform4D h = new Transform4D();

h.setTrans(t);

System.out.println(”h.setTrans(t): “n”+ h.toString());

Vector4D x1 = h.mpy(x0);

System.out.println(”x1 = h.mpy(x0): “n”+ x1.toString());

//pi/2 rotation of (1,0,0) should make (0,1,0)

h.setRotZ(Math.PI/2.0);

System.out.println(”h.setRotZ(Math.PI/2): “n”+ h.toString());

Vector4D x1001 = new Vector4D(1.0, 0.0, 0.0, 1.0);

System.out.println(”x1001 = ”+ x1001.toString());

x1= h.mpy(x1001);

System.out.println(”x1 = h.mpy(x1001): “n”+ x1.toString());

System.out.println(”“nRotation followed by translation ...”);

h.setRotZ(Math.PI/4.0);

System.out.println(”h.setRotZ(Math.PI/4.0): “n”+ h.toString());

Vector4D x2101 = new Vector4D(2.0, 1.0, 0.0, 1.0);

System.out.println(”x2101 = ”+ x2101.toString());

x1= h.mpy(x2101);

System.out.println(”x1 = h.mpy(x2101): “n”+ x1.toString());

f.setTrans(new Vector4D(1.0, 2.0, 0.0, 0.0));

System.out.println(”f.setTrans(new Vector4D(1.0, 2.0, 0.0, 0.0)): ”

+ f.toString());

Vector4D x2 = f.mpy(x1);

System.out.println(”x2 = f.mpy(x1): ”+ x2.toString());

// incorrect order

/*

C–10

Page 121: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

System.out.println(”“nConcatenating rotation and translation ...”);

g = f.mpy(h); // this is h.f

System.out.println(”g = f.mpy(h): “n”+ g.toString());

x2 = g.mpy(x2101);

System.out.println(”x2 = g.mpy(x2101): ”+ x2.toString());

*/

System.out.println(”“nConcatenating rotation and translation ...”);

g = h.mpy(f); // this is f.h

System.out.println(”g = h.mpy(f): “n”+ g.toString());

x2 = g.mpy(x2101);

System.out.println(”x2 = g.mpy(x2101): ”+ x2.toString());

System.out.println(”“nAxis-angle rotation,”);

System.out.println(”see Hill, p. 241, ex. 5.3.4 ...”);

Transform4D ru = new Transform4D();

Vector4D u= new Vector4D(0.577, 0.577, 0.577, 0);

ru.setRotAxis(Math.PI/4.0, u);

System.out.println(”u= new Vector4D(0.577, 0.577, 0.577, 0);”);

System.out.println(”ru.setRotAxis(Math.PI/4.0, u): “n”

+ ru.toString());

double th = ru.getRotAxis(u);

System.out.println(”double th = getRotAxis(u);”);

System.out.println(”th = ”+ th);

System.out.println(”u = ”+ u.toString() );

˝

/** The main method constructs the test

*/

public static void main(String[] args)

– new Transform4DT1(); ˝

˝

C–11

Page 122: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Appendix D

3D Affine Transformations in C++

D.1 Homogeneous 3D Vector — Vector4D.h

//--------------------------------------------------------

// Vector4D.h

// j.g.c. 2005-03-28

//--------------------------------------------------------

#ifndef Vector4DH

#define Vector4DH

#include ¡string¿

#include ¡iostream¿

#include ¡cstdio¿ // for toString/sprintf

using namespace std; // bad bad practice in a header file, but easy!

#define N 4

class Vector4D–

static int n˙;

// friends are not members, but have access to private data

friend ostream& operator¡¡(ostream& os, const Vector4D& v);

friend istream& operator¿¿(istream& os, Vector4D& v);

friend bool operator¡(const Vector4D& lhs, const Vector4D& rhs);

public:

Vector4D();

Vector4D(float d[]);

Vector4D(float x, float y, float z, float w);

Vector4D(istream& is);

void setAll(float val);

Vector4D add(Vector4D v);

Vector4D sub(Vector4D v);

D–1

Page 123: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Vector4D scale(float s);

double length();

string toString() const;

//note below public

float d˙[N];

˝;

#undef N

#endif

D.2 Homogeneous 3D Vector — Vector4D.cpp

//--------------------------------------------------------

// Vector4D.cpp

// j.g.c. 2005-03-28

//--------------------------------------------------------

#include ”Vector4D.h”

int Vector4D::n˙ = 4;

Vector4D::Vector4D()–

setAll(0.0);

˝

Vector4D::Vector4D(float d[])–

for(int i= 0; i¡ n˙; i++)d˙[i]= d[i];

˝

Vector4D::Vector4D(float x, float y, float z, float w)–

d˙[0]= x; d˙[1]= y; d˙[2]= z; d˙[3]= w;

˝

Vector4D::Vector4D(istream& is)–

for(int i= 0; i¡ n˙; i++)is¿¿ d˙[i];

˝

void Vector4D::setAll(float val)–

for(int i= 0; i¡ n˙; i++)d˙[i]= val;

˝

Vector4D Vector4D::add(Vector4D v)–

Vector4D v1= Vector4D();

for(int i= 0; i¡ n˙; i++)v1.d˙[i]= d˙[i] + v.d˙[i];

return v1;

˝

D–2

Page 124: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Vector4D Vector4D::sub(Vector4D v)–

Vector4D v1= Vector4D();

for(int i= 0; i¡ n˙; i++)v1.d˙[i]= d˙[i] - v.d˙[i];

return v1;

˝

Vector4D Vector4D::scale(float s)–

Vector4D v1= Vector4D();

for(int i= 0; i¡ n˙; i++)v1.d˙[i] = s*d˙[i];

return v1;

˝

double Vector4D::length()–

double len= 0.0;

for(int i= 0; i¡ n˙; i++)len+= d˙[i]*d˙[i];

return sqrt(len);

˝

ostream& operator¡¡ (ostream& os, const Vector4D& v)

os¡¡ v.toString();

return os;

˝

string Vector4D::toString() const

//ideally, I should be using stringstream here, but there

// appears to be a problem under g++ 2.96 j.c. 2003/02/22

char cc[80];

sprintf(cc, ”(%8.3f, %8.3f, %8.3f, %8.3f)”, d˙[0], d˙[1], d˙[2], d˙[3]);

return string(cc);

˝

istream& operator¿¿(istream& is, Vector4D& v)

// assumes that fields are separated by whitespace

for(int i= 0; i¡ v.n˙; i++)is¿¿v.d˙[i];

return is;

˝

D.3 Test for Vector4D.cpp

/**

* Vector4DT1.cpp

* tests Vector4D

D–3

Page 125: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

* author j.g.c.

* version 1.0; 2005-03-28

*/

#include ¡iostream¿ // for cout¡¡ etc.

#include ¡string¿

#include ¡fstream¿ // for files - ofstream, ifstream

#include ”Vector4D.h”

using namespace std;

int main()–

float d[4]= –1., 2., 3., 4.˝;

Vector4D x1= Vector4D(d);

cout¡¡”Vector4DT1”¡¡ endl;

cout¡¡ ”x1 = ” ¡¡ x1.toString()¡¡ endl;

Vector4D x2= Vector4D();

x2.setAll(10.0);

cout¡¡ ”x2 = ”¡¡ x2.toString()¡¡ endl;

Vector4D x3 = x2.add(x1);

cout¡¡ ”x3 = x2.add(x1): ”¡¡ x3.toString()¡¡ endl;

Vector4D x4 = x3.scale(0.25);

cout¡¡ ”x4 = x3.scale(0.25): ”¡¡ x4.toString()¡¡ endl;

float len = x1.length();

cout¡¡ ”len = x1.length(): ”¡¡ len¡¡ endl;

˝

D.4 Homogeneous 3D Vector Transformations — Trans-

form4D.h

//--------------------------------------------------------

// Transform4D.h

// j.g.c. 2005-03-28

//--------------------------------------------------------

#ifndef Transform4DH

#define Transform4DH

#include ¡string¿

#include ¡iostream¿

#include ¡cstdio¿ // for toString/sprintf

D–4

Page 126: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

#include ”Vector4D.h”

#define N 4

using namespace std; // bad practice, but easy!

class Transform4D–

static int n˙;

// friends are not members, but have access to private data

friend ostream& operator¡¡(ostream& os, const Transform4D& v);

friend istream& operator¿¿(istream& os, Transform4D& v);

friend bool operator¡(const Transform4D& lhs, const Transform4D& rhs);

public:

Transform4D();

Transform4D(float d[N][N]);

Transform4D(istream& is);

void setAll(float val);

void setIdentity();

void setTrans(Vector4D t);

void setRotZ(double theta);

void setRotX(double theta);

void setRotY(double theta);

void setScale(Vector4D s);

Vector4D mpy(Vector4D v);

//b = a*this

Transform4D mpy(Transform4D s);

string toString() const;

private:

float m˙[N][N];

˝;

#undef N

#endif

D.5 Homogeneous 3D Vector Transformations — Trans-

form4D.cpp

//--------------------------------------------------------

// Transform4D.cpp

// j.g.c. 2005-03-28

D–5

Page 127: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

//--------------------------------------------------------

#include ”Transform4D.h”

#define N 4

int Transform4D::n˙ = N;

Transform4D::Transform4D()–

setAll(0.0);

˝

Transform4D::Transform4D(float m[N][N])–

for(int r = 0; r¡ n˙; r++)–

for(int c = 0; c¡ n˙; c++)–

m˙[r][c]= m[r][c];

˝

˝

˝

Transform4D::Transform4D(istream& is)–

for(int r= 0; r¡ n˙; r++)–

for(int c= 0; c¡ n˙; c++)–

is¿¿ m˙[r][c]; // undoubtedly wrong; test

˝

˝

˝

void Transform4D::setAll(float val)–

for(int r = 0; r¡ n˙; r++)–

for(int c = 0; c¡ n˙; c++)–

m˙[r][c] = val ;

˝

˝

˝

void Transform4D::setIdentity()–

setAll(0.0);

for(int i = 0; i¡ n˙; i++)m˙[i][i] = 1.0;

˝

void Transform4D::setTrans(Vector4D t)–

setIdentity();

int n= n˙-1;

for(int c = 0; c¡ n; c++)m˙[c][n] = t.d˙[c]; //x, y, z

˝

void Transform4D::setRotZ(double theta)–

setIdentity();

double cs = cos(theta);

D–6

Page 128: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

double sn = sin(theta);

m˙[0][0] = cs;

m˙[0][1] = -sn;

m˙[1][0] = sn;

m˙[1][1] = cs;

˝

void Transform4D::setRotX(double theta)–

setIdentity();

double cs = cos(theta);

double sn = sin(theta);

m˙[1][1] = cs;

m˙[1][2] = -sn;

m˙[2][1] = sn;

m˙[2][2] = cs;

˝

void Transform4D::setRotY(double theta)–

setIdentity();

double cs = cos(theta);

double sn = sin(theta);

m˙[0][0] = cs;

m˙[0][2] = -sn;

m˙[2][0] = sn;

m˙[2][2] = cs;

˝

void Transform4D::setScale(Vector4D s)–

setIdentity();

int n= n˙-1;

for(int i = 0; i¡ n; i++)m˙[i][i] = s.d˙[i]; //x, y, z

˝

/**

* returns pre-multiplication of this*parameter

* @param v a vector to be multiplied by this

* @return product b = this*v

*/

Vector4D Transform4D::mpy(Vector4D a)–

Vector4D b = Vector4D();

double dot;

for (int r = 0; r ¡ N; r++) –

dot = 0;

for (int c = 0; c ¡ N; c++) –

dot += m˙[r][c]*a.d˙[c];

˝

b.d˙[r] = dot;

˝

return b;

D–7

Page 129: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

˝

/**

* returns pre-multiplication of parameter*this

* @param a transform to be multiplied by this

* @return product b = a*this

*/

Transform4D Transform4D::mpy(Transform4D a)–

Transform4D b = Transform4D();

double dot;

for (int r = 0; r ¡ N; r++) –

for (int c = 0; c ¡ N; c++) –

dot = 0.0;

for (int i = 0; i ¡ N; i++) –

dot += a.m˙[r][i]*m˙[i][c];

˝

b.m˙[r][c] = dot;

˝

˝

return b;

˝

ostream& operator¡¡ (ostream& os, const Transform4D& m)

os¡¡ m.toString();

return os;

˝

string Transform4D::toString() const–

//ideally, I should be using stringstream here, but there

// appears to be a problem under g++ 2.96 j.c. 2003/02/22

char cc[80];

string s= string(”[”);

for(int r= 0; r¡ n˙; r++)–

sprintf(cc, ”(%8.3f, %8.3f, %8.3f, %8.3f)“n”,

m˙[r][0], m˙[r][1], m˙[r][2], m˙[r][3]);

s+= string(cc);

˝

s+= ”]”;

return s;

˝

istream& operator¿¿(istream& is, Transform4D& m)–

// assumes that fields are separated by whitespace

for(int r= 0; r¡ m.n˙; r++)–

for(int c= 0; c¡ m.n˙; c++)–

is¿¿ m.m˙[r][c];

˝

D–8

Page 130: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

˝

return is;

˝

#undef N

D.6 Test for Transform4D.cpp

/**

* Transform4DT1.cpp

* tests Transform4D

* @author j.g.c.

* version 1.0; 2005-03-28

*/

#include ¡iostream¿ // for cout¡¡ etc.

#include ¡string¿

#include ¡fstream¿ // for files - ofstream, ifstream

#include ”Transform4D.h”

#include ”Vector4D.h”

using namespace std;

class Transform4DT1 –

public:

/**

* Constructor

*/

Transform4DT1()–

cout¡¡ ”Transform4DT1”¡¡ endl;

float d[4]= –1.0, 2.0, 3.0, 4.0˝;

Vector4D xa= Vector4D(d);

cout¡¡ ”xa = ”+ xa.toString()¡¡ endl;

Transform4D f = Transform4D();

f.setIdentity();

cout¡¡ ”f.setIdentity(): “n”+ f.toString()¡¡ endl;

Transform4D g = Transform4D();

g.setIdentity();

cout¡¡ ”g.setIdentity(): “n”¡¡ g.toString()¡¡ endl;

Transform4D fg= f.mpy(g);

cout¡¡ ”fg = f.mpy(g) (g identity): “n”¡¡ fg.toString()¡¡ endl;

D–9

Page 131: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Vector4D xb = f.mpy(xa);

cout¡¡ ”xb = f.mpy(xa): ”¡¡ xb.toString()¡¡ endl;

float d1[4]= –0.0, 0.0, 0.0, 1.0˝;

Vector4D x0= Vector4D(d1);

cout¡¡ ”x0 = ”¡¡ x0.toString()¡¡ endl;

float dt[4]= –1.0, 2.0, 3.0, 0.0˝;

Vector4D t= Vector4D(dt);

cout¡¡ ”t = ”+ t.toString()¡¡ endl;

Transform4D h = Transform4D();

h.setTrans(t);

cout¡¡ ”h.setTrans(t): “n”¡¡ h.toString()¡¡ endl;

Vector4D x1 = h.mpy(x0);

cout¡¡ ”x1 = h.mpy(x0): “n”¡¡ x1.toString()¡¡ endl;

float pi= 3.1415926;

//pi/2 rotation of (1,0,0) should make (0,1,0)

h.setRotZ(pi/2.0);

cout¡¡ ”h.setRotZ(pi/2): “n”¡¡ h.toString()¡¡ endl;

Vector4D x1001 = Vector4D(1.0, 0.0, 0.0, 1.0);

cout¡¡ ”x1001 = ”¡¡ x1001.toString()¡¡ endl;

x1= h.mpy(x1001);

cout¡¡ ”x1 = h.mpy(x1001): “n”¡¡ x1.toString()¡¡ endl;

cout¡¡ ”“nRotation followed by translation ...”¡¡ endl;

h.setRotZ(pi/4.0);

cout¡¡ ”h.setRotZ(pi/4.0): “n”¡¡ h.toString()¡¡ endl;

Vector4D x2101 = Vector4D(2.0, 1.0, 0.0, 1.0);

cout¡¡ ”x2101 = ”¡¡ x2101.toString()¡¡ endl;

x1= h.mpy(x2101);

cout¡¡ ”x1 = h.mpy(x2101): “n”¡¡ x1.toString()¡¡ endl;

f.setTrans(Vector4D(1.0, 2.0, 0.0, 0.0));

cout¡¡ ”f.setTrans(Vector4D(1.0, 2.0, 0.0, 0.0)): ”¡¡

f.toString()¡¡ endl;

Vector4D x2 = f.mpy(x1);

cout¡¡ ”x2 = f.mpy(x1): ”¡¡ x2.toString()¡¡ endl;

// incorrect order

/*

System.out.println(”“nConcatenating rotation and translation ...”);

g = f.mpy(h); // this is h.f

System.out.println(”g = f.mpy(h): “n”+ g.toString());

x2 = g.mpy(x2101);

System.out.println(”x2 = g.mpy(x2101): ”+ x2.toString());

*/

D–10

Page 132: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

cout¡¡ ”“nConcatenating rotation and translation ...”¡¡ endl;

g = h.mpy(f); // this is f.h

cout¡¡ ”g = h.mpy(f): “n”¡¡ g.toString()¡¡ endl;

x2 = g.mpy(x2101);

cout¡¡ ”x2 = g.mpy(x2101): ”¡¡ x2.toString()¡¡ endl;

˝

˝;

/** The main method constructs the test

*/

int main()–

Transform4DT1();

˝

D–11

Page 133: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Appendix E

Quaternions in Java

E.1 Quaternion class — Quaternion.java

package com.jgcampbell.graphicsmaths;

/**

* Quaternion.java

* @author j.g.c.

* version 1.0; 2005-11-24

* based on Dunn and Parberry

*/

import java.io.*;

public class Quaternion –

double w, x, y, z;

private static final double eps = 1.0e-20;

/**

* void constructor

*/

public Quaternion()–

w= 0.0; x = 0.0; y= 0.0; z= 0.0;

˝

/**

* Constructor from double array

* @param d array, w = d[0]

*/

public Quaternion(double[] d)–

w= d[0]; x= d[1]; y= d[2]; z= d[3];

˝

/**

* sets identity

*/

E–1

Page 134: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

public void setIdentity()–

w= 1.0; x= 0.0; y= 0.0; z = 0.0;

˝

/**

* sets rotation-about-z transform

* @param theta angle (radians)

*/

public void setRotZ(double theta)–

double cos = Math.cos(theta/2);

double sin = Math.sin(theta/2);

setIdentity();

w = cos; z= sin;

˝

/**

* sets point quaternion

* @param p Vector4D holding point

*/

public void setPoint(Vector4D p)–

w = 0.0; x = p.d[0]; y = p.d[1]; z = p.d[2];

˝

/**

* sets rotation-about-x transform

* @param theta angle (radians)

*/

public void setRotX(double theta)–

setIdentity();

double cos = Math.cos(theta/2);

double sin = Math.sin(theta/2);

w = cos; x= sin;

˝

/**

* sets rotation-about-y transform

* @param theta angle (radians)

*/

public void setRotY(double theta)–

setIdentity();

double cos = Math.cos(theta/2);

double sin = Math.sin(theta/2);

w = cos; y= sin;

˝

/**

* sets rotation-about-arbitrary axis transform

* @param theta angle (radians)

* @param u axis

E–2

Page 135: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

*/

public void setRotAxis(double theta, Vector4D u)–

double cos = Math.cos(theta/2);

double sin = Math.sin(theta/2);

w= cos;

x = u.d[0]*sin; y = u.d[1]*sin; z = u.d[2]*sin;

˝

/**

* gets angle and axis from

* rotation-about-arbitrary axis transform

* @param theta angle (radians)

* @param u axis

*/

/*public double getRotAxis(Vector4D u)–

double theta = Math.acos(0.5*(m[0][0] + m[1][1] + m[2][2] - 1.0));

double s2 = 2.0*Math.sin(theta);

if(Math.abs(theta) ¿ eps)–

u.d[0] = (m[2][1] - m[1][2])/s2;

u.d[1] = (m[0][2] - m[2][0])/s2;

u.d[2] = (m[1][0] - m[0][1])/s2;

u.d[3] = 0.0;

˝

return theta;

˝

*/

/**

* returns pre-multiplication of this*parameter

* @param a a quaternion to be multiplied by this

* @return product b = this*a

*/

public Quaternion mpy(Quaternion a)–

Quaternion b = new Quaternion();

b.w = w*a.w - x*a.x - y*a.y - z*a.z;

b.x = w*a.x + x*a.w + y*a.z - z*a.y;

b.y = w*a.y + y*a.w + z*a.x - x*a.z;

b.z = w*a.z + z*a.w + x*a.y - y*a.x;

return b;

˝

/**

* add

* @param other a quaternion to be added this

* @return product b = this + a

*/

public Quaternion add(Quaternion other)–

Quaternion b = new Quaternion();

b.w = w+ other.w; b.x = x + other.x;

E–3

Page 136: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

b.y = y+ other.y; b.z = z + other.z;

return b;

˝

/**

* scale

* @param double s scale factor

*/

public void scale(double s)–

w*= s; x*= s; y*= s; z*= s;

˝

/**

* lenSq

* @param a a quaternion

* @return length-squared(this)

*/

public double lenSq()–

return w*w + x*x + y*y + z*z;

˝

/**

* conjg

* @param a a quaternion to be conjugated

* @return product b = inverse(a)

*/

public Quaternion conjg()–

Quaternion b = new Quaternion();

b.w = w; b.x = - x;

b.y = - y; b.z = - z;

return b;

˝

/**

* inv

* @param a a quaternion to be inverted

* @return product b = inverse(this)

*/

public Quaternion inv()–

Quaternion b = new Quaternion();

b = this.conjg();

double aa= this.lenSq();

b.scale(1/aa);

return b;

˝

/**

* creates formatted String

* @return string

E–4

Page 137: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

*/

public String toString()–

StringBuffer s= new StringBuffer(”[”);

s.append(String.format(”%8.3f”, w) );

s.append(” (”);

s.append(String.format(”%8.3f ”, x) );

s.append(String.format(”%8.3f ”, y) );

s.append(String.format(”%8.3f ”, z) );

s.append(”)]”);

return s.toString();

˝

˝

E.2 Example Program using Quaternions

package com.jgcampbell.graphicsmaths;

/**

* QuaternionT1.java

* tests Quaternion

* @author j.g.c.

* version 1.0; 2005-11-24

*/

import java.io.*;

public class QuaternionT1 –

/**

* Constructor

*/

public QuaternionT1()–

System.out.println(”QuaternionT1”);

double[] d= –0.0, 1.0, 1.0, 1.0˝;

Vector4D p= new Vector4D(d);

System.out.println(”p = ”+ p);

Quaternion pp = new Quaternion();

pp.setPoint(p);

System.out.println(”pp.setPoint(p): “n”+ pp);

Quaternion q = new Quaternion();

q.setRotY(Math.PI/2);

E–5

Page 138: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

System.out.println(”q.setRotY(Math.PI/2): “n”+ q);

Quaternion qi = q.inv();

System.out.println(”qi = q.inv(): “n”+ qi);

Quaternion qp= q.mpy(pp);

System.out.println(”qp= q.mpy(p): “n”+ qp);

Quaternion qpqi= qp.mpy(qi);

System.out.println(”qpqi= qp.mpy(qi): “n”+ qpqi);

q.setRotZ(-Math.PI/2);

System.out.println(”q.setRotZ(Math.PI/2): “n”+ q);

qi = q.inv();

System.out.println(”qi = q.inv(): “n”+ qi);

qp= q.mpy(pp);

System.out.println(”qp= q.mpy(p): “n”+ qp);

qpqi= qp.mpy(qi);

System.out.println(”qpqi= qp.mpy(qi): “n”+ qpqi);

˝

/** The main method constructs the test

*/

public static void main(String[] args)

– new QuaternionT1(); ˝

˝

E–6

Page 139: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Bibliography

Adams, K. (2005). Abstract Algebra on a Set S. Personal communication.

Angel, E. (2005). Interactive Computer Graphics: a top-down approach using OpenGL, 4th edn,

Addison Wesley.

Brannan, D. A., Esplen, M. F. & Gray, J. J. (1999). Geometry, Cambridge University Press. ISBN:

0521597870.

Buss, S. R. (2003). 3-D Computer Graphics: a mathematical introduction with OpenGL, Cam-

bridge University Press.

Campbell, J. (2005). The Origins of Quaternions and Related Algebras, Technical report, Let-

terkenny Institute of Technology. URL. http://www.jgcampbell.com/hamilton/quatorig.pdf.

Coxeter, H. M. (1969/1989). Introduction to Geometry, 2nd edn, Wiley. ISBN: 0-471-50458-0.

Craig, J. (1986). Introduction to Robotics Mechanics and Control, Addison Wesley.

Crowe, M. J. (1985/1967). A History of Vector Analysis : The Evolution of the Idea of a Vectorial

System, Dover.

Dunn, F. & Parberry, I. (2002). 3D math primer for graphics and game development, Wordware

Publishers. ISBN: 1556229119.

Eves, H. (1965/1990a). Foundations and Fundamental Concepts of Mathematics, 3rd edn, Dover.

Eves, H. (1990b). An Introduction to the History of Mathematics, 6th edn, Thompson/Brooks-

Cole.

Foley, J., van Dam, A., Feiner, S. & Hughes, J. (1990). Computer Graphics: principles and

practice, 2nd edn, Addison Wesley.

Foley, J., van Dam, A., Feiner, S., Hughes, J. & Phillips, R. (1994). Introduction to Computer

Graphics, Addison Wesley.

Forsyth, D. A. & Ponce, J. (2003). Computer Vision - a modern approach, Prentice Hall.

Gonzalez, R. & Woods, R. (2002). Digital Image Processing, 2nd edn, Prentice Hall.

Hoffmann, B. (1975/1966). About Vectors, Dover.

Katz, V. J. (1998). A History of Mathematics: An Introduction, 2nd edn, Addison Wesley.

Klein, F. (2004/1925a). Elementary Mathematics from an Advanced Standpoint: Arithmetic

Algebra Analysis, Dover.

E–1

Page 140: Notes on Mathematics for 2D and 3D Graphics on Mathematics for 2D and 3D Graphics Jonathan G. Campbell Department of Computing, Letterkenny Institute of Technology, Co. Donegal, Ireland.

Klein, F. (2004/1925b). Elementary Mathematics from an Advanced Standpoint: Geometry,

Dover.

Kline, M. (1967). Mathematics for the Nonmathematician, Dover.

Kline, M. (1972). Mathematical Thought from Ancient to Modern Times, Vol. 1, Oxford University

Press.

Lengyel, E. (2004). Mathematics for 3d Game Programming and Computer Graphics, 2nd edn,

Charles River Media.

Lipschutz, S. & Lipson, M. (1999). Linear Algebra (Schaum’s Outlines), 3rd edn, McGraw-Hill.

MacLane, S. & Birkoff, G. (1999). Algebra, 3rd edn, AMS Chelsea Publishing.

Maxwell, E. (1946). The Methods of Plane Projective Geometry based on the use of General

Homogeneous Coordinates, Cambridge University Press.

Needham, T. (1997). Visual Complex Analysis, Oxford.

Schneider, P. J. & Eberly, D. H. (2003). Geometric Tools for Computer Graphics, Morgan Kauf-

mann. ISBN: 1-55860-594-0.

Shapiro, L. G. & Stockman, G. C. (2001). Computer Vision, Prentice Hall.

Shreiner, D., Woo, M., Neider, J. & Davis, T. (2006). OpenGL Programming Guide: The

Official Guide to Learning OpenGL, Version 2 (The Red Book), 5th edn, Addison Wes-

ley. ISBN: 0-321-33573-2. Note that there is a very usable web version of Edition 1.1 at:

http://www.glprogramming.com/red/.

Spiegel, M. (1959). Vector Analysis (Schaum’s Outlines), McGraw-Hill.

Stillwell, J. (2002). Mathematics and its History, 2nd edn, Springer-Verlag.

Strang, G. (2003). Introduction to linear algebra, 3rd edn, Wellesley-Cambridge Press. ISBN:

0961408898.

vanVerth, J. M. & Bishop, L. M. (2004). Essential mathematics for games and interactive appli-

cations, Morgan Kaufmann. ISBN: 155860863X.

Vince, J. (2001). Essential mathematics for computer graphics fast, Springer-Verlag. ISBN:

1852333804.

E–2