changeset 5:f6e6f3c8f7eb

Vectors done
author Eris Caffee <discordia@eldalin.com>
date Sun, 04 Sep 2011 12:46:08 -0500
parents f4e384b966b9
children 11e216148d1c
files include/Math.h include/Vector.h notes src/main.cpp
diffstat 4 files changed, 569 insertions(+), 211 deletions(-) [+]
line diff
     1.1 --- a/include/Math.h	Tue Aug 30 11:08:12 2011 -0500
     1.2 +++ b/include/Math.h	Sun Sep 04 12:46:08 2011 -0500
     1.3 @@ -1,8 +1,7 @@
     1.4  #ifndef MATH_H_
     1.5  #define MATH_H_
     1.6  
     1.7 -#include <cmath>
     1.8 -#include <string>
     1.9 +#include "Vector.h"
    1.10  
    1.11  namespace arda 
    1.12     {
    1.13 @@ -20,212 +19,15 @@
    1.14     // experts in the field.
    1.15  
    1.16     ////////////////////////////////////////////////////////////////////////////////
    1.17 -   // Vectors
    1.18 +   // Angles
    1.19  
    1.20 -   namespace Vector 
    1.21 +   namespace Angles
    1.22        {
    1.23 +      // This many decimals is enough to cover even IEEE quad precision (128 bit)
    1.24 +      // reals.  Run on PA-RISC lately?  :)
    1.25 +      const double PI = 3.14159265358979323846264338327950288;
    1.26 +      }
    1.27  
    1.28 -      typedef int Vector2i[2];
    1.29 -      typedef float Vector2f[2];
    1.30 -      typedef double Vector2d[2];
    1.31 -
    1.32 -      typedef int Vector3i[3];
    1.33 -      typedef float Vector3f[3];
    1.34 -      typedef double Vector3d[3];
    1.35 -
    1.36 -      typedef int Vector4i[4];
    1.37 -      typedef float Vector4f[4];
    1.38 -      typedef double Vector4d[4];
    1.39 -
    1.40 -      //////////////////////////////////////////////////////////////////////////
    1.41 -      // vectostr*(Vector v)
    1.42 -      //	Returns a C string representation of the vector.
    1.43 -      //	This is one of the few non-inline Vector functions.
    1.44 -
    1.45 -      std::string & vectostr2(Vector2i v, std::string & s);
    1.46 -      std::string & vectostr2(Vector2f v, std::string & s);
    1.47 -      std::string & vectostr2(Vector2d v, std::string & s);
    1.48 -      std::string & vectostr3(Vector3i v, std::string & s);
    1.49 -      std::string & vectostr3(Vector3f v, std::string & s);
    1.50 -      std::string & vectostr3(Vector3d v, std::string & s);
    1.51 -      std::string & vectostr4(Vector4i v, std::string & s);
    1.52 -      std::string & vectostr4(Vector4f v, std::string & s);
    1.53 -      std::string & vectostr4(Vector4d v, std::string & s);
    1.54 -      
    1.55 -      //////////////////////////////////////////////////////////////////////////
    1.56 -      // scale*(Vector v, scalar s)
    1.57 -      //	Multiply a vector by a scalar.
    1.58 -      //	Returns v so that the result may be passed to other functions.
    1.59 -
    1.60 -      inline int * scale2(Vector2i v, const int s)
    1.61 -	 { v[0] = v[0] * s ; v[1] = v[1] * s; return v; }
    1.62 -      inline int * scale2(Vector2i v, const float s)
    1.63 -	 { v[0] = v[0] * s ; v[1] = v[1] * s; return v; }
    1.64 -      inline int * scale2(Vector2i v, const double s)
    1.65 -	 { v[0] = v[0] * s ; v[1] = v[1] * s; return v; }
    1.66 -
    1.67 -      inline float * scale2(Vector2f v, const int s)
    1.68 -	 { v[0] = v[0] * s ; v[1] = v[1] * s; return v; }
    1.69 -      inline float * scale2(Vector2f v, const float s)
    1.70 -	 { v[0] = v[0] * s ; v[1] = v[1] * s; return v; }
    1.71 -      inline float * scale2(Vector2f v, const double s)
    1.72 -	 { v[0] = v[0] * s ; v[1] = v[1] * s; return v; }
    1.73 -
    1.74 -      inline double * scale2(Vector2d v, const int s)
    1.75 -	 { v[0] = v[0] * s ; v[1] = v[1] * s; return v; }
    1.76 -      inline double * scale2(Vector2d v, const float s)
    1.77 -	 { v[0] = v[0] * s ; v[1] = v[1] * s; return v; }
    1.78 -      inline double * scale2(Vector2d v, const double s)
    1.79 -	 { v[0] = v[0] * s ; v[1] = v[1] * s; return v; }
    1.80 -
    1.81 -
    1.82 -      inline int * scale3(Vector3i v, const int s)
    1.83 -	 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; }
    1.84 -      inline int * scale3(Vector3i v, const float s)
    1.85 -	 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; }
    1.86 -      inline int * scale3(Vector3i v, const double s)
    1.87 -	 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; }
    1.88 - 
    1.89 -      inline float * scale3(Vector3f v, const int s)
    1.90 -	 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; }
    1.91 -      inline float * scale3(Vector3f v, const float s)
    1.92 -	 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; }
    1.93 -      inline float * scale3(Vector3f v, const double s)
    1.94 -	 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; }
    1.95 -
    1.96 -      inline double * scale3(Vector3d v, const int s)
    1.97 -	 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; }
    1.98 -      inline double *  scale3(Vector3d v, const float s)
    1.99 -	 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; }
   1.100 -      inline double * scale3(Vector3d v, const double s)
   1.101 -	 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; }
   1.102 -
   1.103 -
   1.104 -      inline int * scale4(Vector4i v, const int s) 
   1.105 -	 { v[0] = v[0] * s ; v[1] = v[1] * s;  v[2] = v[2] * s;  v[3] = v[3] * s; return v; }
   1.106 -      inline int * scale4(Vector4i v, const float s) 
   1.107 -	 { v[0] = v[0] * s ; v[1] = v[1] * s;  v[2] = v[2] * s;  v[3] = v[3] * s; return v; }
   1.108 -      inline int * scale4(Vector4i v, const double s) 
   1.109 -	 { v[0] = v[0] * s ; v[1] = v[1] * s;  v[2] = v[2] * s;  v[3] = v[3] * s; return v; }
   1.110 -
   1.111 -      inline float * scale4(Vector4f v, const int s) 
   1.112 -	 { v[0] = v[0] * s ; v[1] = v[1] * s;  v[2] = v[2] * s;  v[3] = v[3] * s; return v; }
   1.113 -      inline float * scale4(Vector4f v, const float s) 
   1.114 -	 { v[0] = v[0] * s ; v[1] = v[1] * s;  v[2] = v[2] * s;  v[3] = v[3] * s; return v; }
   1.115 -      inline float * scale4(Vector4f v, const double s) 
   1.116 -	 { v[0] = v[0] * s ; v[1] = v[1] * s;  v[2] = v[2] * s;  v[3] = v[3] * s; return v; }
   1.117 -
   1.118 -      inline double * scale4(Vector4d v, const int s) 
   1.119 -	 { v[0] = v[0] * s ; v[1] = v[1] * s;  v[2] = v[2] * s;  v[3] = v[3] * s; return v; }
   1.120 -      inline double * scale4(Vector4d v, const float s) 
   1.121 -	 { v[0] = v[0] * s ; v[1] = v[1] * s;  v[2] = v[2] * s;  v[3] = v[3] * s; return v; }
   1.122 -      inline double * scale4(Vector4d v, const double s) 
   1.123 -	 { v[0] = v[0] * s ; v[1] = v[1] * s;  v[2] = v[2] * s;  v[3] = v[3] * s; return v; }
   1.124 -
   1.125 -
   1.126 -      //////////////////////////////////////////////////////////////////////////
   1.127 -      // dot*(Vector v1, Vector v2)
   1.128 -      //	The dot product of two vectors, which must be the same type
   1.129 -      //	Returns a long for int vectors, a double for floating point vectors.
   1.130 -
   1.131 -      inline long dot2(Vector2i v1, Vector2i v2)
   1.132 -	 { return (long) v1[0]*v2[0] + (long) v1[1]*v2[1]; }
   1.133 -      inline double dot2(Vector2f v1, Vector2f v2)
   1.134 -	 { return (double) v1[0]*v2[0] + (double) v1[1]*v2[1]; }
   1.135 -      inline double dot2(Vector2d v1, Vector2d v2)
   1.136 -	 { return v1[0]*v2[0] + v1[1]*v2[1]; }
   1.137 -
   1.138 -      inline long dot3(Vector3i v1, Vector3i v2)
   1.139 -	 { return (long) v1[0]*v2[0] + (long) v1[1]*v2[1] + (long) v1[2]*v2[2]; }
   1.140 -      inline double dot3(Vector3f v1, Vector3f v2)
   1.141 -	 { return (double) v1[0]*v2[0] + (double) v1[1]*v2[1] + (double) v1[2]*v2[2]; }
   1.142 -      inline double dot3(Vector3d v1, Vector3d v2)
   1.143 -	 { return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; }
   1.144 -
   1.145 -      inline long dot4(Vector4i v1, Vector4i v2)
   1.146 -	 { return (long) v1[0]*v2[0] + (long) v1[1]*v2[1] + (long) v1[2]*v2[2] + (long) v1[3]*v2[3]; }
   1.147 -      inline double dot4(Vector4f v1, Vector4f v2)
   1.148 -	 { return (double) v1[0]*v2[0] + (double) v1[1]*v2[1] + (double) v1[2]*v2[2] + (double) v1[3]*v2[3]; }
   1.149 -      inline double dot4(Vector4d v1, Vector4d v2)
   1.150 -	 { return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2] + v1[3]*v2[3]; }
   1.151 -
   1.152 -
   1.153 -      //////////////////////////////////////////////////////////////////////////
   1.154 -      // length*(Vector v)
   1.155 -      //	Get the length of a vector.
   1.156 -      //	Returns a float for float for float vectors, and a double for 
   1.157 -      //	int and double vectors.
   1.158 -
   1.159 -      inline double length2(Vector2i v)
   1.160 -	 { return sqrt((dot2(v, v))); }
   1.161 -      inline float length2(Vector2f v)
   1.162 -	 { return sqrtf((dot2(v, v))); }
   1.163 -      inline double length2(Vector2d v)
   1.164 -	 { return sqrt((dot2(v, v))); }
   1.165 -
   1.166 -      inline double length3(Vector3i v)
   1.167 -	 { return sqrt((dot3(v, v))); }
   1.168 -      inline float length3(Vector3f v)
   1.169 -	 { return sqrtf((dot3(v, v))); }
   1.170 -      inline double length3(Vector3d v)
   1.171 -	 { return sqrt((dot3(v, v))); }
   1.172 -
   1.173 -      inline double length4(Vector4i v)
   1.174 -	 { return sqrt((dot4(v, v))); }
   1.175 -      inline float length4(Vector4f v)
   1.176 -	 { return sqrtf((dot4(v, v))); }
   1.177 -      inline double length4(Vector4d v)
   1.178 -	 { return sqrt((dot4(v, v))); }
   1.179 -
   1.180 -
   1.181 -      //////////////////////////////////////////////////////////////////////////
   1.182 -      // add*(Vector v1, Vector v2, Vector vres)
   1.183 -      //	Add two vectors together.
   1.184 -      //        Returns vres so that the result may be used in further 
   1.185 -      //	calculations.
   1.186 -
   1.187 -      inline int * add2(Vector2i v1, Vector2i v2, Vector2i vres)
   1.188 -	 { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; return vres; }
   1.189 -      inline float * add2(Vector2f v1, Vector2f v2, Vector2f vres)
   1.190 -	 { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; return vres; }
   1.191 -      inline double * add2(Vector2d v1, Vector2d v2, Vector2d vres)
   1.192 -	 { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; return vres; }
   1.193 -
   1.194 -      inline int * add3(Vector3i v1, Vector3i v2, Vector3i vres)
   1.195 -	 { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; vres[2] = v1[2] + v2[2]; return vres; }
   1.196 -      inline float * add3(Vector3f v1, Vector3f v2, Vector3f vres)
   1.197 -	 { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; vres[2] = v1[2] + v2[2];  return vres; }
   1.198 -      inline double * add3(Vector3d v1, Vector3d v2, Vector3d vres)
   1.199 -	 { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; vres[2] = v1[2] + v2[2];  return vres; }
   1.200 -
   1.201 -      inline int * add4(Vector4i v1, Vector4i v2, Vector4i vres)
   1.202 -	 { 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;}
   1.203 -      inline float * add4(Vector4f v1, Vector4f v2, Vector4f vres)
   1.204 -	 { 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; }
   1.205 -      inline double * add4(Vector4d v1, Vector4d v2, Vector4d vres)
   1.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; }
   1.207 -
   1.208 -      //////////////////////////////////////////////////////////////////////////
   1.209 -      // normalize*(Vector v)
   1.210 -      //	Normalizes the vecor.  Only defined for floating point vectors.
   1.211 -      //	Returns the vector.
   1.212 -
   1.213 -      inline float * normalize2(Vector2f v)
   1.214 -	 { float l = length2(v); v[0] /= l; v[1] /= l; return v; }
   1.215 -      inline double * normalize2(Vector2d v)
   1.216 -	 { double l = length2(v); v[0] /= l; v[1] /= l; return v; }
   1.217 -
   1.218 -      inline float * normalize3(Vector3f v)
   1.219 -	 { float l = length3(v); v[0] /= l; v[1] /= l; v[2] /= l; return v; }
   1.220 -      inline double * normalize3(Vector3d v)
   1.221 -	 { double l = length3(v); v[0] /= l; v[1] /= l; v[2] /= l; return v; }
   1.222 -
   1.223 -      inline float * normalize4(Vector4f v)
   1.224 -	 { float l = length4(v); v[0] /= l; v[1] /= l; v[2] /= l; v[3] /= l; return v; }
   1.225 -      inline double * normalize4(Vector4d v)
   1.226 -	 { double l = length4(v); v[0] /= l; v[1] /= l; v[2] /= l; v[3] /= l; return v; }
   1.227 -   }
   1.228 -
   1.229 -} // namespace arda
   1.230 +   } // namespace arda
   1.231  
   1.232  #endif
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/include/Vector.h	Sun Sep 04 12:46:08 2011 -0500
     2.3 @@ -0,0 +1,421 @@
     2.4 +#ifndef VECTOR_H_
     2.5 +#define VECTOR_H_
     2.6 +
     2.7 +#include <cmath>
     2.8 +#include <string>
     2.9 +
    2.10 +namespace arda 
    2.11 +   {
    2.12 +
    2.13 +   ////////////////////////////////////////////////////////////////////////////////
    2.14 +   // Vectors
    2.15 +   //
    2.16 +   // Supported operations on vectors
    2.17 +   //
    2.18 +   // assign*()		Assign the value of one vector to another.
    2.19 +   // add*()		Add two vectors
    2.20 +   // cross()		Cross product of two 3-space vectors.
    2.21 +   // dot*()		Dot product.
    2.22 +   // get_angle*()	Calculate angle between two vectors.
    2.23 +   // length*()		Length of a vector (the Euclidean norm).
    2.24 +   // normalize*()	Normalize the vector.
    2.25 +   // proj*()		Calculate the projection of one vector onto another.
    2.26 +   // scale*()		Multiply vector by a scalar.
    2.27 +   // subtract*()	A convenience function to avoid writing add(v1, scale(v2, -1))
    2.28 +   // vectostr*()	Returns a printable string representation of the vector.
    2.29 +   //
    2.30 +   // All functions except vectostr are defined inline.
    2.31 +
    2.32 +   namespace Vector 
    2.33 +      {
    2.34 +
    2.35 +      typedef int Vector2i[2];
    2.36 +      typedef float Vector2f[2];
    2.37 +      typedef double Vector2d[2];
    2.38 +
    2.39 +      typedef int Vector3i[3];
    2.40 +      typedef float Vector3f[3];
    2.41 +      typedef double Vector3d[3];
    2.42 +
    2.43 +      typedef int Vector4i[4];
    2.44 +      typedef float Vector4f[4];
    2.45 +      typedef double Vector4d[4];
    2.46 +
    2.47 +      //////////////////////////////////////////////////////////////////////////
    2.48 +      // vectostr*(Vector v)
    2.49 +      //	Returns a C string representation of the vector.
    2.50 +      //	This is one of the few non-inline Vector functions.
    2.51 +
    2.52 +      std::string & vectostr2(Vector2i v, std::string & s);
    2.53 +      std::string & vectostr2(Vector2f v, std::string & s);
    2.54 +      std::string & vectostr2(Vector2d v, std::string & s);
    2.55 +      std::string & vectostr3(Vector3i v, std::string & s);
    2.56 +      std::string & vectostr3(Vector3f v, std::string & s);
    2.57 +      std::string & vectostr3(Vector3d v, std::string & s);
    2.58 +      std::string & vectostr4(Vector4i v, std::string & s);
    2.59 +      std::string & vectostr4(Vector4f v, std::string & s);
    2.60 +      std::string & vectostr4(Vector4d v, std::string & s);
    2.61 +      
    2.62 +      //////////////////////////////////////////////////////////////////////////
    2.63 +      // scale*(Vector v, scalar s)
    2.64 +      //	Multiply a vector by a scalar.
    2.65 +      //	Returns v so that the result may be passed to other functions.
    2.66 +
    2.67 +      inline int * scale2(Vector2i v, const int s)
    2.68 +	 { v[0] = v[0] * s ; v[1] = v[1] * s; return v; }
    2.69 +      inline int * scale2(Vector2i v, const float s)
    2.70 +	 { v[0] = v[0] * s ; v[1] = v[1] * s; return v; }
    2.71 +      inline int * scale2(Vector2i v, const double s)
    2.72 +	 { v[0] = v[0] * s ; v[1] = v[1] * s; return v; }
    2.73 +
    2.74 +      inline float * scale2(Vector2f v, const int s)
    2.75 +	 { v[0] = v[0] * s ; v[1] = v[1] * s; return v; }
    2.76 +      inline float * scale2(Vector2f v, const float s)
    2.77 +	 { v[0] = v[0] * s ; v[1] = v[1] * s; return v; }
    2.78 +      inline float * scale2(Vector2f v, const double s)
    2.79 +	 { v[0] = v[0] * s ; v[1] = v[1] * s; return v; }
    2.80 +
    2.81 +      inline double * scale2(Vector2d v, const int s)
    2.82 +	 { v[0] = v[0] * s ; v[1] = v[1] * s; return v; }
    2.83 +      inline double * scale2(Vector2d v, const float s)
    2.84 +	 { v[0] = v[0] * s ; v[1] = v[1] * s; return v; }
    2.85 +      inline double * scale2(Vector2d v, const double s)
    2.86 +	 { v[0] = v[0] * s ; v[1] = v[1] * s; return v; }
    2.87 +
    2.88 +
    2.89 +      inline int * scale3(Vector3i v, const int s)
    2.90 +	 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; }
    2.91 +      inline int * scale3(Vector3i v, const float s)
    2.92 +	 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; }
    2.93 +      inline int * scale3(Vector3i v, const double s)
    2.94 +	 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; }
    2.95 + 
    2.96 +      inline float * scale3(Vector3f v, const int s)
    2.97 +	 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; }
    2.98 +      inline float * scale3(Vector3f v, const float s)
    2.99 +	 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; }
   2.100 +      inline float * scale3(Vector3f v, const double s)
   2.101 +	 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; }
   2.102 +
   2.103 +      inline double * scale3(Vector3d v, const int s)
   2.104 +	 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; }
   2.105 +      inline double *  scale3(Vector3d v, const float s)
   2.106 +	 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; }
   2.107 +      inline double * scale3(Vector3d v, const double s)
   2.108 +	 { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; }
   2.109 +
   2.110 +
   2.111 +      inline int * scale4(Vector4i v, const int s) 
   2.112 +	 { v[0] = v[0] * s ; v[1] = v[1] * s;  v[2] = v[2] * s;  v[3] = v[3] * s; return v; }
   2.113 +      inline int * scale4(Vector4i v, const float s) 
   2.114 +	 { v[0] = v[0] * s ; v[1] = v[1] * s;  v[2] = v[2] * s;  v[3] = v[3] * s; return v; }
   2.115 +      inline int * scale4(Vector4i v, const double s) 
   2.116 +	 { v[0] = v[0] * s ; v[1] = v[1] * s;  v[2] = v[2] * s;  v[3] = v[3] * s; return v; }
   2.117 +
   2.118 +      inline float * scale4(Vector4f v, const int s) 
   2.119 +	 { v[0] = v[0] * s ; v[1] = v[1] * s;  v[2] = v[2] * s;  v[3] = v[3] * s; return v; }
   2.120 +      inline float * scale4(Vector4f v, const float s) 
   2.121 +	 { v[0] = v[0] * s ; v[1] = v[1] * s;  v[2] = v[2] * s;  v[3] = v[3] * s; return v; }
   2.122 +      inline float * scale4(Vector4f v, const double s) 
   2.123 +	 { v[0] = v[0] * s ; v[1] = v[1] * s;  v[2] = v[2] * s;  v[3] = v[3] * s; return v; }
   2.124 +
   2.125 +      inline double * scale4(Vector4d v, const int s) 
   2.126 +	 { v[0] = v[0] * s ; v[1] = v[1] * s;  v[2] = v[2] * s;  v[3] = v[3] * s; return v; }
   2.127 +      inline double * scale4(Vector4d v, const float s) 
   2.128 +	 { v[0] = v[0] * s ; v[1] = v[1] * s;  v[2] = v[2] * s;  v[3] = v[3] * s; return v; }
   2.129 +      inline double * scale4(Vector4d v, const double s) 
   2.130 +	 { v[0] = v[0] * s ; v[1] = v[1] * s;  v[2] = v[2] * s;  v[3] = v[3] * s; return v; }
   2.131 +
   2.132 +
   2.133 +      //////////////////////////////////////////////////////////////////////////
   2.134 +      // dot*(Vector v1, Vector v2)
   2.135 +      //	The dot product of two vectors, which must be the same type
   2.136 +      //	Returns a long for int vectors, a double for floating point vectors.
   2.137 +
   2.138 +      inline long dot2(Vector2i v1, Vector2i v2)
   2.139 +	 { return (long) v1[0]*v2[0] + (long) v1[1]*v2[1]; }
   2.140 +      inline double dot2(Vector2f v1, Vector2f v2)
   2.141 +	 { return (double) v1[0]*v2[0] + (double) v1[1]*v2[1]; }
   2.142 +      inline double dot2(Vector2d v1, Vector2d v2)
   2.143 +	 { return v1[0]*v2[0] + v1[1]*v2[1]; }
   2.144 +
   2.145 +      inline long dot3(Vector3i v1, Vector3i v2)
   2.146 +	 { return (long) v1[0]*v2[0] + (long) v1[1]*v2[1] + (long) v1[2]*v2[2]; }
   2.147 +      inline double dot3(Vector3f v1, Vector3f v2)
   2.148 +	 { return (double) v1[0]*v2[0] + (double) v1[1]*v2[1] + (double) v1[2]*v2[2]; }
   2.149 +      inline double dot3(Vector3d v1, Vector3d v2)
   2.150 +	 { return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; }
   2.151 +
   2.152 +      inline long dot4(Vector4i v1, Vector4i v2)
   2.153 +	 { return (long) v1[0]*v2[0] + (long) v1[1]*v2[1] + (long) v1[2]*v2[2] + (long) v1[3]*v2[3]; }
   2.154 +      inline double dot4(Vector4f v1, Vector4f v2)
   2.155 +	 { return (double) v1[0]*v2[0] + (double) v1[1]*v2[1] + (double) v1[2]*v2[2] + (double) v1[3]*v2[3]; }
   2.156 +      inline double dot4(Vector4d v1, Vector4d v2)
   2.157 +	 { return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2] + v1[3]*v2[3]; }
   2.158 +
   2.159 +
   2.160 +      //////////////////////////////////////////////////////////////////////////
   2.161 +      // length*(Vector v)
   2.162 +      //	Get the length of a vector.
   2.163 +      //	Returns a float for float for float vectors, and a double for 
   2.164 +      //	int and double vectors.
   2.165 +
   2.166 +      inline double length2(Vector2i v)
   2.167 +	 { return sqrt((dot2(v, v))); }
   2.168 +      inline double length2(Vector2f v)
   2.169 +	 { return sqrtf((dot2(v, v))); }
   2.170 +      inline double length2(Vector2d v)
   2.171 +	 { return sqrt((dot2(v, v))); }
   2.172 +
   2.173 +      inline double length3(Vector3i v)
   2.174 +	 { return sqrt((dot3(v, v))); }
   2.175 +      inline double length3(Vector3f v)
   2.176 +	 { return sqrtf((dot3(v, v))); }
   2.177 +      inline double length3(Vector3d v)
   2.178 +	 { return sqrt((dot3(v, v))); }
   2.179 +
   2.180 +      inline double length4(Vector4i v)
   2.181 +	 { return sqrt((dot4(v, v))); }
   2.182 +      inline double length4(Vector4f v)
   2.183 +	 { return sqrtf((dot4(v, v))); }
   2.184 +      inline double length4(Vector4d v)
   2.185 +	 { return sqrt((dot4(v, v))); }
   2.186 +
   2.187 +
   2.188 +      //////////////////////////////////////////////////////////////////////////
   2.189 +      // add*(Vector v1, Vector v2, Vector vres)
   2.190 +      //	Add two vectors together.
   2.191 +      //        Returns vres so that the result may be used in further 
   2.192 +      //	calculations.
   2.193 +
   2.194 +      inline int * add2(Vector2i v1, Vector2i v2, Vector2i vres)
   2.195 +	 { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; return vres; }
   2.196 +      inline float * add2(Vector2f v1, Vector2f v2, Vector2f vres)
   2.197 +	 { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; return vres; }
   2.198 +      inline double * add2(Vector2d v1, Vector2d v2, Vector2d vres)
   2.199 +	 { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; return vres; }
   2.200 +
   2.201 +      inline int * add3(Vector3i v1, Vector3i v2, Vector3i vres)
   2.202 +	 { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; vres[2] = v1[2] + v2[2]; return vres; }
   2.203 +      inline float * add3(Vector3f v1, Vector3f v2, Vector3f vres)
   2.204 +	 { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; vres[2] = v1[2] + v2[2];  return vres; }
   2.205 +      inline double * add3(Vector3d v1, Vector3d v2, Vector3d vres)
   2.206 +	 { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; vres[2] = v1[2] + v2[2];  return vres; }
   2.207 +
   2.208 +      inline int * add4(Vector4i v1, Vector4i v2, Vector4i vres)
   2.209 +	 { 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;}
   2.210 +      inline float * add4(Vector4f v1, Vector4f v2, Vector4f vres)
   2.211 +	 { 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; }
   2.212 +      inline double * add4(Vector4d v1, Vector4d v2, Vector4d vres)
   2.213 +	 { 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; }
   2.214 +
   2.215 +      //////////////////////////////////////////////////////////////////////////
   2.216 +      // normalize*(Vector v)
   2.217 +      //	Normalizes the vecor.  Only defined for floating point vectors.
   2.218 +      //	Returns the vector.
   2.219 +
   2.220 +      inline float * normalize2(Vector2f v)
   2.221 +	 { double l = length2(v); v[0] /= l; v[1] /= l; return v; }
   2.222 +      inline double * normalize2(Vector2d v)
   2.223 +	 { double l = length2(v); v[0] /= l; v[1] /= l; return v; }
   2.224 +
   2.225 +      inline float * normalize3(Vector3f v)
   2.226 +	 { double l = length3(v); v[0] /= l; v[1] /= l; v[2] /= l; return v; }
   2.227 +      inline double * normalize3(Vector3d v)
   2.228 +	 { double l = length3(v); v[0] /= l; v[1] /= l; v[2] /= l; return v; }
   2.229 +
   2.230 +      inline float * normalize4(Vector4f v)
   2.231 +	 { double l = length4(v); v[0] /= l; v[1] /= l; v[2] /= l; v[3] /= l; return v; }
   2.232 +      inline double * normalize4(Vector4d v)
   2.233 +	 { double l = length4(v); v[0] /= l; v[1] /= l; v[2] /= l; v[3] /= l; return v; }
   2.234 +
   2.235 +      //////////////////////////////////////////////////////////////////////////
   2.236 +      // cross(Vector3 v)
   2.237 +      //	Only defined for floating point 3 vectors.
   2.238 +      //	Returns the result vector.
   2.239 +
   2.240 +      inline float * cross(Vector3f v1, Vector3f v2, Vector3f vres)
   2.241 +	 { 
   2.242 +	 vres[0] =  v1[1]*v2[2] - v2[1]*v1[2];
   2.243 +	 vres[1] = -v1[0]*v2[2] + v2[0]*v1[2];
   2.244 +	 vres[2] =  v1[0]*v2[1] - v2[0]*v1[1];
   2.245 +	 return vres;
   2.246 +	 }
   2.247 +
   2.248 +      inline double * cross(Vector3d v1, Vector3d v2, Vector3d vres)
   2.249 +	 { 
   2.250 +	 vres[0] =  v1[1]*v2[2] - v2[1]*v1[2];
   2.251 +	 vres[1] = -v1[0]*v2[2] + v2[0]*v1[2];
   2.252 +	 vres[2] =  v1[0]*v2[1] - v2[0]*v1[1];
   2.253 +	 return vres;
   2.254 +	 }
   2.255 +   
   2.256 +      //////////////////////////////////////////////////////////////////////////
   2.257 +      // get_angle*(Vector3 v1, Vector3 v2)
   2.258 +      //	Returns the angle in radians between the two vectors.
   2.259 +      //
   2.260 +      // get_angle[234]n() take pre-normalized vectors as arguments and will
   2.261 +      //	fail otherwise.  This version is not defined for interger
   2.262 +      //	vectors since you can't normalize an integer vector.
   2.263 +      // get_angle[234]() take arbitrary vectors as arguments.
   2.264 +      //
   2.265 +      // I started out with two version of get_angle3:
   2.266 +      // get_angle3_1 implemented as
   2.267 +      //  return acos(dot3(v1, v2)/(length3(v1)*length3(v2)));
   2.268 +      // get_angle3_2 implemented as
   2.269 +      //  double tmp = dot3(v1, v2); 
   2.270 +      //  return acos(sqrtf(tmp*tmp/(dot3(v1,v1)*dot3(v2,v2))));
   2.271 +      // 
   2.272 +      // I ran timing tests, since I expected the second one - the one I chose to 
   2.273 +      // use, in the end - to be faster since it only resulted in one sqrt call
   2.274 +      // instead of two.  Here are the results
   2.275 +      //
   2.276 +      // get_angle3_1 44.753006890 seconds for 500,000,000 iterations.
   2.277 +      // get_angle3_2 36.940170102 seconds for 500,000,000 iterations.
   2.278 +      //
   2.279 +      // Faster?  Yes. About 7 nanoseconds vs 9.  A ridiculous optimization
   2.280 +      // to worry about?  Eh.  I might as well use it.
   2.281 +
   2.282 +      inline double get_angle2n(Vector2f v1, Vector2f v2)
   2.283 +	 { return acos(dot2(v1, v2)); }
   2.284 +      inline double get_angle2n(Vector2d v1, Vector2d v2)
   2.285 +	 { return acos(dot2(v1, v2)); }
   2.286 +      inline double get_angle2(Vector2i v1, Vector2i v2)
   2.287 +	 { 
   2.288 +	 double tmp = dot2(v1, v2); 
   2.289 +	 return acos(sqrtf(tmp*tmp/(dot2(v1,v1)*dot2(v2,v2)))); 
   2.290 +	 }
   2.291 +      inline double get_angle2(Vector2f v1, Vector2f v2)
   2.292 +	 { 
   2.293 +	 double tmp = dot2(v1, v2); 
   2.294 +	 return acos(sqrtf(tmp*tmp/(dot2(v1,v1)*dot2(v2,v2)))); 
   2.295 +	 }
   2.296 +      inline double get_angle2(Vector2d v1, Vector2d v2)
   2.297 +	 { 
   2.298 +	 double tmp = dot2(v1, v2); 
   2.299 +	 return acos(sqrtf(tmp*tmp/(dot2(v1,v1)*dot2(v2,v2)))); 
   2.300 +	 }
   2.301 +
   2.302 +      inline double get_angle3n(Vector3f v1, Vector3f v2)
   2.303 +	 { return acos(dot3(v1, v2)); }
   2.304 +      inline double get_angle3n(Vector3d v1, Vector3d v2)
   2.305 +	 { return acos(dot3(v1, v2)); }
   2.306 +      inline double get_angle3(Vector3i v1, Vector3i v2)
   2.307 +	 { 
   2.308 +	 double tmp = dot3(v1, v2); 
   2.309 +	 return acos(sqrtf(tmp*tmp/(dot3(v1,v1)*dot3(v2,v2)))); 
   2.310 +	 }
   2.311 +      inline double get_angle3(Vector3f v1, Vector3f v2)
   2.312 +	 { 
   2.313 +	 double tmp = dot3(v1, v2); 
   2.314 +	 return acos(sqrtf(tmp*tmp/(dot3(v1,v1)*dot3(v2,v2)))); 
   2.315 +	 }
   2.316 +      inline double get_angle3(Vector3d v1, Vector3d v2)
   2.317 +	 { 
   2.318 +	 double tmp = dot3(v1, v2); 
   2.319 +	 return acos(sqrtf(tmp*tmp/(dot3(v1,v1)*dot3(v2,v2)))); 
   2.320 +	 }
   2.321 +
   2.322 +      inline double get_angle4n(Vector4f v1, Vector4f v2)
   2.323 +	 { return acos(dot4(v1, v2)); }
   2.324 +      inline double get_angle4n(Vector4d v1, Vector4d v2)
   2.325 +	 { return acos(dot4(v1, v2)); }
   2.326 +      inline double get_angle4(Vector4i v1, Vector4i v2)
   2.327 +	 { 
   2.328 +	 double tmp = dot4(v1, v2); 
   2.329 +	 return acos(sqrtf(tmp*tmp/(dot4(v1,v1)*dot4(v2,v2)))); 
   2.330 +	 }
   2.331 +      inline double get_angle4(Vector4f v1, Vector4f v2)
   2.332 +	 { 
   2.333 +	 double tmp = dot4(v1, v2); 
   2.334 +	 return acos(sqrtf(tmp*tmp/(dot4(v1,v1)*dot4(v2,v2)))); 
   2.335 +	 }
   2.336 +      inline double get_angle4(Vector4d v1, Vector4d v2)
   2.337 +	 { 
   2.338 +	 double tmp = dot4(v1, v2); 
   2.339 +	 return acos(sqrtf(tmp*tmp/(dot4(v1,v1)*dot4(v2,v2)))); 
   2.340 +	 }
   2.341 +
   2.342 +      //////////////////////////////////////////////////////////////////////////
   2.343 +      // subtract*(Vector v1, Vector v2, Vector vres)
   2.344 +      //	Subtract v2 from v1 and store result in vres.
   2.345 +      //	Equivalent to add(v1, scale(v2, -1), vres).
   2.346 +      //        Returns vres so that the result may be used in further 
   2.347 +      //	calculations.
   2.348 +
   2.349 +      inline int * subtract2(Vector2i v1, Vector2i v2, Vector2i vres)
   2.350 +	 { vres[0] = v1[0] - v2[0]; vres[1] = v1[1] - v2[1]; return vres; }
   2.351 +      inline float * subtract2(Vector2f v1, Vector2f v2, Vector2f vres)
   2.352 +	 { vres[0] = v1[0] - v2[0]; vres[1] = v1[1] - v2[1]; return vres; }
   2.353 +      inline double * subtract2(Vector2d v1, Vector2d v2, Vector2d vres)
   2.354 +	 { vres[0] = v1[0] - v2[0]; vres[1] = v1[1] - v2[1]; return vres; }
   2.355 +
   2.356 +      inline int * subtract3(Vector3i v1, Vector3i v2, Vector3i vres)
   2.357 +	 { vres[0] = v1[0] - v2[0]; vres[1] = v1[1] - v2[1]; vres[2] = v1[2] - v2[2]; return vres; }
   2.358 +      inline float * subtract3(Vector3f v1, Vector3f v2, Vector3f vres)
   2.359 +	 { vres[0] = v1[0] - v2[0]; vres[1] = v1[1] - v2[1]; vres[2] = v1[2] - v2[2];  return vres; }
   2.360 +      inline double * subtract3(Vector3d v1, Vector3d v2, Vector3d vres)
   2.361 +	 { vres[0] = v1[0] - v2[0]; vres[1] = v1[1] - v2[1]; vres[2] = v1[2] - v2[2];  return vres; }
   2.362 +
   2.363 +      inline int * subtract4(Vector4i v1, Vector4i v2, Vector4i vres)
   2.364 +	 { 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;}
   2.365 +      inline float * subtract4(Vector4f v1, Vector4f v2, Vector4f vres)
   2.366 +	 { 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; }
   2.367 +      inline double * subtract4(Vector4d v1, Vector4d v2, Vector4d vres)
   2.368 +	 { 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; }
   2.369 +
   2.370 +
   2.371 +      //////////////////////////////////////////////////////////////////////////
   2.372 +      // assign*(Vector v1, Vector v2)
   2.373 +      //	Copies the value of v2 into v1.
   2.374 +      //	Returns v1.
   2.375 +
   2.376 +      inline int * assign2(Vector2i v1, Vector2i v2)
   2.377 +	 { v1[0] = v2[0]; v1[1] = v2[1]; return v1; }
   2.378 +      inline float * assign2(Vector2f v1, Vector2f v2)
   2.379 +	 { v1[0] = v2[0]; v1[1] = v2[1]; return v1; }
   2.380 +      inline double * assign2(Vector2d v1, Vector2d v2)
   2.381 +	 { v1[0] = v2[0]; v1[1] = v2[1]; return v1; }
   2.382 +
   2.383 +      inline int * assign3(Vector3i v1, Vector3i v2)
   2.384 +	 { v1[0] = v2[0]; v1[1] = v2[1]; v1[2] = v2[2]; return v1; }
   2.385 +      inline float * assign3(Vector3f v1, Vector3f v2)
   2.386 +	 { v1[0] = v2[0]; v1[1] = v2[1]; v1[2] = v2[2]; return v1; }
   2.387 +      inline double * assign3(Vector3d v1, Vector3d v2)
   2.388 +	 { v1[0] = v2[0]; v1[1] = v2[1]; v1[2] = v2[2]; return v1; }
   2.389 +
   2.390 +      inline int * assign4(Vector4i v1, Vector4i v2)
   2.391 +	 { v1[0] = v2[0]; v1[1] = v2[1]; v1[2] = v2[2]; v1[3] = v2[3]; return v1; }
   2.392 +      inline float * assign4(Vector4f v1, Vector4f v2)
   2.393 +	 { v1[0] = v2[0]; v1[1] = v2[1]; v1[2] = v2[2]; v1[3] = v2[3]; return v1; }
   2.394 +      inline double * assign4(Vector4d v1, Vector4d v2)
   2.395 +	 { v1[0] = v2[0]; v1[1] = v2[1]; v1[2] = v2[2]; v1[3] = v2[3]; return v1; }
   2.396 +
   2.397 +
   2.398 +      //////////////////////////////////////////////////////////////////////////
   2.399 +      // proj*(Vector v1, Vector v2, Vector vres)
   2.400 +      //	Calculates the projection of v1 onto v2 and returns the result 
   2.401 +      //	in vres.
   2.402 +      //	Only defined for floating point vectors.
   2.403 +      //	Returns vres.
   2.404 +
   2.405 +      inline float * proj2(Vector2f v1, Vector2f v2, Vector2f vres)
   2.406 +	 { assign2(vres, v2); scale2(vres, (dot2(v1, vres)/dot2(vres,vres))); return vres; }
   2.407 +      inline double * proj2(Vector2d v1, Vector2d v2, Vector2d vres)
   2.408 +	 { assign2(vres, v2); scale2(vres, (dot2(v1, vres)/dot2(vres,vres))); return vres; }
   2.409 +
   2.410 +      inline float * proj3(Vector3f v1, Vector3f v2, Vector3f vres)
   2.411 +	 { assign3(vres, v2); scale3(vres, (dot3(v1, vres)/dot3(vres,vres))); return vres; }
   2.412 +      inline double * proj3(Vector3d v1, Vector3d v2, Vector3d vres)
   2.413 +	 { assign3(vres, v2); scale3(vres, (dot3(v1, vres)/dot3(vres,vres))); return vres; }
   2.414 +
   2.415 +      inline float * proj4(Vector4f v1, Vector4f v2, Vector4f vres)
   2.416 +	 { assign4(vres, v2); scale4(vres, (dot4(v1, vres)/dot4(vres,vres))); return vres; }
   2.417 +      inline double * proj4(Vector4d v1, Vector4d v2, Vector4d vres)
   2.418 +	 { assign4(vres, v2); scale4(vres, (dot4(v1, vres)/dot4(vres,vres))); return vres; }
   2.419 +
   2.420 +      } // Vector
   2.421 +
   2.422 +   } // namespace arda
   2.423 +
   2.424 +#endif // VECTOR_H_
     3.1 --- a/notes	Tue Aug 30 11:08:12 2011 -0500
     3.2 +++ b/notes	Sun Sep 04 12:46:08 2011 -0500
     3.3 @@ -3,16 +3,17 @@
     3.4  
     3.5  Operations to support
     3.6  
     3.7 +* vector to string
     3.8  * dot
     3.9  * length (norm)
    3.10  * vector addition
    3.11  * scalar multiplication
    3.12  * normalize
    3.13 -cross
    3.14 +* cross
    3.15 +* angle between two vectors
    3.16 +assignment
    3.17 +projection of one vector onto another.
    3.18  triple product i.e. dot(u, cross(v, w))   Is this really that common?
    3.19 -angle between two vectors
    3.20 -projection of one vector onto another.
    3.21 -* vector to string
    3.22  
    3.23  Class with operator overloading?
    3.24  
     4.1 --- a/src/main.cpp	Tue Aug 30 11:08:12 2011 -0500
     4.2 +++ b/src/main.cpp	Sun Sep 04 12:46:08 2011 -0500
     4.3 @@ -113,7 +113,7 @@
     4.4  
     4.5     }
     4.6  
     4.7 -   // Vector::add*()
     4.8 +   // Vector::normalize*()
     4.9     {
    4.10     cout << "===============================================================" << endl <<
    4.11  	 "Testing Vector::normalize*()" << endl;
    4.12 @@ -141,4 +141,138 @@
    4.13     
    4.14     }
    4.15  
    4.16 +   // Vector::cross()
    4.17 +   {
    4.18 +   cout << "===============================================================" << endl <<
    4.19 +	 "Testing Vector::cross()" << endl;
    4.20 +
    4.21 +   Vector3f v3f[3] = { { 1.1f, 2.2f, 3.3f }, { 4.4f, 5.5f, 6.6f }, { 0.0f, 0.0f, 0.0f } };
    4.22 +   cout << setw(40) << "v3f[0]: " << vectostr3(v3f[0], s1) << endl;
    4.23 +   cout << setw(40) << "v3f[1]: " << vectostr3(v3f[1], s1) << endl;
    4.24 +   cross(v3f[0], v3f[1], v3f[2]);
    4.25 +   cout << setw(40) << "cross(v3f[0], v3f[1], v3f[2]): " << vectostr3(v3f[2], s1) << endl;
    4.26 +
    4.27 +   Vector3d v3d[3] = { { 1.1, 2.2, 3.3 }, { 4.4, 5.5, 6.6 }, { 0.0, 0.0, 0.0 } };
    4.28 +   cout << setw(40) << "v3d[0]: " << vectostr3(v3d[0], s1) << endl;
    4.29 +   cout << setw(40) << "v3d[1]: " << vectostr3(v3d[1], s1) << endl;
    4.30 +   cross(v3d[0], v3d[1], v3d[2]);
    4.31 +   cout << setw(40) << "cross(v3d[0], v3d[1], v3d[2]): " << vectostr3(v3d[2], s1) << endl;
    4.32 +
    4.33     }
    4.34 +
    4.35 +
    4.36 +   // Vector::cross()
    4.37 +   {
    4.38 +   cout << "===============================================================" << endl <<
    4.39 +	 "Testing Vector::get_angle*()" << endl;
    4.40 +
    4.41 +   Vector3i v3i[2] = { { 1, 2, 3 }, { 4, 5, 6 } };
    4.42 +   cout << setw(40) << "v3i[0]: " << vectostr3(v3i[0], s1) << endl;
    4.43 +   cout << setw(40) << "v3i[1]: " << vectostr3(v3i[1], s1) << endl;
    4.44 +   cout << setw(40) << "get_angle3(v3i[0], v3i[1]): " << get_angle3(v3i[0], v3i[1]) << endl;
    4.45 +
    4.46 +   Vector3f v3f[2] = { { 1.1f, 2.2f, 3.3f }, { 4.4f, 5.5f, 6.6f } };
    4.47 +   cout << setw(40) << "v3f[0]: " << vectostr3(v3f[0], s1) << endl;
    4.48 +   cout << setw(40) << "v3f[1]: " << vectostr3(v3f[1], s1) << endl;
    4.49 +   cout << setw(40) << "get_angle3(v3f[0], v3f[1]): " << get_angle3(v3f[0], v3f[1]) << endl;
    4.50 +   normalize3(v3f[0]);
    4.51 +   normalize3(v3f[1]);
    4.52 +   cout << setw(40) << "v3f[0]: " << vectostr3(v3f[0], s1) << endl;
    4.53 +   cout << setw(40) << "v3f[1]: " << vectostr3(v3f[1], s1) << endl;
    4.54 +   cout << setw(40) << "get_angle3n(v3f[0], v3f[1]): " << get_angle3n(v3f[0], v3f[1]) << endl;
    4.55 +
    4.56 +   Vector3d v3d[2] = { { 1.1, 2.2, 3.3 }, { 4.4, 5.5, 6.6 } };
    4.57 +   cout << setw(40) << "v3d[0]: " << vectostr3(v3d[0], s1) << endl;
    4.58 +   cout << setw(40) << "v3d[1]: " << vectostr3(v3d[1], s1) << endl;
    4.59 +   cout << setw(40) << "get_angle3(v3d[0], v3d[1]): " << get_angle3(v3d[0], v3d[1]) << endl;
    4.60 +   normalize3(v3d[0]);
    4.61 +   normalize3(v3d[1]);
    4.62 +   cout << setw(40) << "v3d[0]: " << vectostr3(v3d[0], s1) << endl;
    4.63 +   cout << setw(40) << "v3d[1]: " << vectostr3(v3d[1], s1) << endl;
    4.64 +   cout << setw(40) << "get_angle3n(v3d[0], v3d[1]): " << get_angle3n(v3d[0], v3d[1]) << endl;
    4.65 +   }
    4.66 +
    4.67 +   // Vector::subtract*()
    4.68 +   {
    4.69 +   cout << "===============================================================" << endl <<
    4.70 +	 "Testing Vector::subtract*()" << endl;
    4.71 +
    4.72 +   Vector2i v2i[3] = { { 1, 2 }, { 3, 4 } };
    4.73 +   Vector2i v2ires;
    4.74 +   cout << setw(40) << "v2i[0]: " << vectostr2(v2i[0], s1) << endl;
    4.75 +   cout << setw(40) << "v2i[1]: " << vectostr2(v2i[1], s1) << endl;
    4.76 +   subtract2(v2i[0], v2i[1], v2ires);
    4.77 +   cout << setw(40) << "subtract2(v2i[0], v2i[1], v2ires): " << vectostr2(v2ires, s1) << endl;
    4.78 +   cout << setw(40) << "length2(subtract2(v2i[0], v2i[1], v2ires)): " << length2(subtract2(v2i[0], v2i[1], v2ires)) << endl;
    4.79 +
    4.80 +   Vector3f v3f[3] = { { 1.1f, 2.2f, 3.3f }, { 4.4f, 5.5f, 6.6f } };
    4.81 +   Vector3f v3fres;
    4.82 +   cout << setw(40) << "v3f[0]: " << vectostr3(v3f[0], s1) << endl;
    4.83 +   cout << setw(40) << "v3f[1]: " << vectostr3(v3f[1], s1) << endl;
    4.84 +   subtract3(v3f[0], v3f[1], v3fres);
    4.85 +   cout << setw(40) << "subtract3(v3f[0], v3f[1], v3fres): " << vectostr3(v3fres, s1) << endl;
    4.86 +   cout << setw(40) << "length3(subtract3(v3f[0], v3f[1], v3fres)): " << length3(subtract3(v3f[0], v3f[1], v3fres)) << endl;
    4.87 +
    4.88 +   Vector4d v4d[3] = { { 1.1, 2.2, 3.3, 4.4 }, { 5.5, 6.6, 7.7, 8.8 } };
    4.89 +   Vector4d v4dres;
    4.90 +   cout << setw(40) << "v4d[0]: " << vectostr4(v4d[0], s1) << endl;
    4.91 +   cout << setw(40) << "v4d[1]: " << vectostr4(v4d[1], s1) << endl;
    4.92 +   subtract4(v4d[0], v4d[1], v4dres);
    4.93 +   cout << setw(40) << "subtract4(v4d[0], v4d[1], v4dres): " << vectostr4(v4dres, s1) << endl;
    4.94 +   cout << setw(40) << "length4(subtract4(v4d[0], v4d[1], v4dres)): " << length4(subtract4(v4d[0], v4d[1], v4dres)) << endl;
    4.95 +
    4.96 +   }
    4.97 +
    4.98 +   // Vector::assign*()
    4.99 +   {
   4.100 +   cout << "===============================================================" << endl <<
   4.101 +	 "Testing Vector::assign*()" << endl;
   4.102 +
   4.103 +   Vector2i v2i[3] = { { 1, 2 }, { 3, 4 } };
   4.104 +   cout << setw(40) << "v2i[0]: " << vectostr2(v2i[0], s1) << endl;
   4.105 +   cout << setw(40) << "v2i[1]: " << vectostr2(v2i[1], s1) << endl;
   4.106 +   assign2(v2i[0], v2i[1]);
   4.107 +   cout << setw(40) << "assign2(v2i[0], v2i[1]): " << vectostr2(v2i[0], s1) << endl;
   4.108 +
   4.109 +   Vector3f v3f[3] = { { 1.1f, 2.2f, 3.3f }, { 4.4f, 5.5f, 6.6f } };
   4.110 +   cout << setw(40) << "v3f[0]: " << vectostr3(v3f[0], s1) << endl;
   4.111 +   cout << setw(40) << "v3f[1]: " << vectostr3(v3f[1], s1) << endl;
   4.112 +   assign3(v3f[0], v3f[1]);
   4.113 +   cout << setw(40) << "assign3(v3f[0], v3f[1]): " << vectostr3(v3f[0], s1) << endl;
   4.114 +
   4.115 +   Vector4d v4d[3] = { { 1.1, 2.2, 3.3, 4.4 }, { 5.5, 6.6, 7.7, 8.8 } };
   4.116 +   cout << setw(40) << "v4d[0]: " << vectostr4(v4d[0], s1) << endl;
   4.117 +   cout << setw(40) << "v4d[1]: " << vectostr4(v4d[1], s1) << endl;
   4.118 +   assign4(v4d[0], v4d[1]);
   4.119 +   cout << setw(40) << "assign4(v4d[0], v4d[1]): " << vectostr4(v4d[0], s1) << endl;
   4.120 +
   4.121 +   }
   4.122 +
   4.123 +   // Vector::proj*()
   4.124 +   {
   4.125 +   cout << "===============================================================" << endl <<
   4.126 +	 "Testing Vector::proj*()" << endl;
   4.127 +
   4.128 +   Vector2f v2f[3] = { { 1.1f, 2.2f }, { 3.3f, 4.4f } };
   4.129 +   Vector2f v2fres;
   4.130 +   cout << setw(40) << "v2f[0]: " << vectostr2(v2f[0], s1) << endl;
   4.131 +   cout << setw(40) << "v2f[1]: " << vectostr2(v2f[1], s1) << endl;
   4.132 +   proj3(v2f[0], v2f[1], v2fres);
   4.133 +   cout << setw(40) << "proj3(v2f[0], v2f[1], v2fres): " << vectostr2(v2fres, s1) << endl;
   4.134 +
   4.135 +   Vector3f v3f[3] = { { 1.1f, 2.2f, 3.3f }, { 4.4f, 5.5f, 6.6f } };
   4.136 +   Vector3f v3fres;
   4.137 +   cout << setw(40) << "v3f[0]: " << vectostr3(v3f[0], s1) << endl;
   4.138 +   cout << setw(40) << "v3f[1]: " << vectostr3(v3f[1], s1) << endl;
   4.139 +   proj3(v3f[0], v3f[1], v3fres);
   4.140 +   cout << setw(40) << "proj3(v3f[0], v3f[1], v3fres): " << vectostr3(v3fres, s1) << endl;
   4.141 +
   4.142 +   Vector4d v4d[3] = { { 1.1, 2.2, 3.3, 4.4 }, { 5.5, 6.6, 7.7, 8.8 } };
   4.143 +   Vector4d v4dres;
   4.144 +   cout << setw(40) << "v4d[0]: " << vectostr4(v4d[0], s1) << endl;
   4.145 +   cout << setw(40) << "v4d[1]: " << vectostr4(v4d[1], s1) << endl;
   4.146 +   proj4(v4d[0], v4d[1], v4dres);
   4.147 +   cout << setw(40) << "proj4(v4d[0], v4d[1], v4dres): " << vectostr4(v4dres, s1) << endl;
   4.148 +
   4.149 +   }
   4.150 +   }