GRASS GIS 8 Programmer's Manual  8.4.0dev(2024)-25961a86c2
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
27  Engineering Research Lab \author Bill Brown USACERL (November 1993) \author
28  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 /* function prototypes */
40 static void P__transform(int num_vert, float (*in)[4], float (*out)[4],
41  float (*c)[4]);
42 static void P_matrix_copy(float (*from)[4], float (*to)[4], int size);
43 
44 /* global variables */
45 static float c_stack[MAX_STACK][4][4]; /* matrix stack */
46 static int stack_ptr = -1; /* index of curr matrix depth */
47 static float d[4][4]; /* tmp matrix */
48 
49 #define NPI M_PI
50 
51 /*
52  ** Current transformation matrix
53  */
54 static float trans_mat[4][4] = {
55  {1., 0., 0., 0.}, {0., 1., 0., 0.}, {0., 0., 1., 0.}, {0., 0., 0., 1.}};
56 
57 static float ident[4][4] = {
58  {1., 0., 0., 0.}, {0., 1., 0., 0.}, {0., 0., 1., 0.}, {0., 0., 0., 1.}};
59 
60 /*!
61  \brief ADD
62 
63  \param x,y,z
64  */
65 void P_scale(float x, float y, float z)
66 {
67  d[0][0] = x;
68  d[0][1] = 0.;
69  d[0][2] = 0.;
70  d[0][3] = 0.;
71  d[1][0] = 0.;
72  d[1][1] = y;
73  d[1][2] = 0.;
74  d[1][3] = 0.;
75  d[2][0] = 0.;
76  d[2][1] = 0.;
77  d[2][2] = z;
78  d[2][3] = 0.;
79  d[3][0] = 0.;
80  d[3][1] = 0.;
81  d[3][2] = 0.;
82  d[3][3] = 1.;
83 
84  /*
85  ** will write into 1 down on matrix stack
86  ** and then the popmatrix() will place it as the current T matrix
87  */
88  P_pushmatrix();
89  P__transform(4, d, c_stack[stack_ptr], trans_mat);
90  P_popmatrix();
91 
92  return;
93 }
94 
95 /*!
96  \brief Transform array of vectors using current T matrix
97 
98  Multiply 'in' matrix (homogeneous coordinate generally) by
99  the current transformation matrix, placing the result in 'out'
100 
101  [in][trans_mat] => [out]
102 
103  \param num_vert
104  \param in
105  \param out
106  */
107 void P_transform(int num_vert, float (*in)[4], float (*out)[4])
108 {
109  P__transform(num_vert, in, out, trans_mat);
110 
111  return;
112 }
113 
114 /*!
115  \brief Transform array of vectors using current T matrix
116 
117  Multiply 'in' matrix (homogeneous coordinate generally) by
118  the current transformation matrix, placing the result in 'out'
119 
120  [in][trans_mat] => [out]
121 
122  \param num_vert
123  \param in
124  \param out
125  */
126 static void P__transform(int num_vert, float (*in)[4], float (*out)[4],
127  float (*c)[4])
128 {
129  register int k, j, i;
130 
131  for (i = 0; i < num_vert; i++) {
132  for (j = 0; j < 4; j++) {
133  out[i][j] = 0.;
134 
135  for (k = 0; k < 4; k++) {
136  out[i][j] += in[i][k] * c[k][j];
137  }
138  }
139  }
140 
141  return;
142 }
143 
144 /*!
145  \brief Copy matrix
146 
147  \param from 'from' matrix
148  \param to 'to' matrix
149  \param size number of rows (ncols=4)
150  */
151 static void P_matrix_copy(float (*from)[4], float (*to)[4], int size)
152 {
153  register int i, j;
154 
155  for (i = 0; i < size; i++) {
156  for (j = 0; j < 4; j++) {
157  to[i][j] = from[i][j];
158  }
159  }
160 
161  return;
162 }
163 
164 /*!
165  \brief Push current transformation matrix onto matrix stack
166  */
167 int P_pushmatrix(void)
168 {
169  if (stack_ptr >= MAX_STACK) {
170  G_warning("P_pushmatrix(): %s", _("Out of matrix stack space"));
171 
172  return (-1);
173  }
174 
175  stack_ptr++;
176  P_matrix_copy(trans_mat, c_stack[stack_ptr], 4);
177 
178  return (0);
179 }
180 
181 /*!
182  \brief Pop top of matrix stack, placing it into the current transformation
183  matrix
184 
185  \return -1 on failure
186  \return 0 on success
187  */
188 int P_popmatrix(void)
189 {
190  if (stack_ptr < 0) {
191  G_warning("P_popmatrix(): %s", _("Tried to pop an empty stack"));
192 
193  return (-1);
194  }
195 
196  P_matrix_copy(c_stack[stack_ptr], trans_mat, 4);
197  stack_ptr--;
198 
199  return (0);
200 }
201 
202 /*!
203  \brief Rotate matrix
204 
205  \param angle angle value
206  \param axis ('x, 'y', 'z')
207  */
208 void P_rot(float angle, char axis)
209 {
210  double theta;
211 
212  P_matrix_copy(ident, d, 4);
213 
214  theta = (NPI / 180.) * angle; /* convert to radians */
215 
216  /* optimize to handle rotations of multiples of 90 deg */
217  switch (axis) {
218  case 'X':
219  case 'x':
220 
221  d[1][1] = cos(theta);
222  d[1][2] = sin(theta);
223  d[2][1] = -sin(theta);
224  d[2][2] = cos(theta);
225 
226  break;
227  case 'Y':
228  case 'y':
229 
230  d[0][0] = cos(theta);
231  d[0][2] = -sin(theta);
232  d[2][0] = sin(theta);
233  d[2][2] = cos(theta);
234  break;
235  case 'Z':
236  case 'z':
237 
238  d[0][0] = cos(theta);
239  d[0][1] = sin(theta);
240  d[1][0] = -sin(theta);
241  d[1][1] = cos(theta);
242 
243  break;
244  }
245 
246  P_pushmatrix();
247  P__transform(4, d, c_stack[stack_ptr], trans_mat);
248  P_popmatrix();
249 
250  return;
251 }
void G_warning(const char *,...) __attribute__((format(printf
#define _(str)
Definition: glocale.h:10
int P_popmatrix(void)
Pop top of matrix stack, placing it into the current transformation matrix.
Definition: trans.c:188
void P_transform(int num_vert, float(*in)[4], float(*out)[4])
Transform array of vectors using current T matrix.
Definition: trans.c:107
void P_scale(float x, float y, float z)
ADD.
Definition: trans.c:65
void P_rot(float angle, char axis)
Rotate matrix.
Definition: trans.c:208
int P_pushmatrix(void)
Push current transformation matrix onto matrix stack.
Definition: trans.c:167
#define NPI
Definition: trans.c:49
#define MAX_STACK
Definition: trans.c:37
#define x