NAME¶
m_alloc2, m_free2, v_alloc2, v_free2, m_alloc3, m_free3, v_alloc3, v_free3,
m_cpy2, m_unity2, v_cpy2, v_fill2, v_unity2, v_zero2, m_cpy3, m_unity3,
v_cpy3, v_fill3, v_unity3, v_zero3, m_det2, v_len2, vtmv_mul2, vv_inprod2,
m_inv2, m_tra2, mm_add2, mm_mul2, mm_sub2, mtmm_mul2, sm_mul2, mv_mul2,
sv_mul2, v_homo2, v_norm2, vv_add2, vv_sub2, vvt_mul2, m_det3, v_len3,
vtmv_mul3, vv_inprod3, m_inv3, m_tra3, mm_add3, mm_mul3, mm_sub3, mtmm_mul3,
sm_mul3, mv_mul3, sv_mul3, v_homo3, v_norm3, vv_add3, vv_cross3, vv_sub3,
vvt_mul3, miraxis2, mirorig2, mirplane2, rot2, scaorig2, scaplane2, scaxis2,
transl2, miraxis3, mirorig3, mirplane3, prjorthaxis, prjpersaxis, rot3,
scaorig3, scaplane3, scaxis3, transl3 - 3d graphics and associated matrix and
vector routines
SYNOPSIS¶
#include <graphmat.h>
/* Data initialisation */
hmat2_t *m_alloc2(m_result)
hmat2_t *m_result;
void m_free2(matrix)
hmat2_t *matrix;
hvec2_t *v_alloc2(v_result)
hvec2_t *v_result;
void v_free2(vector)
hmat2_t *vector;
hmat3_t *m_alloc3(m_result)
hmat3_t *m_result;
void m_free3(matrix)
hmat3_t *matrix;
hvec3_t *v_alloc3(v_result)
hvec3_t *v_result;
void v_free3(vector)
hmat3_t *vector;
hmat2_t *m_cpy2(m_source, m_result)
hmat2_t *m_source, *m_result;
hmat2_t *m_unity2( m_result)
hmat2_t *m_result;
hvec2_t *v_cpy2(v_source, v_result)
hvec2_t *v_source, *v_result;
hvec2_t *v_fill2(x, y, w, v_result)
double x, y, w;
hvec2_t *v_result;
hvec2_t *v_unity2(axis, v_result)
b_axis axis;
hvec2_t *v_result;
hvec2_t *v_zero2(v_result)
hvec2_t *v_result;
hmat3_t *m_cpy3(m_source, m_result)
hmat3_t *m_source, *m_result;
hmat3_t *m_unity3(m_result)
hmat3_t *m_result;
hvec3_t *v_cpy3(v_source, v_result)
hvec3_t *v_source, *v_result;
hvec3_t *v_fill3(x, y, z, w, v_result)
double x, y, z, w;
hvec3_t *v_result;
hvec3_t *v_unity3(axis, v_result)
b_axis axis;
hvec3_t *v_result;
hvec3_t *v_zero3(vector)
hvec3_t *vector;
/* Basic Linear Algebra */
double m_det2(matrix)
hmat2_t *matrix;
double v_len2(vector)
hvec2_t *vector;
double vtmv_mul2(vector, matrix)
hvec2_t *vector;
hmat2_t *matrix;
double vv_inprod2(vectorA, vectorB)
hvec2_t *vectorA, *vectorB;
hmat2_t *m_inv2(matrix, m_result)
hmat2_t *matrix, *m_result;
hmat2_t *m_tra2(matrix, m_result)
hmat2_t *matrix, *m_result;
hmat2_t *mm_add2(matrixA, matrixB, m_result)
hmat2_t *matrixA, *matrixB, *m_result;
hmat2_t *mm_mul2(matrixA, matrixB, m_result)
hmat2_t *matrixA, *matrixB, *m_result;
hmat2_t *mm_sub2(matrixA, matrixB, m_result)
hmat2_t *matrixA, *matrixB, *m_result;
hmat2_t *mtmm_mul2(matrixA, matrixB, m_result)
hmat2_t *matrixA, *matrixB, *m_result;
hmat2_t *sm_mul2(scalar, matrix, m_result)
double scalar;
hmat2_t *matrix, *m_result;
hmat2_t *vvt_mul2(vectorA, vectorB, m_result)
hvec2_t *vectorA, *vectorB;
hmat2_t *m_result;
hvec2_t *mv_mul2(matrix, vector, v_result)
hmat2 *matrix;
hvec2_t *vector, *v_result;
hvec2_t *sv_mul2(scalar, vector, v_result)
double scalar;
hvec2_t *vector, *v_result;
hvec2_t *v_homo2(vector, v_result)
hvec2_t *vector, *v_result;
hvec2_t *v_norm2(vector, v_result)
hvec2_t *vector, *v_result;
hvec2_t *vv_add2(vectorA, vectorB, v_result)
hvec2_t *vectorA, *vectorB, *v_result;
hvec2_t *vv_sub2(vectorA, vectorB, v_result)
hvec2_t *vectorA, *vectorB, *v_result;
double m_det3(matrix)
hmat3_t *matrix;
double v_len3(vector)
hvec3_t *vector;
double vtmv_mul3(vector, matrix)
hvec3_t *vector;
hmat3_t *matrix;
double vv_inprod3(vectorA, vectorB)
hvec3_t *vectorA, *vectorB;
hmat3_t *m_inv3(matrix, m_result)
hmat3_t *matrix, *m_result;
hmat3_t *m_tra3(matrix, m_result)
hmat3_t *matrix, *m_result;
hmat3_t *mm_add3(matrixA, matrixB, m_result)
hmat3_t *matrixA, *matrixB, *m_result;
hmat3_t *mm_mul3(matrixA, matrixB, m_result)
hmat3_t *matrixA, *matrixB, *m_result;
hmat3_t *mm_sub3(matrixA, matrixB, m_result)
hmat3_t *matrixA, *matrixB, *m_result;
hmat3_t *mtmm_mul3(matrixA, matrixB, m_result)
hmat3_t *matrixA, *matrixB, *m_result;
hmat3_t *sm_mul3(scalar, matrix, m_result)
double scalar;
hmat3_t *matrix, *m_result;
hmat3_t *vvt_mul3(vectorA, vectorB, m_result)
hvec3_t *vectorA, *vectorB;
hmat3_t *m_result;
hvec3_t *mv_mul3(matrix, vector, v_result)
hmat3_t *matrix;
*hvec3_t *vector, *v_result;
hvec3_t *sv_mul3(scalar, vec, v_result)
double scalar;
hvec3_t *vector, *v_result;
hvec3_t *v_homo3(vector, v_result)
hvec3_t *vector, *v_result;
hvec3_t *v_norm3(vector, v_result)
hvec3_t *vector, *v_result;
hvec3_t *vv_add3(vectorA, vectorB, v_result)
hvec3_t *vectorA, *vectorB, *v_result;
hvec3_t *vv_cross3(vectorA, vectorB, v_result)
hvec3_t *vectorA, *vectorB, *v_result;
hvec3_t *vv_sub3(vectorA, vectorB, v_result)
hvec3_t *vectorA, *vectorB, *v_result;
/* Elementary transformations */
hmat2_t *miraxis2(axis, m_result)
b_axis axis;
hmat2_t *m_result;
hmat2_t *mirorig2(m_result)
hmat2_t *m_result;
hmat2_t *rot2( rotation, m_result)
double rotation;
hmat2_t *m_result;
hmat2_t *scaorig2(scale, m_result)
double scale;
hmat2_t *m_result;
hmat2_t *scaxis2(scale, axis, m_result)
double scale;
b_axis axis;
hmat2_t *m_result;
hmat2_t *transl2(translation, m_result)
hvec2_t *translation;
hmat2_t *m_result;
hmat3_t *miraxis3(axis, m_result)
b_axis axis;
hmat3_t *m_result;
hmat3_t *mirorig3(m_result)
hmat3_t *m_result;
hmat3_t *mirplane3(plane, m_result)
b_axis plane;
hmat3_t *m_result;
hmat3_t *prjorthaxis(axis, m_result)
b_axis axis;
hmat3_t *m_result;
hmat3_t *prjpersaxis(axis, m_result)
b_axis axis;
hmat3_t *m_result;
hmat3_t *rot3( rotation, axis, m_result)
double rotation;
b_axis axis;
hmat3_t *m_result;
hmat3_t *scaorig3(scale, m_result)
double scale;
hmat3_t *m_result;
hmat3_t *scaplane(scale, plane, m_result)
double scale;
b_axis plane;
hmat3_t *m_result;
hmat3_t *scaxis3(scale, axis, m_result)
double scale;
b_axis axis;
hmat3_t *m_result;
hmat3_t *transl3(translation, m_result)
hvec3_t *translation;
hmat3_t *m_result;
DESCRIPTION¶
Matrix and vector routines associated with 3d graphics in homogeneous
coordinates, such as basic linear algebra and elementary transformations.
This library is setup with a multi-level approach.
Level1 : the data level.
Level 2: the data initialisation level.
Level 3: basic linear algebra level.
Level 4: elementary transformation level.
Level 1, the data structures, is realised as follows :
typedef union
{
double a[3];
struct
{
double x, y, w;
} s;
} hvec2_t;
typedef union
{
} hvec3_t;
typedef struct
{
} hmat2_t;
typedef struct
{
} hmat3_t;
To access the data elements of a vector or a matrix can be accessed with the
macros:
#define v_x( vec ) ((vec).s.x)
#define v_y( vec ) ((vec).s.y)
#define v_z( vec ) ((vec).s.z)
#define v_w( vec ) ((vec).s.w)
#define v_elem( vec, i ) ((vec).a[(i)])
#define m_elem( mat, i, j ) ((mat).m[(i)][(j)])
typedef enum
{
X_AXIS, Y_AXIS, Z_AXIS
} b_axis;
The functions are as follows sorted:
first on the level in which they belong, then on their return value and then on
their name.
NAMES¶
The function names begin with an abbreviation of the type of operand, and in
which order the operations will be carried out on that operand. Then the order
of and which operation will be carried out, followed by the type of
coordinates. (i.e
vtmv_mul3(vector, matrix) : first take the transpose
of
vector, multiply the transpose with
matrix, this result is
multiplied by the incoming vector, all coordinates are homogeneous 3d
coordinates.)
USAGE¶
All the "functions" may have been implemented as macro's, so you can't
take the address of a function. It is however guaranteed that arguments of
each function/macro will be evaluated only once, except for the result
argument, which can be evaluated multiple times.
All operations can be used in place, but overlapping data gives unspecified
results.
If the parameter
v_result or
m_result of a function or the
parameter of an initialisation function equals
NULL, space for the
parameter will be dynamically allocated using
malloc(), otherwise the
parameter is assumed to hold a pointer to a memory area which can be used. A
pointer to the used area (which may have been new allocated) is always
returned.
If an error occurred like memory could not be allocated, an attempt to divide by
zero occurs, or an attempt to invert a singular matrix a general error-routine
will be called, which has two parameters :
gm_errno and
gm_func.
gm_errno is the error type which is one of the following constants :
DIV0, NOMEM or
MATSING. gm_func is a pointer to a
string which contains the name of the function where the error occurred.
A pointer to the error routine is defined as follows :
void (* gm_error)(gm_errno, gm_func);
gm_error_t gm_errno;
char *gm_func;
With
gm_error_t is defined as :
typedef enum
{
DIV0, NOMEM, MATSING
} gm_error_t;
The default error handler will abort after printing a diagnostic. You can
redirect
gm_error to your own error handler. It is not advisable to
return from the error handler as error recovery is not expected to take place.
Matrices are of type
hmat3_t or
hmat2_t for 2d or 3d coordinates,
respectively.
Vectors are of type
hvec3_t or
hvec2_t.
The elements of a vector can be accessed in two manners, the first one is by
name of an element of a structure, the second is like an array.
A plane is described by the normal to that plane, with the assumption made that
the origin is an element of the plane.
rotation is assumed to be a radial.
If a function is deallocating memory, it will check if the incoming pointer is a
NULL pointer.
/* Level2 : Data initialisation */
m_alloc2(), v_alloc2(), m_alloc3(), v_alloc3() allocate memory for a data
item of type
hmat2_t, hvec2_t, hmat3_t and
hvec3_t respectively.
m_free2(), v_free2(), m_free3(), v_free3() reclaim the storage allocated
previously.
m_cpy2(), m_cpy3() copies
m_matrix into
m_result.
m_unity2(), m_unity3() returns the unity matrix. (2d respectively 3d
homogeneous coordinates)
v_cpy2(), v_cpy3() copies
v_source into
v_result. (2d
respectively 3d homogeneous coordinates)
v_fill2(), v_fill3() fills
v_result according the given values.
v_unity2(), v_unity3() returns the unity vector with
w = 1.0, the
incoming basic axis
axis = 1.0, and the other element(s) are 0.0; (2d
respectively 3d homogeneous coordinates)
v_zero2(), v_zero3() return a vector with
w = 1.0 and the other
elements 0.0;
m_cpy2(), m_cpy3() copies
m_source into
m_result. (2d
respectively 3d homogeneous coordinates)
/* level3 : Basic Linear Algebra */
m_det2(), m_det3() calculates the determinant of the incoming matrix. The
determinant is calculated in cartesian rather than homogeneous coordinates.
v_len2(), v_len3() calculates the length of the cathesian part of the
homogeneous vector.
vtmv_mul2(), vtmv_mul3() calculate the result of the transpose of the
incoming vector multiplied by the incoming matrix multiplied by the incoming
vector (2d respectively 3d homogeneous coordinates)
vv_inprod2(), vv_inprod3() calculates the geometrical innerproduct
(vector . vector) of
vectorA and
vectorB.
m_inv2(), m_inv3() calculates the inverse of
matrix. It is an
error if the matrix in singular.
m_tra2(), m_tra3() calculates the transpose
matrix. (2d
respectively 3d homogeneous coordinates)
mm_add2(), mm_sub2(), mm_add3(), mm_sub3() calculates the result of
matrixA + respectively -
matrixB. This operation is unspecified
in the sense of homogeneous coordinates; the matrices are taken in their
normal, mathematial sense.
mm_mul2(), mm_mul3() calculates the result of
matrixA*matrixB (2d
respectively 3d homogeneous coordinates)
mtmm_mul2(), mtmm_mul3() calculates the result of the transpose of the
incoming
matrixA multiplied by
matrixB multiplied by
matrixA (2d respectively 3d homogeneous coordinates)
sm_mul2(), sm_mul3() calculates the result of
scalar*matrix (2d
respectively 3d homogeneous coordinates)
mv_mul2(), mv_mul3() calculates the result of
matrix*vector (2d
respectively 3d homogeneous coordinates)
sv_mul2(), sv_mul3() calculates the result of
scalar*vector. (2d
respectively 3d homogeneous coordinates)
v_homo2(), v_homo3() homogenize
vector so that the
w
component becomes 1.0 but the length of the vector in homogeneous coordinates
stays the same. (2d respectively 3d homogeneous coordinates)
v_norm2(), v_norm3() normalises the incoming vector so the length of the
cartesian vector becomes 1.0. The homogeneous length stays the same. (2d
respectively 3d homogeneous coordinates)
vv_add2(), vv_sub2(), vv_add3(), vv_sub3() calculates the result of
vectorA + respectively -
vectorB. These operations are done in
the mathematical sense. Be careful with homogeneous coordinates, as not every
possible input makes sense.
vvt_mul2(), vvt_mul3() calculates the result of
vectorA multiplied
by the transpose of
vectorB (2d respectively 3d homogeneous
coordinates)
vv_cross3() calculates the geometrical crossproduct (
vectorA x
vectorB) of two vectors (3d homogeneous coordinates)
/* level4 : Elementary transformations */
miraxis2(), miraxis3() calculates the mirror matrix with respect to
axis. (2d respectively 3d homogeneous coordinates)
mirorg2(), mirorg3() calculates the mirror matrix relative to the origin.
(2d respectively 3d homogeneous coordinates)
mirplane3() calculates the mirror matrix relative to a plane. (3d
homogeneous coordinates)
rot2() calculates the rotation matrix over
rotation relative to
the origin. (2d homogeneous coordinates)
rot3() calculates the rotation matrix over
rotation along
axis. (3d homogeneous coordinates)
scaorg2(), scaorg3() calculates the matrix of scaling with
scale
relative to the origin. (2d respectively 3d homogeneous coordinates)
scaplane3() calculates the matrix of scaling with
scale relative
to a plane of which
plane is the normal. (3d homogeneous coordinates)
scaxis2(), scaxis3() calculates the matrix of scaling with
scale
relative to the line given by
axis. (2d respectively 3d homogeneous
coordinates)
transl2(), transl3() calculates the translation matrix over
translation. (2d respectively 3d homogeneous coordinates)
prjorthaxis() calculates the orthographic projection matrix along
axis. (3d homogeneous coordinates)
prjpersaxis() calculates the perspective projection with along
axis The focus is in the origin. The projection plane is on distance
1.0 before the camera. (3d homogeneous coordinates)
CAVEATS¶
Vector addition and subtraction and matrix addition and substraction are not
defined for homogeneous coordinates. One can add and subtract a point vector
and a free vector, but you have to normalise the point vector first. The
result of the subtraction of two point vectors is a free vector.
Calculating the determinant of a matrix and the length of a vector is
unspecified in the sense of homogeneous coordinates
RETURN VALUES¶
There are six types of return values:
void, double, *hvec3_t, *hvec2_t,
*hmat3_t and *hmat2_t.
SEE ALSO¶
graphadd(3), graphmat++(3), fmatpinv(3TV), malloc(3V), Graphics and matrix
routines.
NOTE¶
Library file is
/usr/local/lib/libgraphmat.a
AUTHOR¶
Hans Gringhuis.
Klamer Schutte