view include/Vector.h @ 5:f6e6f3c8f7eb

Vectors done
author Eris Caffee <discordia@eldalin.com>
date Sun, 04 Sep 2011 12:46:08 -0500
parents
children 11e216148d1c
line source
1 #ifndef VECTOR_H_
2 #define VECTOR_H_
4 #include <cmath>
5 #include <string>
7 namespace arda
8 {
10 ////////////////////////////////////////////////////////////////////////////////
11 // Vectors
12 //
13 // Supported operations on vectors
14 //
15 // assign*() Assign the value of one vector to another.
16 // add*() Add two vectors
17 // cross() Cross product of two 3-space vectors.
18 // dot*() Dot product.
19 // get_angle*() Calculate angle between two vectors.
20 // length*() Length of a vector (the Euclidean norm).
21 // normalize*() Normalize the vector.
22 // proj*() Calculate the projection of one vector onto another.
23 // scale*() Multiply vector by a scalar.
24 // subtract*() A convenience function to avoid writing add(v1, scale(v2, -1))
25 // vectostr*() Returns a printable string representation of the vector.
26 //
27 // All functions except vectostr are defined inline.
29 namespace Vector
30 {
32 typedef int Vector2i[2];
33 typedef float Vector2f[2];
34 typedef double Vector2d[2];
36 typedef int Vector3i[3];
37 typedef float Vector3f[3];
38 typedef double Vector3d[3];
40 typedef int Vector4i[4];
41 typedef float Vector4f[4];
42 typedef double Vector4d[4];
44 //////////////////////////////////////////////////////////////////////////
45 // vectostr*(Vector v)
46 // Returns a C string representation of the vector.
47 // This is one of the few non-inline Vector functions.
49 std::string & vectostr2(Vector2i v, std::string & s);
50 std::string & vectostr2(Vector2f v, std::string & s);
51 std::string & vectostr2(Vector2d v, std::string & s);
52 std::string & vectostr3(Vector3i v, std::string & s);
53 std::string & vectostr3(Vector3f v, std::string & s);
54 std::string & vectostr3(Vector3d v, std::string & s);
55 std::string & vectostr4(Vector4i v, std::string & s);
56 std::string & vectostr4(Vector4f v, std::string & s);
57 std::string & vectostr4(Vector4d v, std::string & s);
59 //////////////////////////////////////////////////////////////////////////
60 // scale*(Vector v, scalar s)
61 // Multiply a vector by a scalar.
62 // Returns v so that the result may be passed to other functions.
64 inline int * scale2(Vector2i v, const int s)
65 { v[0] = v[0] * s ; v[1] = v[1] * s; return v; }
66 inline int * scale2(Vector2i v, const float s)
67 { v[0] = v[0] * s ; v[1] = v[1] * s; return v; }
68 inline int * scale2(Vector2i v, const double s)
69 { v[0] = v[0] * s ; v[1] = v[1] * s; return v; }
71 inline float * scale2(Vector2f v, const int s)
72 { v[0] = v[0] * s ; v[1] = v[1] * s; return v; }
73 inline float * scale2(Vector2f v, const float s)
74 { v[0] = v[0] * s ; v[1] = v[1] * s; return v; }
75 inline float * scale2(Vector2f v, const double s)
76 { v[0] = v[0] * s ; v[1] = v[1] * s; return v; }
78 inline double * scale2(Vector2d v, const int s)
79 { v[0] = v[0] * s ; v[1] = v[1] * s; return v; }
80 inline double * scale2(Vector2d v, const float s)
81 { v[0] = v[0] * s ; v[1] = v[1] * s; return v; }
82 inline double * scale2(Vector2d v, const double s)
83 { v[0] = v[0] * s ; v[1] = v[1] * s; return v; }
86 inline int * scale3(Vector3i v, const int s)
87 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; }
88 inline int * scale3(Vector3i v, const float s)
89 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; }
90 inline int * scale3(Vector3i v, const double s)
91 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; }
93 inline float * scale3(Vector3f v, const int s)
94 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; }
95 inline float * scale3(Vector3f v, const float s)
96 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; }
97 inline float * scale3(Vector3f v, const double s)
98 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; }
100 inline double * scale3(Vector3d v, const int s)
101 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; }
102 inline double * scale3(Vector3d v, const float s)
103 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; }
104 inline double * scale3(Vector3d v, const double s)
105 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; }
108 inline int * scale4(Vector4i v, const int s)
109 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; v[3] = v[3] * s; return v; }
110 inline int * scale4(Vector4i v, const float s)
111 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; v[3] = v[3] * s; return v; }
112 inline int * scale4(Vector4i v, const double s)
113 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; v[3] = v[3] * s; return v; }
115 inline float * scale4(Vector4f v, const int s)
116 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; v[3] = v[3] * s; return v; }
117 inline float * scale4(Vector4f v, const float s)
118 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; v[3] = v[3] * s; return v; }
119 inline float * scale4(Vector4f v, const double s)
120 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; v[3] = v[3] * s; return v; }
122 inline double * scale4(Vector4d v, const int s)
123 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; v[3] = v[3] * s; return v; }
124 inline double * scale4(Vector4d v, const float s)
125 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; v[3] = v[3] * s; return v; }
126 inline double * scale4(Vector4d v, const double s)
127 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; v[3] = v[3] * s; return v; }
130 //////////////////////////////////////////////////////////////////////////
131 // dot*(Vector v1, Vector v2)
132 // The dot product of two vectors, which must be the same type
133 // Returns a long for int vectors, a double for floating point vectors.
135 inline long dot2(Vector2i v1, Vector2i v2)
136 { return (long) v1[0]*v2[0] + (long) v1[1]*v2[1]; }
137 inline double dot2(Vector2f v1, Vector2f v2)
138 { return (double) v1[0]*v2[0] + (double) v1[1]*v2[1]; }
139 inline double dot2(Vector2d v1, Vector2d v2)
140 { return v1[0]*v2[0] + v1[1]*v2[1]; }
142 inline long dot3(Vector3i v1, Vector3i v2)
143 { return (long) v1[0]*v2[0] + (long) v1[1]*v2[1] + (long) v1[2]*v2[2]; }
144 inline double dot3(Vector3f v1, Vector3f v2)
145 { return (double) v1[0]*v2[0] + (double) v1[1]*v2[1] + (double) v1[2]*v2[2]; }
146 inline double dot3(Vector3d v1, Vector3d v2)
147 { return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; }
149 inline long dot4(Vector4i v1, Vector4i v2)
150 { return (long) v1[0]*v2[0] + (long) v1[1]*v2[1] + (long) v1[2]*v2[2] + (long) v1[3]*v2[3]; }
151 inline double dot4(Vector4f v1, Vector4f v2)
152 { return (double) v1[0]*v2[0] + (double) v1[1]*v2[1] + (double) v1[2]*v2[2] + (double) v1[3]*v2[3]; }
153 inline double dot4(Vector4d v1, Vector4d v2)
154 { return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2] + v1[3]*v2[3]; }
157 //////////////////////////////////////////////////////////////////////////
158 // length*(Vector v)
159 // Get the length of a vector.
160 // Returns a float for float for float vectors, and a double for
161 // int and double vectors.
163 inline double length2(Vector2i v)
164 { return sqrt((dot2(v, v))); }
165 inline double length2(Vector2f v)
166 { return sqrtf((dot2(v, v))); }
167 inline double length2(Vector2d v)
168 { return sqrt((dot2(v, v))); }
170 inline double length3(Vector3i v)
171 { return sqrt((dot3(v, v))); }
172 inline double length3(Vector3f v)
173 { return sqrtf((dot3(v, v))); }
174 inline double length3(Vector3d v)
175 { return sqrt((dot3(v, v))); }
177 inline double length4(Vector4i v)
178 { return sqrt((dot4(v, v))); }
179 inline double length4(Vector4f v)
180 { return sqrtf((dot4(v, v))); }
181 inline double length4(Vector4d v)
182 { return sqrt((dot4(v, v))); }
185 //////////////////////////////////////////////////////////////////////////
186 // add*(Vector v1, Vector v2, Vector vres)
187 // Add two vectors together.
188 // Returns vres so that the result may be used in further
189 // calculations.
191 inline int * add2(Vector2i v1, Vector2i v2, Vector2i vres)
192 { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; return vres; }
193 inline float * add2(Vector2f v1, Vector2f v2, Vector2f vres)
194 { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; return vres; }
195 inline double * add2(Vector2d v1, Vector2d v2, Vector2d vres)
196 { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; return vres; }
198 inline int * add3(Vector3i v1, Vector3i v2, Vector3i vres)
199 { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; vres[2] = v1[2] + v2[2]; return vres; }
200 inline float * add3(Vector3f v1, Vector3f v2, Vector3f vres)
201 { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; vres[2] = v1[2] + v2[2]; return vres; }
202 inline double * add3(Vector3d v1, Vector3d v2, Vector3d vres)
203 { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; vres[2] = v1[2] + v2[2]; return vres; }
205 inline int * add4(Vector4i v1, Vector4i v2, Vector4i vres)
206 { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; vres[2] = v1[2] + v2[2]; vres[3] = v1[3] + v2[3]; return vres;}
207 inline float * add4(Vector4f v1, Vector4f v2, Vector4f vres)
208 { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; vres[2] = v1[2] + v2[2]; vres[3] = v1[3] + v2[3]; return vres; }
209 inline double * add4(Vector4d v1, Vector4d v2, Vector4d vres)
210 { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; vres[2] = v1[2] + v2[2]; vres[3] = v1[3] + v2[3]; return vres; }
212 //////////////////////////////////////////////////////////////////////////
213 // normalize*(Vector v)
214 // Normalizes the vecor. Only defined for floating point vectors.
215 // Returns the vector.
217 inline float * normalize2(Vector2f v)
218 { double l = length2(v); v[0] /= l; v[1] /= l; return v; }
219 inline double * normalize2(Vector2d v)
220 { double l = length2(v); v[0] /= l; v[1] /= l; return v; }
222 inline float * normalize3(Vector3f v)
223 { double l = length3(v); v[0] /= l; v[1] /= l; v[2] /= l; return v; }
224 inline double * normalize3(Vector3d v)
225 { double l = length3(v); v[0] /= l; v[1] /= l; v[2] /= l; return v; }
227 inline float * normalize4(Vector4f v)
228 { double l = length4(v); v[0] /= l; v[1] /= l; v[2] /= l; v[3] /= l; return v; }
229 inline double * normalize4(Vector4d v)
230 { double l = length4(v); v[0] /= l; v[1] /= l; v[2] /= l; v[3] /= l; return v; }
232 //////////////////////////////////////////////////////////////////////////
233 // cross(Vector3 v)
234 // Only defined for floating point 3 vectors.
235 // Returns the result vector.
237 inline float * cross(Vector3f v1, Vector3f v2, Vector3f vres)
238 {
239 vres[0] = v1[1]*v2[2] - v2[1]*v1[2];
240 vres[1] = -v1[0]*v2[2] + v2[0]*v1[2];
241 vres[2] = v1[0]*v2[1] - v2[0]*v1[1];
242 return vres;
243 }
245 inline double * cross(Vector3d v1, Vector3d v2, Vector3d vres)
246 {
247 vres[0] = v1[1]*v2[2] - v2[1]*v1[2];
248 vres[1] = -v1[0]*v2[2] + v2[0]*v1[2];
249 vres[2] = v1[0]*v2[1] - v2[0]*v1[1];
250 return vres;
251 }
253 //////////////////////////////////////////////////////////////////////////
254 // get_angle*(Vector3 v1, Vector3 v2)
255 // Returns the angle in radians between the two vectors.
256 //
257 // get_angle[234]n() take pre-normalized vectors as arguments and will
258 // fail otherwise. This version is not defined for interger
259 // vectors since you can't normalize an integer vector.
260 // get_angle[234]() take arbitrary vectors as arguments.
261 //
262 // I started out with two version of get_angle3:
263 // get_angle3_1 implemented as
264 // return acos(dot3(v1, v2)/(length3(v1)*length3(v2)));
265 // get_angle3_2 implemented as
266 // double tmp = dot3(v1, v2);
267 // return acos(sqrtf(tmp*tmp/(dot3(v1,v1)*dot3(v2,v2))));
268 //
269 // I ran timing tests, since I expected the second one - the one I chose to
270 // use, in the end - to be faster since it only resulted in one sqrt call
271 // instead of two. Here are the results
272 //
273 // get_angle3_1 44.753006890 seconds for 500,000,000 iterations.
274 // get_angle3_2 36.940170102 seconds for 500,000,000 iterations.
275 //
276 // Faster? Yes. About 7 nanoseconds vs 9. A ridiculous optimization
277 // to worry about? Eh. I might as well use it.
279 inline double get_angle2n(Vector2f v1, Vector2f v2)
280 { return acos(dot2(v1, v2)); }
281 inline double get_angle2n(Vector2d v1, Vector2d v2)
282 { return acos(dot2(v1, v2)); }
283 inline double get_angle2(Vector2i v1, Vector2i v2)
284 {
285 double tmp = dot2(v1, v2);
286 return acos(sqrtf(tmp*tmp/(dot2(v1,v1)*dot2(v2,v2))));
287 }
288 inline double get_angle2(Vector2f v1, Vector2f v2)
289 {
290 double tmp = dot2(v1, v2);
291 return acos(sqrtf(tmp*tmp/(dot2(v1,v1)*dot2(v2,v2))));
292 }
293 inline double get_angle2(Vector2d v1, Vector2d v2)
294 {
295 double tmp = dot2(v1, v2);
296 return acos(sqrtf(tmp*tmp/(dot2(v1,v1)*dot2(v2,v2))));
297 }
299 inline double get_angle3n(Vector3f v1, Vector3f v2)
300 { return acos(dot3(v1, v2)); }
301 inline double get_angle3n(Vector3d v1, Vector3d v2)
302 { return acos(dot3(v1, v2)); }
303 inline double get_angle3(Vector3i v1, Vector3i v2)
304 {
305 double tmp = dot3(v1, v2);
306 return acos(sqrtf(tmp*tmp/(dot3(v1,v1)*dot3(v2,v2))));
307 }
308 inline double get_angle3(Vector3f v1, Vector3f v2)
309 {
310 double tmp = dot3(v1, v2);
311 return acos(sqrtf(tmp*tmp/(dot3(v1,v1)*dot3(v2,v2))));
312 }
313 inline double get_angle3(Vector3d v1, Vector3d v2)
314 {
315 double tmp = dot3(v1, v2);
316 return acos(sqrtf(tmp*tmp/(dot3(v1,v1)*dot3(v2,v2))));
317 }
319 inline double get_angle4n(Vector4f v1, Vector4f v2)
320 { return acos(dot4(v1, v2)); }
321 inline double get_angle4n(Vector4d v1, Vector4d v2)
322 { return acos(dot4(v1, v2)); }
323 inline double get_angle4(Vector4i v1, Vector4i v2)
324 {
325 double tmp = dot4(v1, v2);
326 return acos(sqrtf(tmp*tmp/(dot4(v1,v1)*dot4(v2,v2))));
327 }
328 inline double get_angle4(Vector4f v1, Vector4f v2)
329 {
330 double tmp = dot4(v1, v2);
331 return acos(sqrtf(tmp*tmp/(dot4(v1,v1)*dot4(v2,v2))));
332 }
333 inline double get_angle4(Vector4d v1, Vector4d v2)
334 {
335 double tmp = dot4(v1, v2);
336 return acos(sqrtf(tmp*tmp/(dot4(v1,v1)*dot4(v2,v2))));
337 }
339 //////////////////////////////////////////////////////////////////////////
340 // subtract*(Vector v1, Vector v2, Vector vres)
341 // Subtract v2 from v1 and store result in vres.
342 // Equivalent to add(v1, scale(v2, -1), vres).
343 // Returns vres so that the result may be used in further
344 // calculations.
346 inline int * subtract2(Vector2i v1, Vector2i v2, Vector2i vres)
347 { vres[0] = v1[0] - v2[0]; vres[1] = v1[1] - v2[1]; return vres; }
348 inline float * subtract2(Vector2f v1, Vector2f v2, Vector2f vres)
349 { vres[0] = v1[0] - v2[0]; vres[1] = v1[1] - v2[1]; return vres; }
350 inline double * subtract2(Vector2d v1, Vector2d v2, Vector2d vres)
351 { vres[0] = v1[0] - v2[0]; vres[1] = v1[1] - v2[1]; return vres; }
353 inline int * subtract3(Vector3i v1, Vector3i v2, Vector3i vres)
354 { vres[0] = v1[0] - v2[0]; vres[1] = v1[1] - v2[1]; vres[2] = v1[2] - v2[2]; return vres; }
355 inline float * subtract3(Vector3f v1, Vector3f v2, Vector3f vres)
356 { vres[0] = v1[0] - v2[0]; vres[1] = v1[1] - v2[1]; vres[2] = v1[2] - v2[2]; return vres; }
357 inline double * subtract3(Vector3d v1, Vector3d v2, Vector3d vres)
358 { vres[0] = v1[0] - v2[0]; vres[1] = v1[1] - v2[1]; vres[2] = v1[2] - v2[2]; return vres; }
360 inline int * subtract4(Vector4i v1, Vector4i v2, Vector4i vres)
361 { vres[0] = v1[0] - v2[0]; vres[1] = v1[1] - v2[1]; vres[2] = v1[2] - v2[2]; vres[3] = v1[3] - v2[3]; return vres;}
362 inline float * subtract4(Vector4f v1, Vector4f v2, Vector4f vres)
363 { vres[0] = v1[0] - v2[0]; vres[1] = v1[1] - v2[1]; vres[2] = v1[2] - v2[2]; vres[3] = v1[3] - v2[3]; return vres; }
364 inline double * subtract4(Vector4d v1, Vector4d v2, Vector4d vres)
365 { vres[0] = v1[0] - v2[0]; vres[1] = v1[1] - v2[1]; vres[2] = v1[2] - v2[2]; vres[3] = v1[3] - v2[3]; return vres; }
368 //////////////////////////////////////////////////////////////////////////
369 // assign*(Vector v1, Vector v2)
370 // Copies the value of v2 into v1.
371 // Returns v1.
373 inline int * assign2(Vector2i v1, Vector2i v2)
374 { v1[0] = v2[0]; v1[1] = v2[1]; return v1; }
375 inline float * assign2(Vector2f v1, Vector2f v2)
376 { v1[0] = v2[0]; v1[1] = v2[1]; return v1; }
377 inline double * assign2(Vector2d v1, Vector2d v2)
378 { v1[0] = v2[0]; v1[1] = v2[1]; return v1; }
380 inline int * assign3(Vector3i v1, Vector3i v2)
381 { v1[0] = v2[0]; v1[1] = v2[1]; v1[2] = v2[2]; return v1; }
382 inline float * assign3(Vector3f v1, Vector3f v2)
383 { v1[0] = v2[0]; v1[1] = v2[1]; v1[2] = v2[2]; return v1; }
384 inline double * assign3(Vector3d v1, Vector3d v2)
385 { v1[0] = v2[0]; v1[1] = v2[1]; v1[2] = v2[2]; return v1; }
387 inline int * assign4(Vector4i v1, Vector4i v2)
388 { v1[0] = v2[0]; v1[1] = v2[1]; v1[2] = v2[2]; v1[3] = v2[3]; return v1; }
389 inline float * assign4(Vector4f v1, Vector4f v2)
390 { v1[0] = v2[0]; v1[1] = v2[1]; v1[2] = v2[2]; v1[3] = v2[3]; return v1; }
391 inline double * assign4(Vector4d v1, Vector4d v2)
392 { v1[0] = v2[0]; v1[1] = v2[1]; v1[2] = v2[2]; v1[3] = v2[3]; return v1; }
395 //////////////////////////////////////////////////////////////////////////
396 // proj*(Vector v1, Vector v2, Vector vres)
397 // Calculates the projection of v1 onto v2 and returns the result
398 // in vres.
399 // Only defined for floating point vectors.
400 // Returns vres.
402 inline float * proj2(Vector2f v1, Vector2f v2, Vector2f vres)
403 { assign2(vres, v2); scale2(vres, (dot2(v1, vres)/dot2(vres,vres))); return vres; }
404 inline double * proj2(Vector2d v1, Vector2d v2, Vector2d vres)
405 { assign2(vres, v2); scale2(vres, (dot2(v1, vres)/dot2(vres,vres))); return vres; }
407 inline float * proj3(Vector3f v1, Vector3f v2, Vector3f vres)
408 { assign3(vres, v2); scale3(vres, (dot3(v1, vres)/dot3(vres,vres))); return vres; }
409 inline double * proj3(Vector3d v1, Vector3d v2, Vector3d vres)
410 { assign3(vres, v2); scale3(vres, (dot3(v1, vres)/dot3(vres,vres))); return vres; }
412 inline float * proj4(Vector4f v1, Vector4f v2, Vector4f vres)
413 { assign4(vres, v2); scale4(vres, (dot4(v1, vres)/dot4(vres,vres))); return vres; }
414 inline double * proj4(Vector4d v1, Vector4d v2, Vector4d vres)
415 { assign4(vres, v2); scale4(vres, (dot4(v1, vres)/dot4(vres,vres))); return vres; }
417 } // Vector
419 } // namespace arda
421 #endif // VECTOR_H_