chiark / gitweb /
Proper Subversion configuration.
[newkind] / vector.c
1 /*
2  * Elite - The New Kind.
3  *
4  * Reverse engineered from the BBC disk version of Elite.
5  * Additional material by C.J.Pinder.
6  *
7  * The original Elite code is (C) I.Bell & D.Braben 1984.
8  * This version re-engineered in C by C.J.Pinder 1999-2001.
9  *
10  * email: <christian@newkind.co.uk>
11  *
12  */
13
14
15 /*
16  * The original Elite code did all the vector calculations using 8-bit integers.
17  *
18  * Writing all the routines in C to use 8 bit ints would have been fairly pointless.
19  * I have, therefore, written a new set of routines which use floating point math.
20  */
21
22 #include <stdlib.h>
23 #include <math.h>
24
25 #include "config.h"
26 #include "vector.h"
27
28
29
30 static Matrix start_matrix =
31 {
32         {1.0, 0.0, 0.0},
33         {0.0, 1.0, 0.0},
34         {0.0, 0.0,-1.0}
35 };
36
37
38
39 /*
40  * Multiply first matrix by second matrix.
41  * Put result into first matrix.
42  */
43
44
45 void mult_matrix (struct vector *first, struct vector *second)
46 {
47         int i;
48         Matrix rv;
49
50         for (i = 0; i < 3; i++)
51         {
52
53                 rv[i].x =       (first[0].x * second[i].x) +
54                                         (first[1].x * second[i].y) +
55                                         (first[2].x * second[i].z);
56
57                 rv[i].y =       (first[0].y * second[i].x) +
58                                         (first[1].y * second[i].y) +
59                                         (first[2].y * second[i].z);
60
61                 rv[i].z =       (first[0].z * second[i].x) +
62                                         (first[1].z * second[i].y) +
63                                         (first[2].z * second[i].z);
64         }
65
66         for (i = 0; i < 3; i++)
67                 first[i] = rv[i];
68 }
69
70
71
72
73 void mult_vector (struct vector *vec, struct vector *mat)
74 {
75         double x;
76         double y;
77         double z;
78
79         x = (vec->x * mat[0].x) +
80                 (vec->y * mat[0].y) +
81                 (vec->z * mat[0].z);
82
83         y = (vec->x * mat[1].x) +
84                 (vec->y * mat[1].y) +
85                 (vec->z * mat[1].z);
86
87         z = (vec->x * mat[2].x) +
88                 (vec->y * mat[2].y) +
89                 (vec->z * mat[2].z);
90
91         vec->x = x;
92         vec->y = y;
93         vec->z = z;
94 }
95
96
97 /*
98  * Calculate the dot product of two vectors sharing a common point.
99  * Returns the cosine of the angle between the two vectors.
100  */
101
102
103 double vector_dot_product (struct vector *first, struct vector *second)
104 {
105         return (first->x * second->x) + (first->y * second->y) + (first->z * second->z);        
106 }
107
108
109
110 /*
111  * Convert a vector into a vector of unit (1) length.
112  */
113
114 struct vector unit_vector (struct vector *vec)
115 {
116         double lx,ly,lz;
117         double uni;
118         struct vector res;
119
120         lx = vec->x;
121         ly = vec->y;
122         lz = vec->z;
123
124         uni = sqrt (lx * lx + ly * ly + lz * lz);
125
126         res.x = lx / uni;
127         res.y = ly / uni;
128         res.z = lz / uni;
129         
130         return res;
131 }
132
133
134
135
136
137 void set_init_matrix (struct vector *mat)
138 {
139         int i;
140
141         for (i = 0; i < 3; i++)
142                 mat[i] = start_matrix[i];
143 }
144
145
146
147 void tidy_matrix (struct vector *mat)
148 {
149         mat[2] = unit_vector (&mat[2]);
150
151         if ((mat[2].x > -1) && (mat[2].x < 1))
152         {
153                 if ((mat[2].y > -1) && (mat[2].y < 1))
154                 {
155                         mat[1].z = -(mat[2].x * mat[1].x + mat[2].y * mat[1].y) / mat[2].z;
156                 }
157                 else
158                 {
159                         mat[1].y = -(mat[2].x * mat[1].x + mat[2].z * mat[1].z) / mat[2].y;
160                 }
161         }
162         else
163         {
164                 mat[1].x = -(mat[2].y * mat[1].y + mat[2].z * mat[1].z) / mat[2].x;
165         }
166         
167         mat[1] = unit_vector (&mat[1]);
168         
169
170         /* xyzzy... nothing happens. :-)*/
171         
172         mat[0].x = mat[1].y * mat[2].z - mat[1].z * mat[2].y;
173         mat[0].y = mat[1].z * mat[2].x - mat[1].x * mat[2].z;
174         mat[0].z = mat[1].x * mat[2].y - mat[1].y * mat[2].x;
175 }
176