GRASS GIS 7 Programmer's Manual  7.9.dev(2021)-e5379bbd7
trans.c
Go to the documentation of this file.
1 /*!
2  \file lib/ogsf/trans.c
3 
4  \brief OGSF library - matrix transformation (higher level functions)
5 
6  GRASS OpenGL gsurf OGSF Library
7 
8  NOTE: This file should be REMOVED and any calls to the functions in this
9  file should be replaced with appropriate OpenGL calls.
10 
11  This routine should be available in GL!
12 
13  Arguments are same as GL counterparts
14 
15  I threw this code together in January at the beginning of this
16  class. I was still learning about GL at the time.
17  There are many places where the code could be improved.
18 
19  (C) 1999-2008 by the GRASS Development Team
20 
21  This program is free software under the
22  GNU General Public License (>=v2).
23  Read the file COPYING that comes with GRASS
24  for details.
25 
26  \author Dave Gerdes Jan 1990 All rights reserved, US Army Construction Engineering Research Lab
27  \author Bill Brown USACERL (November 1993)
28  \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
29  */
30 
31 #include <math.h>
32 
33 #include <grass/gis.h>
34 #include <grass/glocale.h>
35 #include <grass/ogsf.h>
36 
37 #define MAX_STACK 20
38 
39 
40 /* function prototypes */
41 static void P__transform(int num_vert, float (*in)[4],
42  float (*out)[4], float (*c)[4]);
43 static void P_matrix_copy(float (*from)[4], float (*to)[4], int size);
44 
45 
46 /* global variables */
47 static float c_stack[MAX_STACK][4][4]; /* matrix stack */
48 static int stack_ptr = -1; /* index of curr matrix depth */
49 static float d[4][4]; /* tmp matrix */
50 
51 #define NPI M_PI
52 
53 /*
54  ** Current transformation matrix
55  */
56 static float trans_mat[4][4] = {
57  {1., 0., 0., 0.},
58  {0., 1., 0., 0.},
59  {0., 0., 1., 0.},
60  {0., 0., 0., 1.}
61 };
62 
63 static float ident[4][4] = {
64  {1., 0., 0., 0.},
65  {0., 1., 0., 0.},
66  {0., 0., 1., 0.},
67  {0., 0., 0., 1.}
68 };
69 
70 /*!
71  \brief ADD
72 
73  \param x,y,z
74  */
75 void P_scale(float x, float y, float z)
76 {
77  d[0][0] = x;
78  d[0][1] = 0.;
79  d[0][2] = 0.;
80  d[0][3] = 0.;
81  d[1][0] = 0.;
82  d[1][1] = y;
83  d[1][2] = 0.;
84  d[1][3] = 0.;
85  d[2][0] = 0.;
86  d[2][1] = 0.;
87  d[2][2] = z;
88  d[2][3] = 0.;
89  d[3][0] = 0.;
90  d[3][1] = 0.;
91  d[3][2] = 0.;
92  d[3][3] = 1.;
93 
94  /*
95  ** will write into 1 down on matrix stack
96  ** and then the popmatrix() will place it as the current T matrix
97  */
98  P_pushmatrix();
99  P__transform(4, d, c_stack[stack_ptr], trans_mat);
100  P_popmatrix();
101 
102  return;
103 }
104 
105 /*!
106  \brief Transform array of vectors using current T matrix
107 
108  Multiply 'in' matrix (homogenous coordinate generally) by
109  the current transformation matrix, placing the result in 'out'
110 
111  [in][trans_mat] => [out]
112 
113  \param num_vert
114  \param in
115  \param out
116  */
117 void P_transform(int num_vert, float (*in)[4], float (*out)[4])
118 {
119  P__transform(num_vert, in, out, trans_mat);
120 
121  return;
122 }
123 
124 /*!
125  \brief Transform array of vectors using current T matrix
126 
127  Multiply 'in' matrix (homogenous coordinate generally) by
128  the current transformation matrix, placing the result in 'out'
129 
130  [in][trans_mat] => [out]
131 
132  \param num_vert
133  \param in
134  \param out
135  */
136 static void P__transform(int num_vert, float (*in)[4], float (*out)[4],
137  float (*c)[4])
138 {
139  register int k, j, i;
140 
141  for (i = 0; i < num_vert; i++) {
142  for (j = 0; j < 4; j++) {
143  out[i][j] = 0.;
144 
145  for (k = 0; k < 4; k++) {
146  out[i][j] += in[i][k] * c[k][j];
147  }
148  }
149  }
150 
151  return;
152 }
153 
154 /*!
155  \brief Copy matrix
156 
157  \param from 'from' matrix
158  \param to 'to' matrix
159  \param size number of rows (ncols=4)
160  */
161 static void P_matrix_copy(float (*from)[4], float (*to)[4], int size)
162 {
163  register int i, j;
164 
165  for (i = 0; i < size; i++) {
166  for (j = 0; j < 4; j++) {
167  to[i][j] = from[i][j];
168  }
169  }
170 
171  return;
172 }
173 
174 /*!
175  \brief Push current transformation matrix onto matrix stack
176  */
177 int P_pushmatrix(void)
178 {
179  if (stack_ptr >= MAX_STACK) {
180  G_warning("P_pushmatrix(): %s", _("Out of matrix stack space"));
181 
182  return (-1);
183  }
184 
185  stack_ptr++;
186  P_matrix_copy(trans_mat, c_stack[stack_ptr], 4);
187 
188  return (0);
189 }
190 
191 /*!
192  \brief Pop top of matrix stack, placing it into the current transformation matrix
193 
194  \return -1 on failure
195  \return 0 on success
196  */
197 int P_popmatrix(void)
198 {
199  if (stack_ptr < 0) {
200  G_warning("P_popmatrix(): %s", _("Tried to pop an empty stack"));
201 
202  return (-1);
203  }
204 
205  P_matrix_copy(c_stack[stack_ptr], trans_mat, 4);
206  stack_ptr--;
207 
208  return (0);
209 }
210 
211 /*!
212  \brief Rotate matrix
213 
214  \param angle angle value
215  \param axis ('x, 'y', 'z')
216  */
217 void P_rot(float angle, char axis)
218 {
219  double theta;
220 
221  P_matrix_copy(ident, d, 4);
222 
223  theta = (NPI / 180.) * angle; /* convert to radians */
224 
225  /* optimize to handle rotations of mutliples of 90 deg */
226  switch (axis) {
227  case 'X':
228  case 'x':
229 
230  d[1][1] = cos(theta);
231  d[1][2] = sin(theta);
232  d[2][1] = -sin(theta);
233  d[2][2] = cos(theta);
234 
235  break;
236  case 'Y':
237  case 'y':
238 
239  d[0][0] = cos(theta);
240  d[0][2] = -sin(theta);
241  d[2][0] = sin(theta);
242  d[2][2] = cos(theta);
243  break;
244  case 'Z':
245  case 'z':
246 
247  d[0][0] = cos(theta);
248  d[0][1] = sin(theta);
249  d[1][0] = -sin(theta);
250  d[1][1] = cos(theta);
251 
252  break;
253  }
254 
255  P_pushmatrix();
256  P__transform(4, d, c_stack[stack_ptr], trans_mat);
257  P_popmatrix();
258 
259  return;
260 }
void P_transform(int num_vert, float(*in)[4], float(*out)[4])
Transform array of vectors using current T matrix.
Definition: trans.c:117
#define NPI
Definition: trans.c:51
void P_rot(float angle, char axis)
Rotate matrix.
Definition: trans.c:217
int P_popmatrix(void)
Pop top of matrix stack, placing it into the current transformation matrix.
Definition: trans.c:197
#define x
int P_pushmatrix(void)
Push current transformation matrix onto matrix stack.
Definition: trans.c:177
#define MAX_STACK
Definition: trans.c:37
void G_warning(const char *,...) __attribute__((format(printf
#define _(str)
Definition: glocale.h:10
void P_scale(float x, float y, float z)
ADD.
Definition: trans.c:75