Proper Subversion configuration.
[newkind] / vector.c
CommitLineData
84bbd123 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
30static 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
45void 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
73void 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
103double 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
114struct 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
137void 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
147void 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