source: GTP/trunk/Lib/Vis/Preprocessing/src/mixkit/MxMat4.cxx @ 1097

Revision 1097, 4.6 KB checked in by mattausch, 18 years ago (diff)
Line 
1/************************************************************************
2
3  4x4 Matrix class
4
5  Copyright (C) 1998 Michael Garland.  See "COPYING.txt" for details.
6 
7  $Id: MxMat4.cxx,v 1.1 2002/09/24 16:53:54 wimmer Exp $
8
9 ************************************************************************/
10
11#include "stdmix.h"
12#include "MxMat4.h"
13
14Mat4 Mat4::I(Vec4(1,0,0,0),Vec4(0,1,0,0),Vec4(0,0,1,0),Vec4(0,0,0,1));
15Mat4 Mat4::zero(Vec4(0,0,0,0),Vec4(0,0,0,0),Vec4(0,0,0,0),Vec4(0,0,0,0));
16Mat4 Mat4::unit(Vec4(1,1,1,1),Vec4(1,1,1,1),Vec4(1,1,1,1),Vec4(1,1,1,1));
17
18Mat4 Mat4::trans(double x, double y, double z)
19{
20    return Mat4(Vec4(1,0,0,x),
21                Vec4(0,1,0,y),
22                Vec4(0,0,1,z),
23                Vec4(0,0,0,1));
24}
25
26Mat4 Mat4::scale(double x, double y, double z)
27{
28    return Mat4(Vec4(x,0,0,0),
29                Vec4(0,y,0,0),
30                Vec4(0,0,z,0),
31                Vec4(0,0,0,1));
32}
33
34Mat4 Mat4::xrot(double a)
35{
36    double c = cos(a);
37    double s = sin(a);
38
39    return Mat4(Vec4(1, 0, 0, 0),
40                Vec4(0, c,-s, 0),
41                Vec4(0, s, c, 0),
42                Vec4(0, 0, 0, 1));
43}
44
45Mat4 Mat4::yrot(double a)
46{
47    double c = cos(a);
48    double s = sin(a);
49
50    return Mat4(Vec4(c, 0, s, 0),
51                Vec4(0, 1, 0, 0),
52                Vec4(-s,0, c, 0),
53                Vec4(0, 0, 0, 1));
54}
55
56Mat4 Mat4::zrot(double a)
57{
58    double c = cos(a);
59    double s = sin(a);
60
61    return Mat4(Vec4(c,-s, 0, 0),
62                Vec4(s, c, 0, 0),
63                Vec4(0, 0, 1, 0),
64                Vec4(0, 0, 0, 1));
65}
66
67Mat4 Mat4::operator*(const Mat4& m) const
68{
69    Mat4 A;
70    int i,j;
71
72    for(i=0;i<4;i++)
73        for(j=0;j<4;j++)
74            A(i,j) = row[i]*m.col(j);
75
76    return A;
77}
78
79double Mat4::det() const
80{
81    return row[0] * cross(row[1], row[2], row[3]);
82}
83
84Mat4 Mat4::transpose() const
85{
86    return Mat4(col(0), col(1), col(2), col(3));
87}
88
89Mat4 Mat4::adjoint() const
90{
91    Mat4 A;
92
93    A.row[0] = cross( row[1], row[2], row[3]);
94    A.row[1] = cross(-row[0], row[2], row[3]);
95    A.row[2] = cross( row[0], row[1], row[3]);
96    A.row[3] = cross(-row[0], row[1], row[2]);
97       
98    return A;
99}
100
101double Mat4::cramerInvert(Mat4& inv) const
102{
103    Mat4 A = adjoint();
104    double d = A.row[0] * row[0];
105
106    if( d==0.0 )
107        return 0.0;
108
109    inv = A.transpose() / d;
110    return d;
111}
112
113
114
115// Matrix inversion code for 4x4 matrices.
116// Originally ripped off and degeneralized from Paul's matrix library
117// for the view synthesis (Chen) software.
118//
119// Returns determinant of a, and b=a inverse.
120// If matrix is singular, returns 0 and leaves trash in b.
121//
122// Uses Gaussian elimination with partial pivoting.
123
124#define SWAP(a, b, t)   {t = a; a = b; b = t;}
125double Mat4::invert(Mat4& B) const
126{
127    Mat4 A(*this);
128
129    int i, j, k;
130    double max, t, det, pivot;
131
132    /*---------- forward elimination ----------*/
133
134    for (i=0; i<4; i++)                 /* put identity matrix in B */
135        for (j=0; j<4; j++)
136            B(i, j) = (double)(i==j);
137
138    det = 1.0;
139    for (i=0; i<4; i++) {               /* eliminate in column i, below diag */
140        max = -1.;
141        for (k=i; k<4; k++)             /* find pivot for column i */
142            if (fabs(A(k, i)) > max) {
143                max = fabs(A(k, i));
144                j = k;
145            }
146        if (max<=0.) return 0.;         /* if no nonzero pivot, PUNT */
147        if (j!=i) {                     /* swap rows i and j */
148            for (k=i; k<4; k++)
149                SWAP(A(i, k), A(j, k), t);
150            for (k=0; k<4; k++)
151                SWAP(B(i, k), B(j, k), t);
152            det = -det;
153        }
154        pivot = A(i, i);
155        det *= pivot;
156        for (k=i+1; k<4; k++)           /* only do elems to right of pivot */
157            A(i, k) /= pivot;
158        for (k=0; k<4; k++)
159            B(i, k) /= pivot;
160        /* we know that A(i, i) will be set to 1, so don't bother to do it */
161
162        for (j=i+1; j<4; j++) {         /* eliminate in rows below i */
163            t = A(j, i);                /* we're gonna zero this guy */
164            for (k=i+1; k<4; k++)       /* subtract scaled row i from row j */
165                A(j, k) -= A(i, k)*t;   /* (ignore k<=i, we know they're 0) */
166            for (k=0; k<4; k++)
167                B(j, k) -= B(i, k)*t;
168        }
169    }
170
171    /*---------- backward elimination ----------*/
172
173    for (i=4-1; i>0; i--) {             /* eliminate in column i, above diag */
174        for (j=0; j<i; j++) {           /* eliminate in rows above i */
175            t = A(j, i);                /* we're gonna zero this guy */
176            for (k=0; k<4; k++)         /* subtract scaled row i from row j */
177                B(j, k) -= B(i, k)*t;
178        }
179    }
180
181    return det;
182}
Note: See TracBrowser for help on using the repository browser.