Last modified 27 June 2003 by jdavis@math.wisc.edu
Inherits from NSObject
Conforms to NSCoding, NSCopying
SMKMatrix can store any 4x4 matrix, but the real purpose of this class is to represent rigid-body transformations (SMKTransformations) in matrix form. Most methods assume that the matrix is "affine", meaning that its last row is (0, 0, 0, 1). This condition is necessary, but not sufficient, for the matrix to belong to the multiplicative group of affine transformations; the product of two affine matrices is affine, but not all affine matrices are invertible. The additive structure of the matrix ring is ignored.
SMKMatrix offers low-level access to its entries, violating data encapsulation principles for the sake of efficiency. It also offers higher-level methods for multiplication and inversion, and for interacting with OpenGL. In many cases, each method is available in two forms: one that stores the result in a preexisting matrix (which can be more efficient) and one that returns the result as a newly allocated matrix (which is more elegant). When possible, the latter is given as a class method.
SMKMatrix stores its entries as an array of 16 double-precision floating point numbers, which corresponds to a 4x4 matrix in column-major order. That is, the first four entries represent the first column, the next four the next column, and so on. This is the convention used in OpenGL. The following methods access the matrix's entries on this low level.
- (id)setColumns:(double *)columns;Copies the given array of 16 doubles into the receiver's internal representation.
Returns the receiver's internal representation.
The next method tests whether the matrix is affine, as defined above.
- (BOOL)isAffine;Returns YES if the last row of the receiver is (0, 0, 0, 1), and NO otherwise.
This method multiplies an affine matrix by a vector:
- (id)multiplyByVector:(double *)v withResult:(double *)result;Multiplies the matrix with the given (column) vector v, which must be distinct from result. That is, result = Mv. This method assumes that the matrix is affine. It does not access v[3] or result[3], so these vectors can be either 3-dimensional or 4-dimensional (homogeneous) with last entry 1.
The methods in this section assume that their arguments (including the receiver) are affine matrices. The arguments may not alias each other. First, the (multiplicative) identity matrix is the one with 1s along its main diagonal and 0s elsewhere.
- (id)makeIdentity;Sets the receiver to the identity matrix.
Returns the identity matrix.
SMKMatrix offers several variations on the all-important multiplication operation.
- (id)multiplyByMatrix:(SMKMatrix *)matrix withResult:(SMKMatrix *)result;Sets result to the product of the receiver and matrix.
- (id)productWithMatrix:(SMKMatrix *)matrix;
Returns the product of the receiver and matrix.
- (id)appendMatrix:(SMKMatrix *)matrix;
Sets the receiver to the product of the receiver and matrix.
- (id)prependMatrix:(SMKMatrix *)matrix;
Sets the receiver to the product of matrix and the receiver.
Affine matrices are not always invertible, but the following methods invert them when they are.
- (BOOL)invertWithResult:(SMKMatrix *)result;Sets result to the inverse of the receiver, returning YES if and only if the receiver was invertible.
Returns the inverse of the receiver, or nil if it is not invertible.
This section describes a variety of methods that interact with OpenGL. Obviously, these methods issue OpenGL commands. It is also worth noting that perspective projection matrices are usually not affine.
- (id)makeModelview;Sets the receiver to the current OpenGL modelview matrix.
Returns the current OpenGL modelview matrix.
Sets the receiver to the current OpenGL projection matrix.
Returns the current OpenGL projection matrix.
Loads the receiver into the top of the current OpenGL matrix stack using glLoadMatrixd().
Multiplies the receiver onto the top of the current OpenGL matrix stack using glMultMatrixd().