Eigen Tutorial. CS2240 Interactive Computer Graphics

Similar documents
1. Describe History of C++? 2. What is Dev. C++? 3. Why Use Dev. C++ instead of C++ DOS IDE?

Vector Algebra Transformations. Lecture 4

MATH (CRN 13695) Lab 1: Basics for Linear Algebra and Matlab

A Basic Guide to Using Matlab in Econ 201FS

CS1114: Matlab Introduction

assembler Machine Code Object Files linker Executable File

Lecture 14: more class, C++ streams

FreeMat Tutorial. 3x + 4y 2z = 5 2x 5y + z = 8 x x + 3y = -1 xx

C++ For Science and Engineering Lecture 2

CS1114: Matlab Introduction

GEOMETRIC OBJECTS AND TRANSFORMATIONS I

Overview. By end of the week:

Compiling with Multiple Files The Importance of Debugging CS 16: Solving Problems with Computers I Lecture #7

Maths for Signals and Systems Linear Algebra in Engineering. Some problems by Gilbert Strang

Matrices. Chapter Matrix A Mathematical Definition Matrix Dimensions and Notation

Constraint-based Metabolic Reconstructions & Analysis H. Scott Hinton. Matlab Tutorial. Lesson: Matlab Tutorial

ECON 502 INTRODUCTION TO MATLAB Nov 9, 2007 TA: Murat Koyuncu

Performing Matrix Operations on the TI-83/84

CS100R: Matlab Introduction

Graphics and Interaction Transformation geometry and homogeneous coordinates

COMP30019 Graphics and Interaction Transformation geometry and homogeneous coordinates

Discussion 1H Notes (Week 3, April 14) TA: Brian Choi Section Webpage:

x = 12 x = 12 1x = 16

UNIVERSITY OF CALIFORNIA, SANTA CRUZ BOARD OF STUDIES IN COMPUTER ENGINEERING

Vector: A series of scalars contained in a column or row. Dimensions: How many rows and columns a vector or matrix has.

Week 0: Intro to Computers and Programming. 1.1 Why Program? 1.2 Computer Systems: Hardware and Software. Hardware Components

Chapter 5. Repetition. Contents. Introduction. Three Types of Program Control. Two Types of Repetition. Three Syntax Structures for Looping in C++

3D Viewing Episode 2

Computer Science 2500 Computer Organization Rensselaer Polytechnic Institute Spring Topic Notes: C and Unix Overview

Affine Transformation. Edith Law & Mike Terry

Lab of COMP 406. MATLAB: Quick Start. Lab tutor : Gene Yu Zhao Mailbox: or Lab 1: 11th Sep, 2013

CSc Introduc/on to Compu/ng. Lecture 8 Edgardo Molina Fall 2011 City College of New York

Transforms 1 Christian Miller CS Fall 2011

Dr Richard Greenaway

pointers + memory double x; string a; int x; main overhead int y; main overhead

PieNum Language Reference Manual

SML: Specialized Matrix Language White Paper

C++ for Java Programmers

CS201 - Introduction to Programming Glossary By

Introduction to Matlab

CSCI 204 Introduction to Computer Science II

Today. Today. Introduction. Matrices. Matrices. Computergrafik. Transformations & matrices Introduction Matrices

2nd Year Computational Physics Week 1 (experienced): Series, sequences & matrices

Math background. 2D Geometric Transformations. Implicit representations. Explicit representations. Read: CS 4620 Lecture 6

2D/3D Geometric Transformations and Scene Graphs

EECE 478. Learning Objectives. Learning Objectives. Linear Algebra and 3D Geometry. Linear algebra in 3D. Coordinate systems

3D Viewing Episode 2

VARIABLES & ASSIGNMENTS

2D Object Definition (1/3)

PIC 10A Objects/Classes

MAT 275 Laboratory 2 Matrix Computations and Programming in MATLAB

Using IDLE for

Computer Science 322 Operating Systems Mount Holyoke College Spring Topic Notes: C and Unix Overview

COMP30019 Graphics and Interaction Three-dimensional transformation geometry and perspective

Operator overloading

ERC CISST Software Quick start for cisstvector

CS 376b Computer Vision

Python lab session 1

CT5510: Computer Graphics. Transformation BOCHANG MOON

CE221 Programming in C++ Part 1 Introduction

CIS220 In Class/Lab 1: Due Sunday night at midnight. Submit all files through Canvas (25 pts)

C++ Programming Lecture 1 Software Engineering Group

Shorthand for values: variables

Lesson 13 - Vectors Dynamic Data Storage

Short Notes of CS201

Mathematics 308 Geometry. Chapter 9. Drawing three dimensional objects

CSE 374 Programming Concepts & Tools. Hal Perkins Fall 2015 Lecture 19 Introduction to C++

CSE 167: Introduction to Computer Graphics Lecture #2: Coordinate Transformations

Matrix Multiplication

Computer Programming : C++

Lab: Supplying Inputs to Programs

Basic memory model Using functions Writing functions. Basics Prototypes Parameters Return types Functions and memory Names and namespaces

Tutorial 2 Part B: The View Matrix & Frame Rates

CS 251 INTERMEDIATE SOFTWARE DESIGN SPRING C ++ Basics Review part 2 Auto pointer, templates, STL algorithms

Better Living with Automatic Differentiation

1/29/2011 AUTO POINTER (AUTO_PTR) INTERMEDIATE SOFTWARE DESIGN SPRING delete ptr might not happen memory leak!

Linear algebra deals with matrixes: two-dimensional arrays of values. Here s a matrix: [ x + 5y + 7z 9x + 3y + 11z

Objectives. Chapter 2: Basic Elements of C++ Introduction. Objectives (cont d.) A C++ Program (cont d.) A C++ Program

Introduction to MATLAB

Chapter 2: Basic Elements of C++

So we have been talking about 3D viewing, the transformations pertaining to 3D viewing. Today we will continue on it. (Refer Slide Time: 1:15)

Chapter 2: Basic Elements of C++ Objectives. Objectives (cont d.) A C++ Program. Introduction

C++ PROGRAMMING. For Industrial And Electrical Engineering Instructor: Ruba A. Salamh

Functions. CS111 Lab Queens College, CUNY Instructor: Kent Chin

ELEC4042 Signal Processing 2 MATLAB Review (prepared by A/Prof Ambikairajah)

It can be confusing when you type something like the expressions below and get an error message. a range variable definition a vector of sine values

An array is a collection of data that holds fixed number of values of same type. It is also known as a set. An array is a data type.

Review. Modules. CS 151 Review #6. Sample Program 6.1a:

C++ Arrays and Vectors

University of Alberta

Using the GeoX Framework

Machine Learning for Signal Processing Fundamentals of Linear Algebra

Matrix Multiplication

C++ Primer for CS175

CSE 374 Programming Concepts & Tools. Hal Perkins Spring 2010

Software Design and Analysis for Engineers

To start using Matlab, you only need be concerned with the command window for now.

SIMPLE INPUT and OUTPUT:

Introduction to Programming in C Department of Computer Science and Engineering. Lecture No. #43. Multidimensional Arrays

Review of Important Topics in CS1600. Functions Arrays C-strings

Transcription:

CS2240 Interactive Computer Graphics

CS2240 Interactive Computer Graphics Introduction Eigen is an open-source linear algebra library implemented in C++. It s fast and well-suited for a wide range of tasks, from heavy numerical computation, to simple vector arithmetic. The goal of this tutorial is to introduce the features of Eigen required for implementing graphics applications, to readers possessing basic knowledge of C++, linear algebra, and computer graphics. Goals After reading this tutorial, the reader should be able to 1. Install Eigen on computers running Linux, Mac OS, and Windows. 2. Create and initialize matrices and vectors of any size with Eigen in C++. 3. Use Eigen for basic algebraic operations on matrices and vectors. The reader should be able to perform addition, multiplication, scalar multiplication, and matrix inversion and transposition. 4. Use Eigen s built-in functions to create 4x4 transformation matrices. Installing Eigen We ll use Git to download the source files for Eigen into the user s home directory. You can, of course, use any directory you prefer - just replace the tilde ~ in the following commands with your desired download path. $ cd ~ $ git clone https :// github. com / eigenteam / eigen -git - mirror If you re like me and the idea of building libraries from source gives you the jitters, don t worry - we don t need to build anything here. Eigen uses pure header libraries, which means all its source code is included in header files. There are no separate.cpp files for function and class definitions - everything goes into the.h files. This makes using Eigen quite simple. To begin using it, simply #include these header files at the beginning of your own code. You can find these headers in ~/eigen-git-mirror/eigen/src. Of course, the compiler needs to be told the location on disk of any header files you include. You can copy the ~/eigen-git-mirror/eigen folder to each new project s directory. Or, you could add the folder once to the compiler s default include path. You can do this by running the following command on machines with Linux or Mac OS: $ sudo ln -s / usr / local / include ~/ eigen -git - mirror / Eigen If you re using a lab machine, add the following line to the end of ~/.bash profile export CPLUS_INCLUDE_PATH = $CPLUS_INCLUDE_PATH$ :~/ eigen -git - mirror If you re using QTCreator, add the following line to your project (.PROJ) file: QMAKE_CXXFLAGS = -I "~/ eigen -git - mirror " 2

Good day, Universe! Let s test our installation by writing a simple program. If you ve followed the steps above, you should be able to compile the following piece of code without any additional configuration. # include <Eigen /Core > # include < iostream > using namespace std ; using namespace Eigen ; int main () { cout << " Eigen version : " << EIGEN_MAJOR_VERSION << "." << EIGEN_MINOR_VERSION << endl ; return 0; } Matrices Creating matrices with Eigen is simple: Matrix3f A; Matrix4d B; Eigen uses a naming convention for its datatypes that is quite similar to OpenGL. The actual datatype name is followed by suffixes that describe its size, and the type of its member elements respectively. In the example above, the variable A is of type Matrix3f that is, a 3x3 matrix of floats. The variable B is a 4x4 matrix of doubles. Keep in mind, though, that not all combinations of size and type are valid Matrix2i works, but Matrix5s throws an error. That is not to say you can t create 5x5 matrices of type short, or that you can only create square matrices. Doing so merely requires a slightly different syntax: // 5 x5 matrix of type short Matrix < short, 5, 5> M1; // 20 x75 matrix of type float Matrix < float, 20, 75 > M2; In fact, this is how all matrices in Eigen are created under the hood. The datatype names described above are only provided as a convenience for commonly used sizes and types. What s more, Eigen even allows us to create matrices whose size is not known at compile time by using an X in place of the size suffix (MatrixXf, MatrixXd). However, as the majority of graphics operations only require us to work with 3x3 and 4x4 single or double precision matrices, we will restrict our attention in this tutorial to the datatypes Matrix3f, Matrix4f, Matrix3d, and Matrix4d. 3

CS2240 Interactive Computer Graphics Initialization Now that we ve created our matrix variables, let s assign some values to them: // Initialize A A << 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0 f; // Initialize B by accessing individual elements for i = 1:4 { for j = 1:4 { B(j, i) = 0.0; } } The first method shown above uses the comma initializer syntax: the programmer specifies the coefficients row by row. Note that all coefficients need to be provided if the number of coefficients does not match the size of the matrix, the compiler will throw an error. Thus, you can imagine this syntax becoming quite cumbersome for large matrices. 1 The second method accesses the individual coefficients of the matrix B using the overloaded parantheses operators. Indexing starts at zero, with the first index specifying the row number, and the second the column number. As you have probably guessed, you can use the same syntax to query the coefficients. Can you guess whether the following code prints a zero or a one? cout << A(1, 2); Notice that we have structured our loops such that the outer loop runs over the columns, and the inner loop iterates over the rows. Doing it the other way around would have worked too, but would have been less efficient. This is because Eigen stores matrices in column-major order by default. This can be a bit confusing since coefficients in the comma initialization format are specified in row-major order. Another potential point of confusion is that unlike C/C++, or Python arrays, Eigen uses parantheses rather than square brackets to access matrix elements. In addition to the above two methods, Eigen provides utility functions to initialize matrices to predefined values: // Set each coefficient to a uniform random value in the range [-1, 1] A = Matrix3f :: Random (); // Set B to the identity matrix B = Matrix4d :: Identity (); // Set all elements to zero A = Matrix3f :: Zero (); // Set all elements to ones A = Matrix3f :: Ones (); 1 When using comma initialization, the inputs can even be other matrices and vectors. You can learn more about this feature at https://eigen.tuxfamily.org/dox/group TutorialAdvancedInitialization.html. 4

// Set all elements to a constant value B = Matrix4d :: Constant (4.5) ; Matrix Operations Common arithmetic operators are overloaded to work with matrices: Matrix4f M1 = Matrix4f :: Random (); Matrix4f M2 = Matrix4f :: Constant ( 2. 2) ; // Addition // The size and the coefficient - types of the matrices must match cout << M1 + M2 << endl ; // Matrix multiplication // The inner dimensions and the coefficient - types must match cout << M1 * M2 << endl ; // Scalar multiplication, and subtraction // What do you expect the output to be? cout << M2 - Matrix4f :: Ones () * 2.2 << endl ; Equality (==) and inequality (!=) are the only relational operators that work with matrices. Two matrices are considered equal if all corresponding coefficients are equal. cout << ( M2 - Matrix4f :: Ones () * 2.2 == Matrix4f :: Zero ()) << endl ; Common matrix operations are provided as methods of the matrix class: // Transposition cout << M1. transpose () << endl ; // Inversion ( # include < Eigen / Dense > ) // Generates NaNs if the matrix is not invertible cout << M1. inverse () << endl ; Sometimes, we may prefer to apply an operation to a matrix element-wise. This can be done by asking Eigen to treat the matrix as a general array by invoking the array() method: // Square each element of the matrix cout << M1. array (). square () << endl ; // Multiply two matrices element - wise cout << M1. array () * Matrix4f :: Identity (). array () << endl ; // All relational operators can be applied element - wise cout << M1. array () <= M2. array () << endl << endl ; cout << M1. array () > M2. array () << endl ; Note that these operations do not work in-place. That is, calling M1.array().sqrt() returns a new matrix, with M1 retaining its original value. 5

CS2240 Interactive Computer Graphics Vectors A vector in Eigen is nothing more than a matrix with a single column: typedef Matrix < float, 3, 1 > Vector3f ; typedef Matrix < double, 4, 1 > Vector4d ; Consequently, many of the operators and functions we discussed above for matrices also work with vectors. The naming convention is also similar (in this case, the size suffix defines the one-dimensional length, rather than the square dimensions). // Comma initialization v << 1.0f, 2.0f, 3.0 f; // Coefficient access cout << v (2) << endl ; // Vectors of length up to four can be initialized in the constructor Vector3f w (1.0f, 2.0f, 3.0 f); // Utility functions Vector3f v1 = Vector3f :: Ones (); Vector3f v2 = Vector3f :: Zero (); Vector4d v3 = Vector4d :: Random (); Vector4d v4 = Vector4d :: Constant ( 1. 8) ; // Arithmetic operations cout << v1 + v2 << endl << endl ; cout << v4 - v3 << endl ; // Scalar multiplication cout << v4 * 2 << endl ; // Equality // Again, equality and inequality are the only relational // operators that work with vectors cout << ( Vector2f :: Ones () * 3 == Vector2f :: Constant (3) ) << endl ; Since vectors are just one-dimensional matrices, matrix-vector multiplication works as long as the inner dimensions and coefficient-types of the operands agree: Vector4f v5 = Vector4f (1.0f, 2.0f, 3.0f, 4.0 f); // 4x4 * 4x1 - Works! cout << Matrix4f :: Random () * v5 << endl ; // 4 x1 * 4 x4 - Compiler Error! cout << v5 * Matrix4f :: Random () << endl ; 6

As you would expect, matrix multiplication doesn t work with two vectors as the inner dimensions of two nx1 matrices don t match. However, transposing one of the vectors fixes this: // Transposition converts the column vector to a row vector // This makes the inner dimensions match, allowing matrix multiplication v1 = Vector3f :: Random (); v2 = Vector3f :: Random (); cout << v1 * v2. transpose () << endl ; The linear algebra savvy amongst us probably recognized the last operation as nothing other than the dot product. In fact, vectors have built-in functions for the dot product, and other common operations: cout << v1.dot (v2) << endl << endl ; cout << v1. normalized () << endl << endl ; cout << v1. cross (v2) << endl ; // Convert a vector to and from homogenous coordinates Vector3f s = Vector3f :: Random (); Vector4f q = s. homogeneous (); cout << ( s == q. hnormalized ()) << endl ; And, finally, element-wise operations can be performed by asking Eigen to treat the vector as a general array: cout << v1. array () * v2. array () << endl << endl ; cout << v1. array ().sin () << endl ; Example: Vertex Transformation Now that we have a basic understanding of Eigen, let s use it to perform a very common operation in graphics: vertex transformation. 7

CS2240 Interactive Computer Graphics # include <Eigen /Core > # include <Eigen / Geometry > # include < iostream > using namespace std ; using namespace Eigen ; int main () { float arrvertices [] = { -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0}; MatrixXf mvertices = Map < Matrix < float, 3, 8 > > ( arrvertices ); Transform < float, 3, Affine > t = Transform < float, 3, Affine >:: Identity (); t. scale ( 0.8 f ); t. rotate ( AngleAxisf (0.25 f * M_PI, Vector3f :: UnitX () ) ); t. translate ( Vector3f (1.5, 10.2, -5.1) ); cout << t * mvertices. colwise (). homogeneous () << endl ; } This example introduces several new Eigen constructs. To start with, we are using a C++ array to initialize a MatrixXf object. The array holds the x, y, and z coordinates of the vertices of a cube. 2 Eigen s Map class allows us to perform this initialization. Next, we create a transformation. You may recall from linear algebra that a transformation is nothing more than a matrix. This is also true in Eigen the Transform class just makes it easier to deal with the underlying matrix representation. You can access the underlying matrix by calling t.matrix(). Transform<float, 3, Affine> t creates a 3-dimensional affine transformation with singleprecision floating point coefficients. The next three lines apply a uniform scaling, rotation, and translation to the created transform object. In matrix form, this may be written as Where I is the identity matrix. U = T RSI The rotation is specified as a combination of angle and rotation-axis by using the AngleAxisf class. The axis should be normalized, and in most cases we can simply use the convenience functions Vector3f::UnitX(), Vector3f::UnitY, and Vector3f::UnitZ() which represent unit vectors in the x, y, and z directions, respectively. 2 We could have loaded the array into an array of eight Vector3f objects. However, storing it as a matrix is more efficient, and leads to cleaner code. 8

Finally, we apply the transformation to the vertices of our cube. See how storing the vertices as columns of a matrix allows us to transform all vertices with a single matrix multiplication. To do this, however, the inner dimensions of the transformation matrix, and the vertex matrix have to match. t uses homogeneous coordinates, and so a 3-dimensional transformation is represented as a 4x4 matrix. To match these dimensions, we homogenize each column of our vertex matrix by using the colwise() method. Each column of the output represents a transformed vertex: 0.4 2 2 0.4 0.4 2 2 0.4 8.65499 8.65499 9.78636 9.78636 7.52362 7.52362 8.65499 8.65499 1. 75362 1. 75362 2. 885 2. 885 2. 885 2. 885 4. 01637 4. 01637 Further Reading The Eigen Quick Reference Guide provides a handy reference to most matrix and vector operations: https://eigen.tuxfamily.org/dox/group QuickRefPage.html 9