source: golgotha/src/golg/mmult.cc @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 11 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 8.8 KB
Line 
1/********************************************************************** <BR>
2  This file is part of Crack dot Com's free source code release of
3  Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
4  information about compiling & licensing issues visit this URL</a>
5  <PRE> If that doesn't help, contact Jonathan Clark at
6  golgotha_source@usa.net (Subject should have "GOLG" in it)
7***********************************************************************/
8
9#include <stdlib.h>
10#include <stdio.h>
11#include <string.h>
12
13typedef char *cell;
14typedef cell matrix[4][4];
15
16cell newcell()
17{
18  cell ret = (char*)malloc(80);
19  ret[0] = 0;
20  return ret;
21}
22
23char *add_term(char *s, char *t)
24{
25  cell ret;
26
27  if (!t)
28    ret = s;
29  else if (!s)
30    ret = strdup(t);
31  else {
32    ret = newcell();
33
34    if (atoi(s) && atoi(t)) {
35      sprintf(ret,"%+d",atoi(s)+atoi(t));
36    }
37    else {
38      strcat(ret,s);
39      strcat(ret,t);
40    }
41  }
42  return ret;
43}
44
45char *mult_term(char *s, char *t)
46{
47  cell ret;
48
49  if (!s || !t)
50    ret = 0;
51  else if (atoi(t)==1)
52    ret = strdup(s);
53  else if (atoi(t)==-1) {
54    ret = strdup(s);
55    ret[0] = ((ret[0]=='-')?'+':'-');
56  }
57  else if (atoi(s)==1) {
58    ret = strdup(t);
59  }
60  else if (atoi(s)==-1) {
61    ret = strdup(t);
62    ret[0] = ((ret[0]=='-')?'+':'-');
63  }
64  else {
65    ret = newcell();
66    if (atoi(s) && atoi(t)) {
67      sprintf(ret,"%+d",atoi(s)*atoi(t));
68    }
69    else {
70      strcat(ret, s);
71      strcat(ret, t+1);
72      ret[0] = (((s[0]=='-') ^ (t[0]=='-'))?'-':'+');
73    }
74  }
75  return ret;
76}
77
78void matmult(matrix a, matrix b, matrix result)
79{
80  for (int j=0; j<4; j++)
81    for (int i=0; i<4; i++) {
82      cell sum = 0;
83      cell prod;
84      for (int k=0; k<4; k++)
85        sum = add_term(sum, mult_term(a[j][k], b[k][i]));
86      result[j][i] = sum;
87    }
88}
89
90void matdup(matrix a,matrix b)
91{
92  for (int j=0; j<4; j++)
93    for (int i=0; i<4; i++)
94      a[j][i] = (b[j][i]?strdup(b[j][i]):0);
95}
96
97void mattranspose(matrix a,matrix dest)
98{
99  for (int j=0; j<4; j++)
100    for (int i=0; i<4; i++)
101      dest[j][i] = (a[i][j]?strdup(a[i][j]):0);
102}
103
104void matnegate(matrix a,matrix dest)
105{
106  for (int j=0; j<4; j++)
107    for (int i=0; i<4; i++)
108      dest[j][i] = mult_term(a[i][j],"-1");
109}
110
111void mat_gett(matrix a,matrix dest)
112{
113  for (int j=0; j<4; j++)
114    for (int i=0; i<4; i++)
115      if (i==j)
116        dest[j][i] = strdup("+1");
117      else if (i>=3)
118        dest[j][i] = (a[j][i]?strdup(a[j][i]):0);
119      else
120        dest[j][i] = 0;
121}
122
123void mat_getrot(matrix a,matrix dest)
124{
125  for (int j=0; j<3; j++)
126  {
127    dest[3][j] = 0;
128    dest[j][3] = 0;
129    for (int i=0; i<3; i++)
130      dest[j][i] = (a[j][i]?strdup(a[j][i]):0);
131  }
132  dest[3][3] = strdup("+1");
133}
134
135void print(matrix a)
136{
137  for (int j=0; j<4; j++)
138    for (int i=0; i<4; i++)
139      printf("(%d,%d) = %s\n", j+1,i+1, a[j][i]?a[j][i]:"0");
140}
141
142void printmat(matrix a)
143{
144  int len[4], i,j,l;
145  char buf[4][20];
146
147  for (i=0; i<4; i++)
148    len[i]=1;
149
150  for (j=0; j<4; j++)
151    for (i=0; i<4; i++)
152      if (a[j][i])
153        if ((l=strlen(a[j][i]))>len[i])
154          len[i]=l;
155
156  for (i=0; i<4; i++)
157    sprintf(buf[i]," %%-%ds ",len[i]);
158
159  for (j=0; j<4; j++)
160  {
161    printf("[ ");
162    for (i=0; i<4; i++)
163      printf(buf[i], a[j][i]?a[j][i]:"0");
164    printf(" ]\n");
165  }
166}
167
168void printaff(matrix a)
169{
170  static char pr[]="xyzt";
171
172  for (int i=0; i<4; i++)
173    for (int j=0; j<3; j++)
174      printf("aff.%c.%c = %s\n", pr[i],pr[j], a[j][i]?a[j][i]:"0");
175}
176
177
178matrix blank =
179{ { "+", "+", "+", "+" },
180  { "+", "+", "+", "+" },
181  { "+", "+", "+", "+" },
182  { "+", "+", "+", "+" } };
183
184matrix v =
185{ { "+v(1,1)", "+v(1,2)", "+v(1,3)", "+v(1,4)" },
186  { "+v(2,1)", "+v(2,2)", "+v(2,3)", "+v(2,4)" },
187  { "+v(3,1)", "+v(3,2)", "+v(3,3)", "+v(3,4)" },
188  { "+v(4,1)", "+v(4,2)", "+v(4,3)", "+v(4,4)" } };
189
190matrix aff =
191{ { "+aff.x.x", "+aff.y.x", "+aff.z.x", "+aff.t.x" },
192  { "+aff.x.y", "+aff.y.y", "+aff.z.y", "+aff.t.y" },
193  { "+aff.x.z", "+aff.y.z", "+aff.z.z", "+aff.t.z" },
194  { 0         , 0         , 0         , "+1"       } };
195
196matrix m1 =
197{ { "+1", 0,    0,    0    },
198  { 0,    "+1", 0,    0    },
199  { 0,    0,    "+1", 0    },
200  { 0,    0,    0,    "+1" } };
201
202matrix m0 =
203{ { 0, 0, 0, 0 },
204  { 0, 0, 0, 0 },
205  { 0, 0, 0, 0 },
206  { 0, 0, 0, 0 } };
207
208matrix rotz =
209{ { "+cos(z)", "-sin(z)", 0        , 0         },
210  { "+sin(z)", "+cos(z)", 0        , 0         },
211  { 0        , 0        , "+1"     , 0         },
212  { 0        , 0        , 0        , "+1"      } };
213
214matrix irotz =
215{ { "+cos(z)", "+sin(z)", 0        , 0         },
216  { "-sin(z)", "+cos(z)", 0        , 0         },
217  { 0        , 0        , "+1"     , 0         },
218  { 0        , 0        , 0        , "+1"      } };
219
220matrix roty =
221{ { "+cos(y)", 0        , "+sin(y)", 0         },
222  { 0        , "+1"     , 0        , 0         },
223  { "-sin(y)", 0        , "+cos(y)", 0         },
224  { 0        , 0        , 0        , "+1"      } };
225
226matrix iroty =
227{ { "+cos(y)", 0        , "-sin(y)", 0         },
228  { 0        , "+1"     , 0        , 0         },
229  { "+sin(y)", 0        , "+cos(y)", 0         },
230  { 0        , 0        , 0        , "+1"      } };
231
232matrix rotx =
233{ { "+1"     , 0        , 0        , 0         },
234  { 0        , "+cos(x)", "-sin(x)", 0         },
235  { 0        , "+sin(x)", "+cos(x)", 0         },
236  { 0        , 0        , 0        , "+1"      } };
237
238matrix irotx =
239{ { "+1"     , 0        , 0        , 0         },
240  { 0        , "+cos(x)", "+sin(x)", 0         },
241  { 0        , "-sin(x)", "+cos(x)", 0         },
242  { 0        , 0        , 0        , "+1"      } };
243
244matrix xlat =
245{ { "+1"     , 0        , 0        , "+tx"     },
246  { 0        , "+1"     , 0        , "+ty"     },
247  { 0        , 0        , "+1"     , "+tz"     },
248  { 0        , 0        , 0        , "+1"      } };
249
250matrix ixlat =
251{ { "+1"     , 0        , 0        , "-tx"     },
252  { 0        , "+1"     , 0        , "-ty"     },
253  { 0        , 0        , "+1"     , "-tz"     },
254  { 0        , 0        , 0        , "+1"      } };
255
256matrix scale =
257{ { "+scalex", 0        , 0        , 0         },
258  { 0        , "+scaley", 0        , 0         },
259  { 0        , 0        , "+scalez", 0         },
260  { 0        , 0        , 0        , "+1"      } };
261
262matrix iscale =
263{ { "+(1/scalex)", 0            , 0            , 0         },
264  { 0            , "+(1/scaley)", 0            , 0         },
265  { 0            , 0            , "+(1/scalez)", 0         },
266  { 0            , 0            , 0            , "+1"      } };
267
268matrix cam =
269{ { "+cam.x.x", "+cam.y.x", "+cam.z.x", "+cam.t.x" },
270  { "+cam.x.y", "+cam.y.y", "+cam.z.y", "+cam.t.y" },
271  { "+cam.x.z", "+cam.y.z", "+cam.z.z", "+cam.t.z" },
272  { 0         , 0         , 0         , "+1"       } };
273
274matrix icamt =
275{ { "+1"     , 0        , 0        , "-cam.t.x"     },
276  { 0        , "+1"     , 0        , "-cam.t.y"     },
277  { 0        , 0        , "+1"     , "-cam.t.z"     },
278  { 0        , 0        , 0        , "+1"      } };
279
280matrix point =
281{ { 0        , 0        , 0        , "+px"      },
282  { 0        , 0        , 0        , "+py"      },
283  { 0        , 0        , 0        , "+pz"      },
284  { 0        , 0        , 0        , "+1"       } };
285
286matrix front =
287{ { 0        , 0        , 0        , "+1"       },
288  { 0        , 0        , 0        , 0          },
289  { 0        , 0        , 0        , 0          },
290  { 0        , 0        , 0        , "+1"       } };
291
292void main(int argc, char **argv)
293{
294  matrix tmp,tmp2;
295  int test;
296
297  test = (argc>1);
298
299  if (test) {
300    printf("\n1*0 = \n");
301    matmult(m1,m0,tmp);
302    print(tmp);
303   
304    printf("\n1*1 = \n");
305    matmult(m1,m1,tmp);
306    print(tmp);
307   
308    printf("\nv*0 = \n");
309    matmult(v,m0,tmp);
310    print(tmp);
311   
312    printf("\nv*1 = \n");
313    matmult(v,m1,tmp);
314    print(tmp);
315   
316    printf("\n1*v = \n");
317    matmult(m1,v,tmp);
318    print(tmp);
319
320    printf("\nrotz*roty*rotx = \n");
321    matmult(rotz,roty,tmp);
322    matmult(tmp,rotx,tmp2);
323    printaff(tmp2);
324  }
325
326  matrix test1, test2;
327
328  matmult(aff, xlat, test1);
329  printaff(test1);
330  printf("\n");
331  matmult(aff, rotz, test1);
332  printaff(test1);
333  printf("\n");
334  matmult(aff, roty, test1);
335  printaff(test1);
336  printf("\n");
337  matmult(aff, rotx, test1);
338  printaff(test1);
339  printf("\n");
340  matmult(aff, scale, test1);
341  printaff(test1);
342  printf("\n");
343
344  matrix camrot,icamrot,ixform;
345
346  mat_getrot(cam, camrot);
347  mattranspose(camrot, icamrot);
348
349  printf("\nicamt = \n");
350  printmat(icamt);
351  printf("\nicamrot = \n");
352  printmat(icamrot);
353
354  matmult(icamrot,icamt,ixform);
355  printf("\nixform = \n");
356  printmat(ixform);
357
358  matmult(ixform,point,tmp);
359  printmat(tmp);
360}
361
Note: See TracBrowser for help on using the repository browser.