GRASS Programmer's Manual
6.4.2(2012)
|
00001 00031 #include <math.h> 00032 00033 #include <grass/gis.h> 00034 #include <grass/glocale.h> 00035 #include <grass/gstypes.h> 00036 00037 #define MAX_STACK 20 00038 00039 00040 /* function prototypes */ 00041 static void P__transform(int num_vert, float (*in)[4], 00042 float (*out)[4], float (*c)[4]); 00043 static void P_matrix_copy(float (*from)[4], float (*to)[4], int size); 00044 00045 00046 /* global variables */ 00047 static float c_stack[MAX_STACK][4][4]; /* matrix stack */ 00048 static int stack_ptr = -1; /* index of curr matrix depth */ 00049 static float d[4][4]; /* tmp matrix */ 00050 00051 #define NPI M_PI 00052 00053 /* 00054 ** Current transformation matrix 00055 */ 00056 static float trans_mat[4][4] = { 00057 {1., 0., 0., 0.}, 00058 {0., 1., 0., 0.}, 00059 {0., 0., 1., 0.}, 00060 {0., 0., 0., 1.} 00061 }; 00062 00063 static float ident[4][4] = { 00064 {1., 0., 0., 0.}, 00065 {0., 1., 0., 0.}, 00066 {0., 0., 1., 0.}, 00067 {0., 0., 0., 1.} 00068 }; 00069 00075 void P_scale(float x, float y, float z) 00076 { 00077 d[0][0] = x; 00078 d[0][1] = 0.; 00079 d[0][2] = 0.; 00080 d[0][3] = 0.; 00081 d[1][0] = 0.; 00082 d[1][1] = y; 00083 d[1][2] = 0.; 00084 d[1][3] = 0.; 00085 d[2][0] = 0.; 00086 d[2][1] = 0.; 00087 d[2][2] = z; 00088 d[2][3] = 0.; 00089 d[3][0] = 0.; 00090 d[3][1] = 0.; 00091 d[3][2] = 0.; 00092 d[3][3] = 1.; 00093 00094 /* 00095 ** will write into 1 down on matrix stack 00096 ** and then the popmatrix() will place it as the current T matrix 00097 */ 00098 P_pushmatrix(); 00099 P__transform(4, d, c_stack[stack_ptr], trans_mat); 00100 P_popmatrix(); 00101 00102 return; 00103 } 00104 00117 void P_transform(int num_vert, float (*in)[4], float (*out)[4]) 00118 { 00119 P__transform(num_vert, in, out, trans_mat); 00120 00121 return; 00122 } 00123 00136 static void P__transform(int num_vert, float (*in)[4], float (*out)[4], 00137 float (*c)[4]) 00138 { 00139 register int k, j, i; 00140 00141 for (i = 0; i < num_vert; i++) { 00142 for (j = 0; j < 4; j++) { 00143 out[i][j] = 0.; 00144 00145 for (k = 0; k < 4; k++) { 00146 out[i][j] += in[i][k] * c[k][j]; 00147 } 00148 } 00149 } 00150 00151 return; 00152 } 00153 00161 static void P_matrix_copy(float (*from)[4], float (*to)[4], int size) 00162 { 00163 register int i, j; 00164 00165 for (i = 0; i < size; i++) { 00166 for (j = 0; j < 4; j++) { 00167 to[i][j] = from[i][j]; 00168 } 00169 } 00170 00171 return; 00172 } 00173 00177 int P_pushmatrix(void) 00178 { 00179 if (stack_ptr >= MAX_STACK) { 00180 G_warning("P_pushmatrix(): %s", _("Out of matrix stack space")); 00181 00182 return (-1); 00183 } 00184 00185 stack_ptr++; 00186 P_matrix_copy(trans_mat, c_stack[stack_ptr], 4); 00187 00188 return (0); 00189 } 00190 00197 int P_popmatrix(void) 00198 { 00199 if (stack_ptr < 0) { 00200 G_warning("P_popmatrix(): %s", _("Tried to pop an empty stack")); 00201 00202 return (-1); 00203 } 00204 00205 P_matrix_copy(c_stack[stack_ptr], trans_mat, 4); 00206 stack_ptr--; 00207 00208 return (0); 00209 } 00210 00217 void P_rot(float angle, char axis) 00218 { 00219 double theta; 00220 00221 P_matrix_copy(ident, d, 4); 00222 00223 theta = (NPI / 180.) * angle; /* convert to radians */ 00224 00225 /* optimize to handle rotations of mutliples of 90 deg */ 00226 switch (axis) { 00227 case 'X': 00228 case 'x': 00229 00230 d[1][1] = cos(theta); 00231 d[1][2] = sin(theta); 00232 d[2][1] = -sin(theta); 00233 d[2][2] = cos(theta); 00234 00235 break; 00236 case 'Y': 00237 case 'y': 00238 00239 d[0][0] = cos(theta); 00240 d[0][2] = -sin(theta); 00241 d[2][0] = sin(theta); 00242 d[2][2] = cos(theta); 00243 break; 00244 case 'Z': 00245 case 'z': 00246 00247 d[0][0] = cos(theta); 00248 d[0][1] = sin(theta); 00249 d[1][0] = -sin(theta); 00250 d[1][1] = cos(theta); 00251 00252 break; 00253 } 00254 00255 P_pushmatrix(); 00256 P__transform(4, d, c_stack[stack_ptr], trans_mat); 00257 P_popmatrix(); 00258 00259 return; 00260 }