GRASS GIS 8 Programmer's Manual 8.2.1(2023)-exported
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 */
41static void P__transform(int num_vert, float (*in)[4],
42 float (*out)[4], float (*c)[4]);
43static void P_matrix_copy(float (*from)[4], float (*to)[4], int size);
44
45
46/* global variables */
47static float c_stack[MAX_STACK][4][4]; /* matrix stack */
48static int stack_ptr = -1; /* index of curr matrix depth */
49static float d[4][4]; /* tmp matrix */
50
51#define NPI M_PI
52
53/*
54 ** Current transformation matrix
55 */
56static 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
63static 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 */
75void 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 */
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 */
117void 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 */
136static 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 */
161static 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 */
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 */
197int 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 */
217void 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 G_warning(const char *msg,...)
Print a warning message to stderr.
Definition: gis/error.c:204
int P_popmatrix(void)
Pop top of matrix stack, placing it into the current transformation matrix.
Definition: trans.c:197
void P_transform(int num_vert, float(*in)[4], float(*out)[4])
Transform array of vectors using current T matrix.
Definition: trans.c:117
void P_scale(float x, float y, float z)
ADD.
Definition: trans.c:75
void P_rot(float angle, char axis)
Rotate matrix.
Definition: trans.c:217
int P_pushmatrix(void)
Push current transformation matrix onto matrix stack.
Definition: trans.c:177
#define NPI
Definition: trans.c:51
#define MAX_STACK
Definition: trans.c:37
#define x