]> git.mxchange.org Git - simgear.git/blob - Math/mat3.h
Tweak for SGI portability.
[simgear.git] / Math / mat3.h
1 /* Copyright 1988, Brown Computer Graphics Group.  All Rights Reserved. */
2
3 /* -------------------------------------------------------------------------
4                        Public MAT3 include file
5    ------------------------------------------------------------------------- */
6
7 #ifndef MAT3_HAS_BEEN_INCLUDED
8 #define MAT3_HAS_BEEN_INCLUDED
9
10 /* -----------------------------  Constants  ------------------------------ */
11
12 /*
13  * Make sure the math library .h file is included, in case it wasn't.
14  */
15
16 #ifndef HUGE
17 #include <math.h>
18 #endif
19 #include <stdio.h>
20
21 #include <string.h>
22
23 #ifdef __cplusplus                                                          
24 extern "C" {                            
25 #endif                                   
26
27
28 #define MAT3_DET0       -1                      /* Indicates singular mat */
29 #define MAT3_EPSILON    1e-12                   /* Close enough to zero   */
30
31 #ifdef M_PI
32 #  define  MAT3_PI    M_PI
33 #else
34 #  define  MAT3_PI    3.14159265358979323846
35 #endif
36
37
38 #define USE_XTRA_MAT3_INLINES
39
40 /* ------------------------------  Types  --------------------------------- */
41
42 typedef double MAT3mat[4][4];           /* 4x4 matrix                    */
43 typedef double MAT3vec[3];              /* Vector                        */
44 typedef double MAT3hvec[4];             /* Vector with homogeneous coord */
45
46 /* ------------------------------  Macros  -------------------------------- */
47
48 /* Tests if a number is within EPSILON of zero */
49 #define MAT3_IS_ZERO(N)         ((N) < MAT3_EPSILON && (N) > -MAT3_EPSILON)
50
51 /* Sets a vector to the three given values */
52 #define MAT3_SET_VEC(V,X,Y,Z)   ((V)[0]=(X), (V)[1]=(Y), (V)[2]=(Z))
53
54 /* Tests a vector for all components close to zero */
55 #define MAT3_IS_ZERO_VEC(V)     (MAT3_IS_ZERO((V)[0]) && \
56                                  MAT3_IS_ZERO((V)[1]) && \
57                                  MAT3_IS_ZERO((V)[2]))
58
59 /* Dot product of two vectors */
60 #define MAT3_DOT_PRODUCT(V1,V2) \
61                         ((V1)[0]*(V2)[0] + (V1)[1]*(V2)[1] + (V1)[2]*(V2)[2])
62
63 /* Copy one vector to other */
64 #define MAT3_COPY_VEC(TO,FROM)  ((TO)[0] = (FROM)[0], \
65                                  (TO)[1] = (FROM)[1], \
66                                  (TO)[2] = (FROM)[2])
67
68 /* Normalize vector to unit length, using TEMP as temporary variable.
69  * TEMP will be zero if vector has zero length */
70 #define MAT3_NORMALIZE_VEC(V,TEMP) \
71         if ((TEMP = sqrt(MAT3_DOT_PRODUCT(V,V))) > MAT3_EPSILON) { \
72            TEMP = 1.0 / TEMP; \
73            MAT3_SCALE_VEC(V,V,TEMP); \
74         } else TEMP = 0.0
75
76 /* Scale vector by given factor, storing result vector in RESULT_V */
77 #define MAT3_SCALE_VEC(RESULT_V,V,SCALE) \
78         MAT3_SET_VEC(RESULT_V, (V)[0]*(SCALE), (V)[1]*(SCALE), (V)[2]*(SCALE))
79
80 /* Adds vectors V1 and V2, storing result in RESULT_V */
81 #define MAT3_ADD_VEC(RESULT_V,V1,V2) \
82         MAT3_SET_VEC(RESULT_V, (V1)[0]+(V2)[0], (V1)[1]+(V2)[1], \
83                                (V1)[2]+(V2)[2])
84
85 /* Subtracts vector V2 from V1, storing result in RESULT_V */
86 #define MAT3_SUB_VEC(RESULT_V,V1,V2) \
87         MAT3_SET_VEC(RESULT_V, (V1)[0]-(V2)[0], (V1)[1]-(V2)[1], \
88                                (V1)[2]-(V2)[2])
89
90 /* Multiplies vectors V1 and V2, storing result in RESULT_V */
91 #define MAT3_MULT_VEC(RESULT_V,V1,V2) \
92         MAT3_SET_VEC(RESULT_V, (V1)[0]*(V2)[0], (V1)[1]*(V2)[1], \
93                                (V1)[2]*(V2)[2])
94
95 /* Sets RESULT_V to the linear combination of V1 and V2, scaled by
96  * SCALE1 and SCALE2, respectively */
97 #define MAT3_LINEAR_COMB(RESULT_V,SCALE1,V1,SCALE2,V2) \
98         MAT3_SET_VEC(RESULT_V,  (SCALE1)*(V1)[0] + (SCALE2)*(V2)[0], \
99                                 (SCALE1)*(V1)[1] + (SCALE2)*(V2)[1], \
100                                 (SCALE1)*(V1)[2] + (SCALE2)*(V2)[2])
101
102 /* Several of the vector macros are useful for homogeneous-coord vectors */
103 #define MAT3_SET_HVEC(V,X,Y,Z,W) ((V)[0]=(X), (V)[1]=(Y), \
104                                   (V)[2]=(Z), (V)[3]=(W))
105
106 #define MAT3_COPY_HVEC(TO,FROM) ((TO)[0] = (FROM)[0], \
107                                  (TO)[1] = (FROM)[1], \
108                                  (TO)[2] = (FROM)[2], \
109                                  (TO)[3] = (FROM)[3])
110
111 #define MAT3_SCALE_HVEC(RESULT_V,V,SCALE) \
112         MAT3_SET_HVEC(RESULT_V, (V)[0]*(SCALE), (V)[1]*(SCALE), \
113                                 (V)[2]*(SCALE), (V)[3]*(SCALE))
114
115 #define MAT3_ADD_HVEC(RESULT_V,V1,V2) \
116         MAT3_SET_HVEC(RESULT_V, (V1)[0]+(V2)[0], (V1)[1]+(V2)[1], \
117                                 (V1)[2]+(V2)[2], (V1)[3]+(V2)[3])
118
119 #define MAT3_SUB_HVEC(RESULT_V,V1,V2) \
120         MAT3_SET_HVEC(RESULT_V, (V1)[0]-(V2)[0], (V1)[1]-(V2)[1], \
121                                 (V1)[2]-(V2)[2], (V1)[3]-(V2)[3])
122
123 #define MAT3_MULT_HVEC(RESULT_V,V1,V2) \
124         MAT3_SET_HVEC(RESULT_V, (V1)[0]*(V2)[0], (V1)[1]*(V2)[1], \
125                                 (V1)[2]*(V2)[2], (V1)[3]*(V2)[3])
126
127 /* ------------------------------  Entries  ------------------------------- */
128
129
130 /* In MAT3geom.c */
131 void    MAT3direction_matrix (MAT3mat result_mat, MAT3mat mat);
132 int     MAT3normal_matrix (MAT3mat result_mat, MAT3mat mat);
133 void    MAT3rotate (MAT3mat result_mat, MAT3vec axis, double angle_in_radians);
134 void    MAT3translate (MAT3mat result_mat, MAT3vec trans);
135 void    MAT3scale (MAT3mat result_mat, MAT3vec scale);
136 void    MAT3shear(MAT3mat result_mat, double xshear, double yshear);
137
138 #if defined( USE_XTRA_MAT3_INLINES )
139
140 #define MAT3mult_vec( result_vec, vec, mat) { \
141    MAT3vec tempvec; \
142    tempvec[0]=vec[0]*mat[0][0]+vec[1]*mat[1][0]+vec[2]*mat[2][0]+mat[3][0]; \
143    tempvec[1]=vec[0]*mat[0][1]+vec[1]*mat[1][1]+vec[2]*mat[2][1]+mat[3][1]; \
144    tempvec[2]=vec[0]*mat[0][2]+vec[1]*mat[1][2]+vec[2]*mat[2][2]+mat[3][2]; \
145    result_vec[0] = tempvec[0]; \
146    result_vec[1] = tempvec[1]; \
147    result_vec[2] = tempvec[2]; \
148 }
149
150 #define MAT3cross_product(result_vec, vec1, vec2)  { \
151    MAT3vec tempvec; \
152    tempvec[0] = vec1[1] * vec2[2] - vec1[2] * vec2[1]; \
153    tempvec[1] = vec1[2] * vec2[0] - vec1[0] * vec2[2]; \
154    tempvec[2] = vec1[0] * vec2[1] - vec1[1] * vec2[0]; \
155    result_vec[0] = tempvec[0]; \
156    result_vec[1] = tempvec[1]; \
157    result_vec[2] = tempvec[2]; \
158
159
160 #if defined( USE_MEM ) || defined( WIN32 )
161 #define MAT3copy( to, from)    memcpy(to, from, sizeof(MAT3mat))
162 #define MAT3zero(mat)   memset(mat,0x00, sizeof(MAT3mat))
163 #define MAT3mult( result_mat,  mat1,  mat2) { \
164    register int i, j; \
165    MAT3mat      tmp_mat; \
166    for (i = 0; i < 4; i++) \
167       for (j = 0; j < 4; j++) \
168          tmp_mat[i][j] = (mat1[i][0] * mat2[0][j] + mat1[i][1] * mat2[1][j] \
169                                  + mat1[i][2] * mat2[2][j] + mat1[i][3] * mat2[3][j]); \
170     memcpy(result_mat, tmp_mat, sizeof(MAT3mat)); \
171 }
172 #define MAT3identity(mat) { \
173    register int i; \
174    memset(mat, 0x00, sizeof(MAT3mat)); \
175    for (i = 0; i < 4; i++)  mat[i][i] = 1.0; \
176 }
177
178 #else //  !defined( USE_MEM ) || !defined( WIN32 )
179
180 #define MAT3copy( to, from)    bcopy(from, to, sizeof(MAT3mat))
181 #define MAT3zero(mat)   bzero (mat, sizeof(MAT3mat))
182 #define MAT3mult( result_mat,  mat1,  mat2) { \
183    register int i, j; \
184    MAT3mat      tmp_mat; \
185    for (i = 0; i < 4; i++) \
186       for (j = 0; j < 4; j++) \
187          tmp_mat[i][j] = (mat1[i][0] * mat2[0][j] + mat1[i][1] * mat2[1][j] \
188                                  + mat1[i][2] * mat2[2][j] + mat1[i][3] * mat2[3][j]); \
189     bcopy(tmp_mat, result_mat, sizeof(MAT3mat)); \
190 }
191 #define MAT3identity(mat) { \
192    register int i; \
193    bzero(mat, sizeof(MAT3mat)); \
194    for(i = 0; i < 4; i++)   mat[i][i] = 1.0; \
195 }
196 #endif
197
198 #else // !defined( USE_XTRA_MAT3_INLINES )
199
200 /* In MAT3mat.c */
201 void    MAT3identity(MAT3mat);
202 void    MAT3zero(MAT3mat);
203
204 void    MAT3copy (MAT3mat to, MAT3mat from);
205 void    MAT3mult (MAT3mat result, MAT3mat, MAT3mat);
206
207 #endif // defined( USE_XTRA_MAT3_INLINES )
208
209 void    MAT3transpose (MAT3mat result, MAT3mat);
210 int     MAT3invert (MAT3mat result, MAT3mat);
211 void    MAT3print (MAT3mat, FILE *fp);
212 void    MAT3print_formatted (MAT3mat, FILE *fp, 
213                              char *title, char *head, char *format, char *tail);
214 int     MAT3equal( void );
215 double  MAT3trace( void );
216 int     MAT3power( void );
217 int     MAT3column_reduce( void );
218 int     MAT3kernel_basis( void );
219
220 /* In MAT3vec.c */
221 int     MAT3mult_hvec (MAT3hvec result_vec, MAT3hvec vec, MAT3mat mat, int normalize);
222 void    MAT3perp_vec(MAT3vec result_vec, MAT3vec vec, int is_unit);
223 #if !defined( USE_XTRA_MAT3_INLINES )
224 void    MAT3mult_vec(MAT3vec result_vec, MAT3vec vec, MAT3mat mat);
225 void    MAT3cross_product(MAT3vec result,MAT3vec,MAT3vec);
226 #endif // !defined( USE_XTRA_MAT3_INLINES )
227
228
229 #ifdef __cplusplus
230 }
231 #endif
232
233
234 #endif /* MAT3_HAS_BEEN_INCLUDED */
235