changeset 7:378862555189

Refactored Vectors into templated classes. Much nicer now.
author Eris Caffee <discordia@eldalin.com>
date Wed, 28 Sep 2011 12:48:42 -0500
parents 11e216148d1c
children 5377337c7de0
files CMakeLists.txt include/Math.h include/Matrix.h include/Vector.h src/Vector.cpp src/main.cpp
diffstat 6 files changed, 918 insertions(+), 924 deletions(-) [+]
line diff
     1.1 --- a/CMakeLists.txt	Tue Sep 06 11:26:39 2011 -0500
     1.2 +++ b/CMakeLists.txt	Wed Sep 28 12:48:42 2011 -0500
     1.3 @@ -120,8 +120,16 @@
     1.4    add_definitions(-pedantic -Wall)
     1.5  endif ()
     1.6  
     1.7 +################################################################################
     1.8 +# Other miscellaneous compiler options
     1.9 +
    1.10 +#if (CMAKE_COMPILER_IS_GNUCXX)
    1.11 +#  # Allow anonymous structs
    1.12 +#  add_definitions(-fms-extensions)
    1.13 +#endif ()
    1.14  
    1.15  ################################################################################
    1.16 +# Build for profiling.
    1.17  
    1.18  option(Option_Profile_Program "Build for gprof profiling." OFF)
    1.19  if (Option_Profile_Program)
    1.20 @@ -138,11 +146,8 @@
    1.21  # test driver.  Also, it just seems good practice to explicitly list things since
    1.22  # it avoids accidental inclusion of things that ought not to be included.
    1.23  set (SRCS_${App_Name}
    1.24 -  src/Vector.cpp
    1.25 -  src/Matrix.cpp
    1.26    include/Math.h
    1.27    include/Vector.h
    1.28 -  include/Matrix.h
    1.29  )
    1.30  
    1.31  include_directories (
    1.32 @@ -162,19 +167,19 @@
    1.33  # clobber each others temp files since they are being built from the same
    1.34  # sources.
    1.35  
    1.36 -add_library (${App_Name} SHARED
    1.37 -  ${SRCS_${App_Name}}
    1.38 -)
    1.39 -set_target_properties (${App_Name} PROPERTIES OUTPUT_NAME ${App_Name})
    1.40 -set_target_properties (${App_Name} PROPERTIES PREFIX "lib")
    1.41 -set_target_properties (${App_Name} PROPERTIES CLEAN_DIRECT_OUTPUT 1)
    1.42 -
    1.43 -add_library (${App_Name}-static STATIC
    1.44 -  ${SRCS_${App_Name}}
    1.45 -)
    1.46 -set_target_properties (${App_Name}-static PROPERTIES OUTPUT_NAME ${App_Name})
    1.47 -set_target_properties (${App_Name}-static PROPERTIES PREFIX "lib")
    1.48 -set_target_properties (${App_Name}-static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
    1.49 +#add_library (${App_Name} SHARED
    1.50 +#  ${SRCS_${App_Name}}
    1.51 +#)
    1.52 +#set_target_properties (${App_Name} PROPERTIES OUTPUT_NAME ${App_Name})
    1.53 +#set_target_properties (${App_Name} PROPERTIES PREFIX "lib")
    1.54 +#set_target_properties (${App_Name} PROPERTIES CLEAN_DIRECT_OUTPUT 1)
    1.55 +#
    1.56 +#add_library (${App_Name}-static STATIC
    1.57 +#  ${SRCS_${App_Name}}
    1.58 +#)
    1.59 +#set_target_properties (${App_Name}-static PROPERTIES OUTPUT_NAME ${App_Name})
    1.60 +#set_target_properties (${App_Name}-static PROPERTIES PREFIX "lib")
    1.61 +#set_target_properties (${App_Name}-static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
    1.62  
    1.63  # Build a test application.
    1.64  
    1.65 @@ -190,6 +195,6 @@
    1.66  )
    1.67  
    1.68  target_link_libraries (${App_Name}-test
    1.69 -  ${App_Name}
    1.70 +#  ${App_Name}
    1.71  )
    1.72  
     2.1 --- a/include/Math.h	Tue Sep 06 11:26:39 2011 -0500
     2.2 +++ b/include/Math.h	Wed Sep 28 12:48:42 2011 -0500
     2.3 @@ -2,7 +2,7 @@
     2.4  #define MATH_H_
     2.5  
     2.6  #include "Vector.h"
     2.7 -#include "Matrix.h"
     2.8 +// #include "Matrix.h"
     2.9  
    2.10  namespace arda 
    2.11     {
     3.1 --- a/include/Matrix.h	Tue Sep 06 11:26:39 2011 -0500
     3.2 +++ b/include/Matrix.h	Wed Sep 28 12:48:42 2011 -0500
     3.3 @@ -406,6 +406,115 @@
     3.4        float * transpose4(Matrix4f m, Matrix4f mres);
     3.5        double * transpose4(Matrix4d m, Matrix4d mres);
     3.6  
     3.7 +      //////////////////////////////////////////////////////////////////////////
     3.8 +      // det*(Matrix m)
     3.9 +      //	Computer the determinant of a matrix.
    3.10 +      //	Returns the determinant.
    3.11 +
    3.12 +      inline double det2(Matrix2i m)
    3.13 +	 { return m[0] * m[3] - m[1] * m[2]; }
    3.14 +      inline double det2(Matrix2f m)
    3.15 +	 { return m[0] * m[3] - m[1] * m[2]; }
    3.16 +      inline double det2(Matrix2d m)
    3.17 +	 { return m[0] * m[3] - m[1] * m[2]; }
    3.18 +
    3.19 +      inline double det3(Matrix3i m)
    3.20 +	 { return m[0] * (  m[4] * m[8]  
    3.21 +			  - m[5] * m[7])  
    3.22 +	       -  m[3] * (  m[1] * m[8]
    3.23 +			  - m[2] * m[7]) 
    3.24 +	       +  m[6] * (  m[1] * m[5] 
    3.25 +			  - m[2] * m[4]); }
    3.26 +      inline double det3(Matrix3f m)
    3.27 +	 { return m[0] * (  m[4] * m[8] 
    3.28 +			  - m[5] * m[7])  
    3.29 +	       -  m[3] * (  m[1] * m[8] 
    3.30 +                          - m[2] * m[7]) 
    3.31 +	       +  m[6] * (  m[1] * m[5] 
    3.32 +			    - m[2] * m[4]); }
    3.33 +      inline double det3(Matrix3d m)
    3.34 +	 { return m[0] * (  m[4] * m[8] 
    3.35 +			  - m[5] * m[7])
    3.36 +	       - m[3] * (  m[1] * m[8] 
    3.37 +			 - m[2] * m[7])
    3.38 +	       + m[6] * (m[1] * m[5] 
    3.39 +			 - m[2] * m[4]); }
    3.40 +
    3.41 +      inline double det4(Matrix4i m)
    3.42 +	 { return m[0] * (m[5] * (m[10] * m[15] - 
    3.43 +				  m[11] * m[14]) - 
    3.44 +			  m[9] * (m[6] * m[15] - 
    3.45 +				  m[7] * m[14]) +
    3.46 +			  m[13] * (m[6] * m[11] - 
    3.47 +				   m[7] * m[10])) -
    3.48 +	       m[4] * (m[1] * (m[10] * m[15] - 
    3.49 +			       m[11] * m[14]) - 
    3.50 +		       m[9] * (m[2] * m[15] - 
    3.51 +			       m[3] * m[14]) +
    3.52 +		       m[13] * (m[2] * m[11] - 
    3.53 +				m[3] * m[10])) +
    3.54 +	       m[8] * (m[1] * (m[6] * m[15] - 
    3.55 +			       m[7] * m[14]) - 
    3.56 +		       m[5] * (m[2] * m[15] - 
    3.57 +			       m[3] * m[14]) +
    3.58 +		       m[13] * (m[2] * m[7] - 
    3.59 +				m[3] * m[6])) +
    3.60 +	       m[12] * (m[1] * (m[6] * m[11] - 
    3.61 +				m[7] * m[10]) - 
    3.62 +			m[5] * (m[2] * m[11] - 
    3.63 +				m[3] * m[10]) +
    3.64 +			m[9] * (m[2] * m[7] - 
    3.65 +				m[3] * m[6])); }
    3.66 +      inline double det4(Matrix4f m)
    3.67 +	 { return m[0] * (m[5] * (m[10] * m[15] - 
    3.68 +				  m[11] * m[14]) - 
    3.69 +			  m[9] * (m[6] * m[15] - 
    3.70 +				  m[7] * m[14]) +
    3.71 +			  m[13] * (m[6] * m[11] - 
    3.72 +				   m[7] * m[10])) -
    3.73 +	       m[4] * (m[1] * (m[10] * m[15] - 
    3.74 +			       m[11] * m[14]) - 
    3.75 +		       m[9] * (m[2] * m[15] - 
    3.76 +			       m[3] * m[14]) +
    3.77 +		       m[13] * (m[2] * m[11] - 
    3.78 +				m[3] * m[10])) +
    3.79 +	       m[8] * (m[1] * (m[6] * m[15] - 
    3.80 +			       m[7] * m[14]) - 
    3.81 +		       m[5] * (m[2] * m[15] - 
    3.82 +			       m[3] * m[14]) +
    3.83 +		       m[13] * (m[2] * m[7] - 
    3.84 +				m[3] * m[6])) +
    3.85 +	       m[12] * (m[1] * (m[6] * m[11] - 
    3.86 +				m[7] * m[10]) - 
    3.87 +			m[5] * (m[2] * m[11] - 
    3.88 +				m[3] * m[10]) +
    3.89 +			m[9] * (m[2] * m[7] - 
    3.90 +				m[3] * m[6])); }
    3.91 +      inline double det4(Matrix4d m)
    3.92 +	 { return m[0] * (m[5] * (m[10] * m[15] - 
    3.93 +				  m[11] * m[14]) - 
    3.94 +			  m[9] * (m[6] * m[15] - 
    3.95 +				  m[7] * m[14]) +
    3.96 +			  m[13] * (m[6] * m[11] - 
    3.97 +				   m[7] * m[10])) -
    3.98 +	       m[4] * (m[1] * (m[10] * m[15] - 
    3.99 +			       m[11] * m[14]) - 
   3.100 +		       m[9] * (m[2] * m[15] - 
   3.101 +			       m[3] * m[14]) +
   3.102 +		       m[13] * (m[2] * m[11] - 
   3.103 +				m[3] * m[10])) +
   3.104 +	       m[8] * (m[1] * (m[6] * m[15] - 
   3.105 +			       m[7] * m[14]) - 
   3.106 +		       m[5] * (m[2] * m[15] - 
   3.107 +			       m[3] * m[14]) +
   3.108 +		       m[13] * (m[2] * m[7] - 
   3.109 +				m[3] * m[6])) +
   3.110 +	       m[12] * (m[1] * (m[6] * m[11] - 
   3.111 +				m[7] * m[10]) - 
   3.112 +			m[5] * (m[2] * m[11] - 
   3.113 +				m[3] * m[10]) +
   3.114 +			m[9] * (m[2] * m[7] - 
   3.115 +				m[3] * m[6])); }
   3.116        } // namespace Matrix
   3.117  
   3.118     } // namespace arda
     4.1 --- a/include/Vector.h	Tue Sep 06 11:26:39 2011 -0500
     4.2 +++ b/include/Vector.h	Wed Sep 28 12:48:42 2011 -0500
     4.3 @@ -1,420 +1,497 @@
     4.4  #ifndef VECTOR_H_
     4.5  #define VECTOR_H_
     4.6  
     4.7 +#include <cassert>
     4.8  #include <cmath>
     4.9  #include <string>
    4.10 +#include <iostream>
    4.11 +#include <sstream>
    4.12 +
    4.13  
    4.14  namespace arda 
    4.15     {
    4.16 -   namespace Vector 
    4.17 +   ////////////////////////////////////////////////////////////////////////////////
    4.18 +   // Vectors
    4.19 +   //
    4.20 +   // Templated classes for 2, 3, and 4 dimensional vectors of any type,
    4.21 +   //     although these types are really intended to be int, float, and double 
    4.22 +   //     only.  (i.e. if you roll your own base type, it had better act like
    4.23 +   //     a numeric scalar.)
    4.24 +   //
    4.25 +   // Supported operations on vectors
    4.26 +   //
    4.27 +   // Construction
    4.28 +   //     Vector v;             // Default zero vector.
    4.29 +   //     Vector v2(v);         // Construct from other vector.
    4.30 +   //     T a, b;
    4.31 +   //     Vector v(a, b)        // Construct from values.
    4.32 +   // []
    4.33 +   //     If you have a Vector named v you can access it's member elements as
    4.34 +   //     v[0], v[1], v[2], and v[3]. in addtion to v.x, v.y, v.z, and v.w
    4.35 +   // == != + += - -=
    4.36 +   //     Defined for operations on two vectors of the same type.
    4.37 +   // * *= / /=
    4.38 +   //     Defined for scalar multiplication/division with int, float, and double.
    4.39 +   //     *= and /= are defined as member functions, but * and / are defined
    4.40 +   //     as standalone template operators so that I can support v*a as well as
    4.41 +   //     a*v order of multiplication.
    4.42 +   // assign(T a, T b [, T b [, T d]])
    4.43 +   //     Directly assign values to the vector.
    4.44 +   // cross(Vector3& v2)
    4.45 +   // cross(Vector3& v2, Vector3& vres)
    4.46 +   //     Cross product of the vector with v2.  Only defined for Vector3 types.
    4.47 +   //     The version that takes two arguments stores the result in the second
    4.48 +   //     argument.  This may be faster since no temporary object is created
    4.49 +   //     during the operation.
    4.50 +   // dot(Vector& v2)
    4.51 +   //     The dot product of the vector with v2.
    4.52 +   // get_angle(Vector& v2)
    4.53 +   //     Returns the angle (in radians) between the vector and v2.
    4.54 +   //     Not meaningful for int vectors.
    4.55 +   // get_anglen(Vector& v2)
    4.56 +   //     Like get_angle(), but the vectors must already be normalized.
    4.57 +   //     Not meaningful for int vectors.
    4.58 +   // getstring(std::string & s)
    4.59 +   //     Returns a C string representation of the vector.
    4.60 +   //     This is one of the few non-inline Vector functions.
    4.61 +   // length()
    4.62 +   //     Get the length of a vector.
    4.63 +   //     Returns a double for all vector types.
    4.64 +   // normalize()
    4.65 +   //     Normalizes the vecor.
    4.66 +   //     Not meaningful for int vectors.
    4.67 +   // proj(Vector& v2, Vector& vres)
    4.68 +   //     Calculates the projection of the vector onto v2 and returns the result 
    4.69 +   //     in vres. 
    4.70 +   //     Not meaningful for int vectors.
    4.71 +   //     Returns vres.
    4.72 +   //
    4.73 +   //
    4.74 +   // Note that the following typedefs are defined for convenience:
    4.75 +   //
    4.76 +   // typedef Vector2<int> Vector2i;
    4.77 +   // typedef Vector2<float> Vector2f;
    4.78 +   // typedef Vector2<double> Vector2d;
    4.79 +   // typedef Vector3<int> Vector3i;
    4.80 +   // typedef Vector3<float> Vector3f;
    4.81 +   // typedef Vector3<double> Vector3d;
    4.82 +   // typedef Vector4<int> Vector4i;
    4.83 +   // typedef Vector4<float> Vector4f;
    4.84 +   // typedef Vector4<double> Vector4d;
    4.85 +   //
    4.86 +   //
    4.87 +   // Scalar multiplication and division are overloaded.  Why?
    4.88 +   // I'm not sure I need this.  The idea is to support all likely scalar
    4.89 +   // types without having to rely on implicit or explicity type conversion,
    4.90 +   // especially not a conversion that might result in loss of precision.
    4.91 +   // Multiplying a float Vector by a double scala, for example.
    4.92 +   // Is there a better way to do this?
    4.93 +
    4.94 +
    4.95 +
    4.96 +   /////////////////////////////////////////////////////////////////////////////
    4.97 +   template <class T> class Vector2
    4.98        {
    4.99 +      public:
   4.100 +      T x, y;
   4.101  
   4.102 -      ////////////////////////////////////////////////////////////////////////////////
   4.103 -      // Vectors
   4.104 -      //
   4.105 -      // Supported operations on vectors
   4.106 -      //
   4.107 -      // assign*()	Assign the value of one vector to another.
   4.108 -      // add*()		Add two vectors
   4.109 -      // cross()	Cross product of two 3-space vectors.
   4.110 -      // dot*()		Dot product.
   4.111 -      // get_angle*()	Calculate angle between two vectors.
   4.112 -      // length*()	Length of a vector (the Euclidean norm).
   4.113 -      // normalize*()	Normalize the vector.
   4.114 -      // proj*()	Calculate the projection of one vector onto another.
   4.115 -      // scale*()	Multiply vector by a scalar.
   4.116 -      // subtract*()	A convenience function to avoid writing add(v1, scale(v2, -1))
   4.117 -      // getstring*()	Returns a printable string representation of the vector.
   4.118 -      //
   4.119 -      // All functions except getstring are defined inline.
   4.120 +      // Constructors
   4.121 +      Vector2() : x (0), y(0) {}
   4.122 +      Vector2(T a) : x (a), y(a) {}
   4.123 +      Vector2(T a, T b) : x (a), y(b) {}
   4.124  
   4.125 -      typedef int Vector2i[2];
   4.126 -      typedef float Vector2f[2];
   4.127 -      typedef double Vector2d[2];
   4.128 +      // Array indexing
   4.129 +      inline T& operator[](unsigned int i)
   4.130 +	 { assert (i<2); if (i==0) return x; return y; }
   4.131 +      inline const T& operator[](unsigned int i) const
   4.132 +	 { assert (i<2); if (i==0) return x; return y; }
   4.133  
   4.134 -      typedef int Vector3i[3];
   4.135 -      typedef float Vector3f[3];
   4.136 -      typedef double Vector3d[3];
   4.137 +      // Assignment
   4.138 +      inline Vector2<T>& operator=(const Vector2<T>& v2)
   4.139 +	 { x = v2.x; y = v2.y; return *this; }
   4.140 +      inline Vector2<T>& assign(const T a, const T b)
   4.141 +	 { x = a; y = b; return *this; }
   4.142  
   4.143 -      typedef int Vector4i[4];
   4.144 -      typedef float Vector4f[4];
   4.145 -      typedef double Vector4d[4];
   4.146 +      // Comparison
   4.147 +      inline bool operator==(Vector2<T>& v2) const
   4.148 +	 { return ((x == v2.x) && (y == v2.y)); }
   4.149 +      inline bool operator!=(Vector2<T>& v2) const
   4.150 +	 { return ! ((x == v2.x) && (y == v2.y)); }
   4.151  
   4.152 -      //////////////////////////////////////////////////////////////////////////
   4.153 -      // getstring*(Vector v)
   4.154 -      //	Returns a C string representation of the vector.
   4.155 -      //	This is one of the few non-inline Vector functions.
   4.156 +      // Vector addition
   4.157 +      inline Vector2<T> operator+(const Vector2<T>& v2) const
   4.158 +	 { Vector2<T> vres; vres.x = x + v2.x; vres.y = y + v2.y; return vres; }
   4.159 +      inline Vector2<T>& operator+=(const Vector2<T>& v2)
   4.160 +	 { x += v2.x; y += v2.y; return *this; }
   4.161  
   4.162 -      std::string & getstring2v(Vector2i v, std::string & s);
   4.163 -      std::string & getstring2v(Vector2f v, std::string & s);
   4.164 -      std::string & getstring2v(Vector2d v, std::string & s);
   4.165 -      std::string & getstring3v(Vector3i v, std::string & s);
   4.166 -      std::string & getstring3v(Vector3f v, std::string & s);
   4.167 -      std::string & getstring3v(Vector3d v, std::string & s);
   4.168 -      std::string & getstring4v(Vector4i v, std::string & s);
   4.169 -      std::string & getstring4v(Vector4f v, std::string & s);
   4.170 -      std::string & getstring4v(Vector4d v, std::string & s);
   4.171 -      
   4.172 -      //////////////////////////////////////////////////////////////////////////
   4.173 -      // scale*(Vector v, scalar s)
   4.174 -      //	Multiply a vector by a scalar.
   4.175 -      //	Returns v so that the result may be passed to other functions.
   4.176 +      // Vector subtraction
   4.177 +      inline Vector2<T> operator-(const Vector2<T>& v2) const
   4.178 +	 { Vector2<T> vres; vres.x = x - v2.x; vres.y = y - v2.y; return vres; }
   4.179 +      inline Vector2<T>& operator-=(const Vector2<T>& v2)
   4.180 +	 { x -= v2.x; y -= v2.y; return *this; }
   4.181  
   4.182 -      inline int * scale2v(Vector2i v, const int s)
   4.183 -	 { v[0] *= s ; v[1] *= s; return v; }
   4.184 -      inline int * scale2v(Vector2i v, const float s)
   4.185 -	 { v[0] *= s ; v[1] *= s; return v; }
   4.186 -      inline int * scale2v(Vector2i v, const double s)
   4.187 -	 { v[0] *= s ; v[1] *= s; return v; }
   4.188 +      // Scalar multiplication
   4.189 +      inline Vector2<T>& operator*=(const int a)
   4.190 +	 { x *= a; y *= a; return *this; }
   4.191 +      inline Vector2<T>& operator*=(const float a)
   4.192 +	 { x *= a; y *= a; return *this; }
   4.193 +      inline Vector2<T>& operator*=(const double a)
   4.194 +	 { x *= a; y *= a; return *this; }
   4.195  
   4.196 -      inline float * scale2v(Vector2f v, const int s)
   4.197 -	 { v[0] *= s ; v[1] *= s; return v; }
   4.198 -      inline float * scale2v(Vector2f v, const float s)
   4.199 -	 { v[0] *= s ; v[1] *= s; return v; }
   4.200 -      inline float * scale2v(Vector2f v, const double s)
   4.201 -	 { v[0] *= s ; v[1] *= s; return v; }
   4.202 +      // Scalar division
   4.203 +      inline Vector2<T>& operator/=(const int a)
   4.204 +	 { assert(a!=0); x /= a; y /= a; return *this; }
   4.205 +      inline Vector2<T>& operator/=(const float a)
   4.206 +	 { assert(a!=0); x /= a; y /= a; return *this; }
   4.207 +      inline Vector2<T>& operator/=(const double a)
   4.208 +	 { assert(a!=0); x /= a; y /= a; return *this; }
   4.209  
   4.210 -      inline double * scale2v(Vector2d v, const int s)
   4.211 -	 { v[0] *= s ; v[1] *= s; return v; }
   4.212 -      inline double * scale2v(Vector2d v, const float s)
   4.213 -	 { v[0] *= s ; v[1] *= s; return v; }
   4.214 -      inline double * scale2v(Vector2d v, const double s)
   4.215 -	 { v[0] *= s ; v[1] *= s; return v; }
   4.216  
   4.217 +      // methods
   4.218  
   4.219 -      inline int * scale3v(Vector3i v, const int s)
   4.220 -	 { v[0] *= s ; v[1] *= s; v[2] *= s; return v; }
   4.221 -      inline int * scale3v(Vector3i v, const float s)
   4.222 -	 { v[0] *= s ; v[1] *= s; v[2] *= s; return v; }
   4.223 -      inline int * scale3v(Vector3i v, const double s)
   4.224 -	 { v[0] *= s ; v[1] *= s; v[2] *= s; return v; }
   4.225 - 
   4.226 -      inline float * scale3v(Vector3f v, const int s)
   4.227 -	 { v[0] *= s ; v[1] *= s; v[2] *= s; return v; }
   4.228 -      inline float * scale3v(Vector3f v, const float s)
   4.229 -	 { v[0] *= s ; v[1] *= s; v[2] *= s; return v; }
   4.230 -      inline float * scale3v(Vector3f v, const double s)
   4.231 -	 { v[0] *= s ; v[1] *= s; v[2] *= s; return v; }
   4.232 +      inline T dot(const Vector2<T>& v2) const
   4.233 +	 { return x*v2.x + y*v2.y; }
   4.234  
   4.235 -      inline double * scale3v(Vector3d v, const int s)
   4.236 -	 { v[0] *= s ; v[1] *= s; v[2] *= s; return v; }
   4.237 -      inline double *  scale3v(Vector3d v, const float s)
   4.238 -	 { v[0] *= s ; v[1] *= s; v[2] *= s; return v; }
   4.239 -      inline double * scale3v(Vector3d v, const double s)
   4.240 -	 { v[0] *= s ; v[1] *= s; v[2] *= s; return v; }
   4.241 +      inline double get_angle(Vector2<T>& v2)
   4.242 +	 { 
   4.243 +	 double tmp = dot(v2); 
   4.244 +	 return acos(sqrt(tmp*tmp/(dot(*this)*v2.dot(v2))));
   4.245 +	 }
   4.246  
   4.247 +      inline double get_anglen(Vector2<T>& v2)
   4.248 +	 { return acos((double) dot(v2)); }
   4.249  
   4.250 -      inline int * scale4v(Vector4i v, const int s) 
   4.251 -	 { v[0] *= s ; v[1] *= s;  v[2] *= s;  v[3] *= s; return v; }
   4.252 -      inline int * scale4v(Vector4i v, const float s) 
   4.253 -	 { v[0] *= s ; v[1] *= s;  v[2] *= s;  v[3] *= s; return v; }
   4.254 -      inline int * scale4v(Vector4i v, const double s) 
   4.255 -	 { v[0] *= s ; v[1] *= s;  v[2] *= s;  v[3] *= s; return v; }
   4.256 +      std::string & getstring(std::string & s) const;
   4.257  
   4.258 -      inline float * scale4v(Vector4f v, const int s) 
   4.259 -	 { v[0] *= s ; v[1] *= s;  v[2] *= s;  v[3] *= s; return v; }
   4.260 -      inline float * scale4v(Vector4f v, const float s) 
   4.261 -	 { v[0] *= s ; v[1] *= s;  v[2] *= s;  v[3] *= s; return v; }
   4.262 -      inline float * scale4v(Vector4f v, const double s) 
   4.263 -	 { v[0] *= s ; v[1] *= s;  v[2] *= s;  v[3] *= s; return v; }
   4.264 +      inline double length(void) const
   4.265 +	 { return sqrt((dot(*this))); }
   4.266  
   4.267 -      inline double * scale4v(Vector4d v, const int s) 
   4.268 -	 { v[0] *= s ; v[1] *= s;  v[2] *= s;  v[3] *= s; return v; }
   4.269 -      inline double * scale4v(Vector4d v, const float s) 
   4.270 -	 { v[0] *= s ; v[1] *= s;  v[2] *= s;  v[3] *= s; return v; }
   4.271 -      inline double * scale4v(Vector4d v, const double s) 
   4.272 -	 { v[0] *= s ; v[1] *= s;  v[2] *= s;  v[3] *= s; return v; }
   4.273 +      inline Vector2<T>& normalize()
   4.274 +	 { double l = length(); if (l == 0.0) return *this; x /= l; y /= l; return *this; }
   4.275  
   4.276 +      inline Vector2<T> proj(Vector2<T>& v2)
   4.277 +	 { Vector2<T> vres; vres = v2 * dot(v2)/v2.dot(v2); return vres; }
   4.278 +      inline Vector2<T>& proj(Vector2<T>& v2, Vector2<T>& vres)
   4.279 +	 { vres = v2 * dot(v2)/v2.dot(v2); return vres; }
   4.280 +      };
   4.281  
   4.282 -      //////////////////////////////////////////////////////////////////////////
   4.283 -      // dot*(Vector v1, Vector v2)
   4.284 -      //	The dot product of two vectors, which must be the same type
   4.285 -      //	Returns a long for int vectors, a double for floating point vectors.
   4.286 +   // Scalar multiplication, continued
   4.287 +   template <class T> inline Vector2<T> operator*(const Vector2<T>& v, const int a)
   4.288 +         { return Vector2<T>(v) *= a;}
   4.289 +   template <class T> inline Vector2<T> operator*(const int a, const Vector2<T>& v)
   4.290 +         { return Vector2<T>(v) *= a;}
   4.291 +   template <class T> inline Vector2<T> operator*(const Vector2<T> v, const float a)
   4.292 +      { return Vector2<T>(v) *= a;}
   4.293 +   template <class T> inline Vector2<T> operator*(const float a, const Vector2<T> v)
   4.294 +      { return Vector2<T>(v) *= a;}
   4.295 +   template <class T> inline Vector2<T> operator*(const Vector2<T>& v, const double a)
   4.296 +      { return Vector2<T>(v) *= a;}
   4.297 +   template <class T> inline Vector2<T> operator*(const double a, const Vector2<T>& v)
   4.298 +      { return Vector2<T>(v) *= a;}
   4.299  
   4.300 -      inline long dot2v(Vector2i v1, Vector2i v2)
   4.301 -	 { return (long) v1[0]*v2[0] + (long) v1[1]*v2[1]; }
   4.302 -      inline double dot2v(Vector2f v1, Vector2f v2)
   4.303 -	 { return (double) v1[0]*v2[0] + (double) v1[1]*v2[1]; }
   4.304 -      inline double dot2v(Vector2d v1, Vector2d v2)
   4.305 -	 { return v1[0]*v2[0] + v1[1]*v2[1]; }
   4.306 +   // Scalar division, continued
   4.307 +   template <class T> inline Vector2<T> operator/(const Vector2<T>& v, const int a)
   4.308 +      { return Vector2<T>(v) /= a;}
   4.309 +   template <class T> inline Vector2<T> operator/(const int a, const Vector2<T>& v)
   4.310 +      { return Vector2<T>(v) /= a;}
   4.311 +   template <class T> inline Vector2<T> operator/(const Vector2<T>& v, const float a)
   4.312 +      { return Vector2<T>(v) /= a;}
   4.313 +   template <class T> inline Vector2<T> operator/(const float a, const Vector2<T>& v)
   4.314 +      { return Vector2<T>(v) /= a;}
   4.315 +   template <class T> inline Vector2<T> operator/(const Vector2<T>& v, const double a)
   4.316 +      { return Vector2<T>(v) /= a;}
   4.317 +   template <class T> inline Vector2<T> operator/(const double a, const Vector2<T>& v)
   4.318 +      { return Vector2<T>(v) /= a;}
   4.319  
   4.320 -      inline long dot3v(Vector3i v1, Vector3i v2)
   4.321 -	 { return (long) v1[0]*v2[0] + (long) v1[1]*v2[1] + (long) v1[2]*v2[2]; }
   4.322 -      inline double dot3v(Vector3f v1, Vector3f v2)
   4.323 -	 { return (double) v1[0]*v2[0] + (double) v1[1]*v2[1] + (double) v1[2]*v2[2]; }
   4.324 -      inline double dot3v(Vector3d v1, Vector3d v2)
   4.325 -	 { return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; }
   4.326 +   /////////////////////////////////////////////////////////////////////////////
   4.327 +   template <class T> class Vector3
   4.328 +      {
   4.329 +      public:
   4.330 +      T x, y, z;
   4.331  
   4.332 -      inline long dot4v(Vector4i v1, Vector4i v2)
   4.333 -	 { return (long) v1[0]*v2[0] + (long) v1[1]*v2[1] + (long) v1[2]*v2[2] + (long) v1[3]*v2[3]; }
   4.334 -      inline double dot4v(Vector4f v1, Vector4f v2)
   4.335 -	 { return (double) v1[0]*v2[0] + (double) v1[1]*v2[1] + (double) v1[2]*v2[2] + (double) v1[3]*v2[3]; }
   4.336 -      inline double dot4v(Vector4d v1, Vector4d v2)
   4.337 -	 { return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2] + v1[3]*v2[3]; }
   4.338 +      // Constructors
   4.339 +      Vector3() : x (0), y(0), z(0) {}
   4.340 +      Vector3(T a) : x (a), y(a), z(a) {}
   4.341 +      Vector3(T a, T b, T c) : x (a), y(b), z(c) {}
   4.342  
   4.343 +      // Array indexing
   4.344 +      inline T& operator[](unsigned int i)
   4.345 +	 { assert (i<3); if (i==0) return x; if (i==1) return y; return z; }
   4.346 +      inline const T& operator[](unsigned int i) const
   4.347 +	 { assert (i<3); if (i==0) return x; if (i==1) return y; return z; }
   4.348  
   4.349 -      //////////////////////////////////////////////////////////////////////////
   4.350 -      // length*(Vector v)
   4.351 -      //	Get the length of a vector.
   4.352 -      //	Returns a float for float for float vectors, and a double for 
   4.353 -      //	int and double vectors.
   4.354 +      // Assignment
   4.355 +      inline Vector3<T>& operator=(const Vector3<T>& v2)
   4.356 +	 { x = v2.x; y = v2.y; z = v2.z; return *this; }
   4.357 +      inline Vector3<T>& assign(const T a, const T b, const T c)
   4.358 +	 { x = a; y = b; z = c; return *this; }
   4.359  
   4.360 -      inline double length2v(Vector2i v)
   4.361 -	 { return sqrt((dot2v(v, v))); }
   4.362 -      inline double length2v(Vector2f v)
   4.363 -	 { return sqrtf((dot2v(v, v))); }
   4.364 -      inline double length2v(Vector2d v)
   4.365 -	 { return sqrt((dot2v(v, v))); }
   4.366 +      // Comparison
   4.367 +      inline bool operator==(Vector3<T>& v2) const
   4.368 +	 { return ((x == v2.x) && (y == v2.y) && (z == v2.z)); }
   4.369 +      inline bool operator!=(Vector3<T>& v2) const
   4.370 +	 { return ! ((x == v2.x) && (y == v2.y) && (z == v2.z)); }
   4.371  
   4.372 -      inline double length3v(Vector3i v)
   4.373 -	 { return sqrt((dot3v(v, v))); }
   4.374 -      inline double length3v(Vector3f v)
   4.375 -	 { return sqrtf((dot3v(v, v))); }
   4.376 -      inline double length3v(Vector3d v)
   4.377 -	 { return sqrt((dot3v(v, v))); }
   4.378 +      // Vector addition
   4.379 +      inline Vector3<T> operator+(const Vector3<T>& v2) const
   4.380 +	 { Vector3<T> vres; vres.x = x + v2.x; vres.y = y + v2.y; vres.z = z + v2.z; return vres; }
   4.381 +      inline Vector3<T>& operator+=(const Vector3<T>& v2)
   4.382 +	 { x += v2.x; y += v2.y; z += v2.z; return *this; }
   4.383  
   4.384 -      inline double length4v(Vector4i v)
   4.385 -	 { return sqrt((dot4v(v, v))); }
   4.386 -      inline double length4v(Vector4f v)
   4.387 -	 { return sqrtf((dot4v(v, v))); }
   4.388 -      inline double length4v(Vector4d v)
   4.389 -	 { return sqrt((dot4v(v, v))); }
   4.390 +      // Vector subtraction
   4.391 +      inline Vector3<T> operator-(const Vector3<T>& v2) const
   4.392 +	 { Vector3<T> vres; vres.x = x - v2.x; vres.y = y - v2.y; vres.z = z - v2.z; return vres; }
   4.393 +      inline Vector3<T>& operator-=(const Vector3<T>& v2)
   4.394 +	 { x -= v2.x; y -= v2.y; z -= v2.z; return *this; }
   4.395  
   4.396 +      // Scalar multiplication
   4.397 +      inline Vector3<T>& operator*=(const int a)
   4.398 +	 { x *= a; y *= a; z *= a; return *this; }
   4.399 +      inline Vector3<T>& operator*=(const float a)
   4.400 +	 { x *= a; y *= a; z *= a; return *this; }
   4.401 +      inline Vector3<T>& operator*=(const double a)
   4.402 +	 { x *= a; y *= a; z *= a; return *this; }
   4.403  
   4.404 -      //////////////////////////////////////////////////////////////////////////
   4.405 -      // add*(Vector v1, Vector v2)
   4.406 -      //	Add v2 to v1.
   4.407 -      //        Returns v1 so that the result may be used in further 
   4.408 -      //	calculations.
   4.409 +      // Scalar division
   4.410 +      inline Vector3<T>& operator/=(const int a)
   4.411 +	 { assert(a!=0); x /= a; y /= a; z /= a; return *this; }
   4.412 +      inline Vector3<T>& operator/=(const float a)
   4.413 +	 { assert(a!=0); x /= a; y /= a; z /= a; return *this; }
   4.414 +      inline Vector3<T>& operator/=(const double a)
   4.415 +	 { assert(a!=0); x /= a; y /= a; z /= a; return *this; }
   4.416  
   4.417 -      inline int * add2v(Vector2i v1, Vector2i v2)
   4.418 -	 { v1[0] += v2[0]; v1[1] += v2[1]; return v1; }
   4.419 -      inline float * add2v(Vector2f v1, Vector2f v2)
   4.420 -	 { v1[0] += v2[0]; v1[1] += v2[1]; return v1; }
   4.421 -      inline double * add2v(Vector2d v1, Vector2d v2)
   4.422 -	 { v1[0] += v2[0]; v1[1] += v2[1]; return v1; }
   4.423  
   4.424 -      inline int * add3v(Vector3i v1, Vector3i v2)
   4.425 -	 { v1[0] += v2[0]; v1[1] += v2[1]; v1[2] += v2[2]; return v1; }
   4.426 -      inline float * add3v(Vector3f v1, Vector3f v2)
   4.427 -	 { v1[0] += v2[0]; v1[1] += v2[1]; v1[2] += v2[2];  return v1; }
   4.428 -      inline double * add3v(Vector3d v1, Vector3d v2)
   4.429 -	 { v1[0] += v2[0]; v1[1] += v2[1]; v1[2] += v2[2];  return v1; }
   4.430 +      // methods
   4.431  
   4.432 -      inline int * add4v(Vector4i v1, Vector4i v2)
   4.433 -	 { v1[0] += v2[0]; v1[1] += v2[1]; v1[2] += v2[2]; v1[3] += v2[3]; return v1; }
   4.434 -      inline float * add4v(Vector4f v1, Vector4f v2)
   4.435 -	 { v1[0] += v2[0]; v1[1] += v2[1]; v1[2] += v2[2]; v1[3] += v2[3]; return v1; }
   4.436 -      inline double * add4v(Vector4d v1, Vector4d v2)
   4.437 -	 { v1[0] += v2[0]; v1[1] += v2[1]; v1[2] += v2[2]; v1[3] += v2[3]; return v1; }
   4.438 -
   4.439 -      //////////////////////////////////////////////////////////////////////////
   4.440 -      // normalize*(Vector v)
   4.441 -      //	Normalizes the vecor.  Only defined for floating point vectors.
   4.442 -      //	Returns the vector.
   4.443 -
   4.444 -      inline float * normalize2v(Vector2f v)
   4.445 -	 { double l = length2v(v); v[0] /= l; v[1] /= l; return v; }
   4.446 -      inline double * normalize2v(Vector2d v)
   4.447 -	 { double l = length2v(v); v[0] /= l; v[1] /= l; return v; }
   4.448 -
   4.449 -      inline float * normalize3v(Vector3f v)
   4.450 -	 { double l = length3v(v); v[0] /= l; v[1] /= l; v[2] /= l; return v; }
   4.451 -      inline double * normalize3v(Vector3d v)
   4.452 -	 { double l = length3v(v); v[0] /= l; v[1] /= l; v[2] /= l; return v; }
   4.453 -
   4.454 -      inline float * normalize4v(Vector4f v)
   4.455 -	 { double l = length4v(v); v[0] /= l; v[1] /= l; v[2] /= l; v[3] /= l; return v; }
   4.456 -      inline double * normalize4v(Vector4d v)
   4.457 -	 { double l = length4v(v); v[0] /= l; v[1] /= l; v[2] /= l; v[3] /= l; return v; }
   4.458 -
   4.459 -      //////////////////////////////////////////////////////////////////////////
   4.460 -      // cross(Vector3 v)
   4.461 -      //	Only defined for floating point 3 vectors.
   4.462 -      //	Returns the result vector.
   4.463 -
   4.464 -      inline float * cross(Vector3f v1, Vector3f v2, Vector3f vres)
   4.465 +      inline Vector3<T>& cross(Vector3<T>& v2, Vector3<T>& vres)
   4.466  	 { 
   4.467 -	 vres[0] =  v1[1]*v2[2] - v2[1]*v1[2];
   4.468 -	 vres[1] = -v1[0]*v2[2] + v2[0]*v1[2];
   4.469 -	 vres[2] =  v1[0]*v2[1] - v2[0]*v1[1];
   4.470 +	 vres.x =  y*v2.z - v2.y*z;
   4.471 +	 vres.y = -x*v2.z + v2.x*z;
   4.472 +	 vres.z =  x*v2.y - v2.x*y;
   4.473 +	 return vres;
   4.474 +	 }
   4.475 +      inline Vector3<T> cross(Vector3<T>& v2)
   4.476 +	 { 
   4.477 +	 Vector3<T> vres;
   4.478 +	 vres.x =  y*v2.z - v2.y*z;
   4.479 +	 vres.y = -x*v2.z + v2.x*z;
   4.480 +	 vres.z =  x*v2.y - v2.x*y;
   4.481  	 return vres;
   4.482  	 }
   4.483  
   4.484 -      inline double * cross(Vector3d v1, Vector3d v2, Vector3d vres)
   4.485 +      inline T dot(const Vector3<T>& v2) const
   4.486 +	 { return x*v2.x + y*v2.y + z*v2.z; }
   4.487 +
   4.488 +      inline double get_angle(Vector3<T>& v2)
   4.489  	 { 
   4.490 -	 vres[0] =  v1[1]*v2[2] - v2[1]*v1[2];
   4.491 -	 vres[1] = -v1[0]*v2[2] + v2[0]*v1[2];
   4.492 -	 vres[2] =  v1[0]*v2[1] - v2[0]*v1[1];
   4.493 -	 return vres;
   4.494 -	 }
   4.495 -   
   4.496 -      //////////////////////////////////////////////////////////////////////////
   4.497 -      // get_angle*(Vector3 v1, Vector3 v2)
   4.498 -      //	Returns the angle in radians between the two vectors.
   4.499 -      //
   4.500 -      // get_angle[234]n() take pre-normalized vectors as arguments and will
   4.501 -      //	fail otherwise.  This version is not defined for interger
   4.502 -      //	vectors since you can't normalize an integer vector.
   4.503 -      // get_angle[234]() take arbitrary vectors as arguments.
   4.504 -      //
   4.505 -      // I started out with two version of get_angle3:
   4.506 -      // get_angle3_1 implemented as
   4.507 -      //  return acos(dot3v(v1, v2)/(length3v(v1)*length3v(v2)));
   4.508 -      // get_angle3_2 implemented as
   4.509 -      //  double tmp = dot3v(v1, v2); 
   4.510 -      //  return acos(sqrtf(tmp*tmp/(dot3v(v1,v1)*dot3v(v2,v2))));
   4.511 -      // 
   4.512 -      // I ran timing tests, since I expected the second one - the one I chose to 
   4.513 -      // use, in the end - to be faster since it only resulted in one sqrt call
   4.514 -      // instead of two.  Here are the results
   4.515 -      //
   4.516 -      // get_angle3_1 44.753006890 seconds for 500,000,000 iterations.
   4.517 -      // get_angle3_2 36.940170102 seconds for 500,000,000 iterations.
   4.518 -      //
   4.519 -      // Faster?  Yes. About 7 nanoseconds vs 9.  A ridiculous optimization
   4.520 -      // to worry about?  Eh.  I might as well use it.
   4.521 -
   4.522 -      inline double get_angle2n(Vector2f v1, Vector2f v2)
   4.523 -	 { return acos(dot2v(v1, v2)); }
   4.524 -      inline double get_angle2n(Vector2d v1, Vector2d v2)
   4.525 -	 { return acos(dot2v(v1, v2)); }
   4.526 -      inline double get_angle2v(Vector2i v1, Vector2i v2)
   4.527 -	 { 
   4.528 -	 double tmp = dot2v(v1, v2); 
   4.529 -	 return acos(sqrtf(tmp*tmp/(dot2v(v1,v1)*dot2v(v2,v2)))); 
   4.530 -	 }
   4.531 -      inline double get_angle2v(Vector2f v1, Vector2f v2)
   4.532 -	 { 
   4.533 -	 double tmp = dot2v(v1, v2); 
   4.534 -	 return acos(sqrtf(tmp*tmp/(dot2v(v1,v1)*dot2v(v2,v2)))); 
   4.535 -	 }
   4.536 -      inline double get_angle2v(Vector2d v1, Vector2d v2)
   4.537 -	 { 
   4.538 -	 double tmp = dot2v(v1, v2); 
   4.539 -	 return acos(sqrtf(tmp*tmp/(dot2v(v1,v1)*dot2v(v2,v2)))); 
   4.540 +	 double tmp = dot(v2); 
   4.541 +	 return acos(sqrt(tmp*tmp/(dot(*this)*v2.dot(v2))));
   4.542  	 }
   4.543  
   4.544 -      inline double get_angle3n(Vector3f v1, Vector3f v2)
   4.545 -	 { return acos(dot3v(v1, v2)); }
   4.546 -      inline double get_angle3n(Vector3d v1, Vector3d v2)
   4.547 -	 { return acos(dot3v(v1, v2)); }
   4.548 -      inline double get_angle3v(Vector3i v1, Vector3i v2)
   4.549 +      inline double get_anglen(Vector3<T>& v2)
   4.550 +	 { return acos((double) dot(v2)); }
   4.551 +
   4.552 +      std::string & getstring(std::string & s) const;
   4.553 +
   4.554 +      inline double length(void) const
   4.555 +	 { return sqrt((dot(*this))); }
   4.556 +
   4.557 +      inline Vector3<T>& normalize()
   4.558 +	 { double l = length(); if (l == 0.0) return *this; x /= l; y /= l; z /= l; return *this; }
   4.559 +
   4.560 +      inline Vector3<T> proj(Vector3<T>& v2)
   4.561 +	 { Vector3<T> vres; vres = v2 * dot(v2)/v2.dot(v2); return vres; }
   4.562 +      inline Vector3<T>& proj(Vector3<T>& v2, Vector3<T>& vres)
   4.563 +	 { vres = v2 * dot(v2)/v2.dot(v2); return vres; }
   4.564 +      };
   4.565 +
   4.566 +   // Scalar multiplication, continued
   4.567 +   template <class T> inline Vector3<T> operator*(const Vector3<T>& v, const int a)
   4.568 +         { return Vector3<T>(v) *= a;}
   4.569 +   template <class T> inline Vector3<T> operator*(const int a, const Vector3<T>& v)
   4.570 +         { return Vector3<T>(v) *= a;}
   4.571 +   template <class T> inline Vector3<T> operator*(const Vector3<T> v, const float a)
   4.572 +      { return Vector3<T>(v) *= a;}
   4.573 +   template <class T> inline Vector3<T> operator*(const float a, const Vector3<T> v)
   4.574 +      { return Vector3<T>(v) *= a;}
   4.575 +   template <class T> inline Vector3<T> operator*(const Vector3<T>& v, const double a)
   4.576 +      { return Vector3<T>(v) *= a;}
   4.577 +   template <class T> inline Vector3<T> operator*(const double a, const Vector3<T>& v)
   4.578 +      { return Vector3<T>(v) *= a;}
   4.579 +
   4.580 +   // Scalar division, continued
   4.581 +   template <class T> inline Vector3<T> operator/(const Vector3<T>& v, const int a)
   4.582 +      { return Vector3<T>(v) /= a;}
   4.583 +   template <class T> inline Vector3<T> operator/(const int a, const Vector3<T>& v)
   4.584 +      { return Vector3<T>(v) /= a;}
   4.585 +   template <class T> inline Vector3<T> operator/(const Vector3<T>& v, const float a)
   4.586 +      { return Vector3<T>(v) /= a;}
   4.587 +   template <class T> inline Vector3<T> operator/(const float a, const Vector3<T>& v)
   4.588 +      { return Vector3<T>(v) /= a;}
   4.589 +   template <class T> inline Vector3<T> operator/(const Vector3<T>& v, const double a)
   4.590 +      { return Vector3<T>(v) /= a;}
   4.591 +   template <class T> inline Vector3<T> operator/(const double a, const Vector3<T>& v)
   4.592 +      { return Vector3<T>(v) /= a;}
   4.593 +
   4.594 +   /////////////////////////////////////////////////////////////////////////////
   4.595 +   template <class T> class Vector4
   4.596 +      {
   4.597 +      public:
   4.598 +      T x, y, z, w;
   4.599 +
   4.600 +      // Constructors
   4.601 +      Vector4() : x (0), y(0), z(0), w(0) {}
   4.602 +      Vector4(T a) : x (a), y(a), z(a), w(a) {}
   4.603 +      Vector4(T a, T b, T c, T d) : x (a), y(b), z(c), w(d) {}
   4.604 +
   4.605 +      // Array indexing
   4.606 +      inline T& operator[](unsigned int i)
   4.607 +	 { assert (i<4); if (i==0) return x; if (i==1) return y; if (i==2) return z; return w; }
   4.608 +      inline const T& operator[](unsigned int i) const
   4.609 +	 { assert (i<4); if (i==0) return x; if (i==1) return y; if (i==2) return z; return w; }
   4.610 +
   4.611 +      // Assignment
   4.612 +      inline Vector4<T>& operator=(const Vector4<T>& v2)
   4.613 +	 { x = v2.x; y = v2.y; z = v2.z; w = v2.w; return *this; }
   4.614 +      inline Vector4<T>& assign(const T a, const T b, const T c, const T d)
   4.615 +	 { x = a; y = b; z = c; w = d; return *this; }
   4.616 +
   4.617 +      // Comparison
   4.618 +      inline bool operator==(Vector4<T>& v2) const
   4.619 +	 { return ((x == v2.x) && (y == v2.y) && (z == v2.z) && (w == v2.w)); }
   4.620 +      inline bool operator!=(Vector4<T>& v2) const
   4.621 +	 { return ! ((x == v2.x) && (y == v2.y) && (z == v2.z) && (w == v2.w)); }
   4.622 +
   4.623 +      // Vector addition
   4.624 +      inline Vector4<T> operator+(const Vector4<T>& v2) const
   4.625 +	 { Vector4<T> vres; vres.x = x + v2.x; vres.y = y + v2.y; vres.z = z + v2.z; vres.w = w + v2.w; return vres; }
   4.626 +      inline Vector4<T>& operator+=(const Vector4<T>& v2)
   4.627 +	 { x += v2.x; y += v2.y; z += v2.z; w += v2.w; return *this; }
   4.628 +
   4.629 +      // Vector subtraction
   4.630 +      inline Vector4<T> operator-(const Vector4<T>& v2) const
   4.631 +	 { Vector4<T> vres; vres.x = x - v2.x; vres.y = y - v2.y; vres.z = z - v2.z; vres.w = w - v2.w; return vres; }
   4.632 +      inline Vector4<T>& operator-=(const Vector4<T>& v2)
   4.633 +	 { x -= v2.x; y -= v2.y; z -= v2.z; w -= v2.w; return *this; }
   4.634 +
   4.635 +      // Scalar multiplication
   4.636 +      inline Vector4<T>& operator*=(const int a)
   4.637 +	 { x *= a; y *= a; z *= a; w *= a; return *this; }
   4.638 +      inline Vector4<T>& operator*=(const float a)
   4.639 +	 { x *= a; y *= a; z *= a; w *= a; return *this; }
   4.640 +      inline Vector4<T>& operator*=(const double a)
   4.641 +	 { x *= a; y *= a; z *= a; w *= a; return *this; }
   4.642 +
   4.643 +      // Scalar division
   4.644 +      inline Vector4<T>& operator/=(const int a)
   4.645 +	 { assert(a!=0); x /= a; y /= a; z /= a; w /= a; return *this; }
   4.646 +      inline Vector4<T>& operator/=(const float a)
   4.647 +	 { assert(a!=0); x /= a; y /= a; z /= a; w /= a; return *this; }
   4.648 +      inline Vector4<T>& operator/=(const double a)
   4.649 +	 { assert(a!=0); x /= a; y /= a; z /= a; w /= a; return *this; }
   4.650 +
   4.651 +
   4.652 +      // methods
   4.653 +
   4.654 +      inline T dot(const Vector4<T>& v2) const
   4.655 +	 { return x*v2.x + y*v2.y + z*v2.z + w*v2.w; }
   4.656 +
   4.657 +      inline double get_angle(Vector4<T>& v2)
   4.658  	 { 
   4.659 -	 double tmp = dot3v(v1, v2); 
   4.660 -	 return acos(sqrtf(tmp*tmp/(dot3v(v1,v1)*dot3v(v2,v2)))); 
   4.661 -	 }
   4.662 -      inline double get_angle3v(Vector3f v1, Vector3f v2)
   4.663 -	 { 
   4.664 -	 double tmp = dot3v(v1, v2); 
   4.665 -	 return acos(sqrtf(tmp*tmp/(dot3v(v1,v1)*dot3v(v2,v2)))); 
   4.666 -	 }
   4.667 -      inline double get_angle3v(Vector3d v1, Vector3d v2)
   4.668 -	 { 
   4.669 -	 double tmp = dot3v(v1, v2); 
   4.670 -	 return acos(sqrtf(tmp*tmp/(dot3v(v1,v1)*dot3v(v2,v2)))); 
   4.671 +	 double tmp = dot(v2); 
   4.672 +	 return acos(sqrt(tmp*tmp/(dot(*this)*v2.dot(v2))));
   4.673  	 }
   4.674  
   4.675 -      inline double get_angle4n(Vector4f v1, Vector4f v2)
   4.676 -	 { return acos(dot4v(v1, v2)); }
   4.677 -      inline double get_angle4n(Vector4d v1, Vector4d v2)
   4.678 -	 { return acos(dot4v(v1, v2)); }
   4.679 -      inline double get_angle4v(Vector4i v1, Vector4i v2)
   4.680 -	 { 
   4.681 -	 double tmp = dot4v(v1, v2); 
   4.682 -	 return acos(sqrtf(tmp*tmp/(dot4v(v1,v1)*dot4v(v2,v2)))); 
   4.683 -	 }
   4.684 -      inline double get_angle4v(Vector4f v1, Vector4f v2)
   4.685 -	 { 
   4.686 -	 double tmp = dot4v(v1, v2); 
   4.687 -	 return acos(sqrtf(tmp*tmp/(dot4v(v1,v1)*dot4v(v2,v2)))); 
   4.688 -	 }
   4.689 -      inline double get_angle4v(Vector4d v1, Vector4d v2)
   4.690 -	 { 
   4.691 -	 double tmp = dot4v(v1, v2); 
   4.692 -	 return acos(sqrtf(tmp*tmp/(dot4v(v1,v1)*dot4v(v2,v2)))); 
   4.693 -	 }
   4.694 +      inline double get_anglen(Vector4<T>& v2)
   4.695 +	 { return acos((double) dot(v2)); }
   4.696  
   4.697 -      //////////////////////////////////////////////////////////////////////////
   4.698 -      // subtract*(Vector v1, Vector v2)
   4.699 -      //	Subtract v2 from v1,
   4.700 -      //	Equivalent to add(v1, scale(v2, -1)).
   4.701 -      //        Returns v1 so that the result may be used in further 
   4.702 -      //	calculations.
   4.703 +      std::string & getstring(std::string & s) const;
   4.704  
   4.705 -      inline int * subtract2v(Vector2i v1, Vector2i v2)
   4.706 -	 { v1[0] -= v2[0]; v1[1] -= v2[1]; return v1; }
   4.707 -      inline float * subtract2v(Vector2f v1, Vector2f v2)
   4.708 -	 { v1[0] -= v2[0]; v1[1] -= v2[1]; return v1; }
   4.709 -      inline double * subtract2v(Vector2d v1, Vector2d v2)
   4.710 -	 { v1[0] -= v2[0]; v1[1] -= v2[1]; return v1; }
   4.711 +      inline double length(void) const
   4.712 +	 { return sqrt((dot(*this))); }
   4.713  
   4.714 -      inline int * subtract3v(Vector3i v1, Vector3i v2)
   4.715 -	 { v1[0] -= v2[0]; v1[1] -= v2[1]; v1[2] -= v2[2]; return v1; }
   4.716 -      inline float * subtract3v(Vector3f v1, Vector3f v2)
   4.717 -	 { v1[0] -= v2[0]; v1[1] -= v2[1]; v1[2] -= v2[2];  return v1; }
   4.718 -      inline double * subtract3v(Vector3d v1, Vector3d v2)
   4.719 -	 { v1[0] -= v2[0]; v1[1] -= v2[1]; v1[2] -= v2[2];  return v1; }
   4.720 +      inline Vector4<T>& normalize()
   4.721 +	 { double l = length(); if (l == 0.0) return *this; x /= l; y /= l; z /= l; w /= l; return *this; }
   4.722  
   4.723 -      inline int * subtract4v(Vector4i v1, Vector4i v2)
   4.724 -	 { v1[0] -= v2[0]; v1[1] -= v2[1]; v1[2] -= v2[2]; v1[3] -= v2[3]; return v1;}
   4.725 -      inline float * subtract4v(Vector4f v1, Vector4f v2)
   4.726 -	 { v1[0] -= v2[0]; v1[1] -= v2[1]; v1[2] -= v2[2]; v1[3] -= v2[3]; return v1; }
   4.727 -      inline double * subtract4v(Vector4d v1, Vector4d v2)
   4.728 -	 { v1[0] -= v2[0]; v1[1] -= v2[1]; v1[2] -= v2[2]; v1[3] -= v2[3]; return v1; }
   4.729 +      inline Vector4<T> proj(Vector4<T>& v2)
   4.730 +	 { Vector4<T> vres; vres = v2 * dot(v2)/v2.dot(v2); return vres; }
   4.731 +      inline Vector4<T>& proj(Vector4<T>& v2, Vector4<T>& vres)
   4.732 +	 { vres = v2 * dot(v2)/v2.dot(v2); return vres; }
   4.733 +      };
   4.734  
   4.735 +   // Scalar multiplication, continued
   4.736 +   template <class T> inline Vector4<T> operator*(const Vector4<T>& v, const int a)
   4.737 +         { return Vector4<T>(v) *= a;}
   4.738 +   template <class T> inline Vector4<T> operator*(const int a, const Vector4<T>& v)
   4.739 +         { return Vector4<T>(v) *= a;}
   4.740 +   template <class T> inline Vector4<T> operator*(const Vector4<T> v, const float a)
   4.741 +      { return Vector4<T>(v) *= a;}
   4.742 +   template <class T> inline Vector4<T> operator*(const float a, const Vector4<T> v)
   4.743 +      { return Vector4<T>(v) *= a;}
   4.744 +   template <class T> inline Vector4<T> operator*(const Vector4<T>& v, const double a)
   4.745 +      { return Vector4<T>(v) *= a;}
   4.746 +   template <class T> inline Vector4<T> operator*(const double a, const Vector4<T>& v)
   4.747 +      { return Vector4<T>(v) *= a;}
   4.748  
   4.749 -      //////////////////////////////////////////////////////////////////////////
   4.750 -      // assign*(Vector v1, Vector v2)
   4.751 -      //	Copies the value of v2 into v1.
   4.752 -      //	Returns v1.
   4.753 +   // Scalar division, continued
   4.754 +   template <class T> inline Vector4<T> operator/(const Vector4<T>& v, const int a)
   4.755 +      { return Vector4<T>(v) /= a;}
   4.756 +   template <class T> inline Vector4<T> operator/(const int a, const Vector4<T>& v)
   4.757 +      { return Vector4<T>(v) /= a;}
   4.758 +   template <class T> inline Vector4<T> operator/(const Vector4<T>& v, const float a)
   4.759 +      { return Vector4<T>(v) /= a;}
   4.760 +   template <class T> inline Vector4<T> operator/(const float a, const Vector4<T>& v)
   4.761 +      { return Vector4<T>(v) /= a;}
   4.762 +   template <class T> inline Vector4<T> operator/(const Vector4<T>& v, const double a)
   4.763 +      { return Vector4<T>(v) /= a;}
   4.764 +   template <class T> inline Vector4<T> operator/(const double a, const Vector4<T>& v)
   4.765 +      { return Vector4<T>(v) /= a;}
   4.766  
   4.767 -      inline int * assign2v(Vector2i v1, Vector2i v2)
   4.768 -	 { v1[0] = v2[0]; v1[1] = v2[1]; return v1; }
   4.769 -      inline float * assign2v(Vector2f v1, Vector2f v2)
   4.770 -	 { v1[0] = v2[0]; v1[1] = v2[1]; return v1; }
   4.771 -      inline double * assign2v(Vector2d v1, Vector2d v2)
   4.772 -	 { v1[0] = v2[0]; v1[1] = v2[1]; return v1; }
   4.773 +   /////////////////////////////////////////////////////////////////////////////
   4.774  
   4.775 -      inline int * assign3v(Vector3i v1, Vector3i v2)
   4.776 -	 { v1[0] = v2[0]; v1[1] = v2[1]; v1[2] = v2[2]; return v1; }
   4.777 -      inline float * assign3v(Vector3f v1, Vector3f v2)
   4.778 -	 { v1[0] = v2[0]; v1[1] = v2[1]; v1[2] = v2[2]; return v1; }
   4.779 -      inline double * assign3v(Vector3d v1, Vector3d v2)
   4.780 -	 { v1[0] = v2[0]; v1[1] = v2[1]; v1[2] = v2[2]; return v1; }
   4.781 +   typedef Vector2<int> Vector2i;
   4.782 +   typedef Vector2<float> Vector2f;
   4.783 +   typedef Vector2<double> Vector2d;
   4.784  
   4.785 -      inline int * assign4v(Vector4i v1, Vector4i v2)
   4.786 -	 { v1[0] = v2[0]; v1[1] = v2[1]; v1[2] = v2[2]; v1[3] = v2[3]; return v1; }
   4.787 -      inline float * assign4v(Vector4f v1, Vector4f v2)
   4.788 -	 { v1[0] = v2[0]; v1[1] = v2[1]; v1[2] = v2[2]; v1[3] = v2[3]; return v1; }
   4.789 -      inline double * assign4v(Vector4d v1, Vector4d v2)
   4.790 -	 { v1[0] = v2[0]; v1[1] = v2[1]; v1[2] = v2[2]; v1[3] = v2[3]; return v1; }
   4.791 +   typedef Vector3<int> Vector3i;
   4.792 +   typedef Vector3<float> Vector3f;
   4.793 +   typedef Vector3<double> Vector3d;
   4.794  
   4.795 -
   4.796 -      //////////////////////////////////////////////////////////////////////////
   4.797 -      // proj*(Vector v1, Vector v2, Vector vres)
   4.798 -      //	Calculates the projection of v1 onto v2 and returns the result 
   4.799 -      //	in vres.
   4.800 -      //	Only defined for floating point vectors.
   4.801 -      //	Returns vres.
   4.802 -
   4.803 -      inline float * proj2v(Vector2f v1, Vector2f v2, Vector2f vres)
   4.804 -	 { assign2v(vres, v2); scale2v(vres, (dot2v(v1, vres)/dot2v(vres,vres))); return vres; }
   4.805 -      inline double * proj2v(Vector2d v1, Vector2d v2, Vector2d vres)
   4.806 -	 { assign2v(vres, v2); scale2v(vres, (dot2v(v1, vres)/dot2v(vres,vres))); return vres; }
   4.807 -
   4.808 -      inline float * proj3v(Vector3f v1, Vector3f v2, Vector3f vres)
   4.809 -	 { assign3v(vres, v2); scale3v(vres, (dot3v(v1, vres)/dot3v(vres,vres))); return vres; }
   4.810 -      inline double * proj3v(Vector3d v1, Vector3d v2, Vector3d vres)
   4.811 -	 { assign3v(vres, v2); scale3v(vres, (dot3v(v1, vres)/dot3v(vres,vres))); return vres; }
   4.812 -
   4.813 -      inline float * proj4v(Vector4f v1, Vector4f v2, Vector4f vres)
   4.814 -	 { assign4v(vres, v2); scale4v(vres, (dot4v(v1, vres)/dot4v(vres,vres))); return vres; }
   4.815 -      inline double * proj4v(Vector4d v1, Vector4d v2, Vector4d vres)
   4.816 -	 { assign4v(vres, v2); scale4v(vres, (dot4v(v1, vres)/dot4v(vres,vres))); return vres; }
   4.817 -
   4.818 -      } // Vector
   4.819 +   typedef Vector4<int> Vector4i;
   4.820 +   typedef Vector4<float> Vector4f;
   4.821 +   typedef Vector4<double> Vector4d;
   4.822  
   4.823     } // namespace arda
   4.824  
   4.825 +////////////////////////////////////////////////////////////////////////////////
   4.826 +template <class T> std::string & arda::Vector2<T>::getstring(std::string & s) const
   4.827 +   {
   4.828 +   s.clear();
   4.829 +   std::stringstream ss;
   4.830 +   ss << "[ " << x << ", " << y << " ]";
   4.831 +   s = ss.str();
   4.832 +   return s;   
   4.833 +   }
   4.834 +
   4.835 +////////////////////////////////////////////////////////////////////////////////
   4.836 +template <class T> std::string & arda::Vector3<T>::getstring(std::string & s) const
   4.837 +   {
   4.838 +   s.clear();
   4.839 +   std::stringstream ss;
   4.840 +   ss << "[ " << x << ", " << y << ", " << z << " ]";
   4.841 +   s = ss.str();
   4.842 +   return s;   
   4.843 +   }
   4.844 +
   4.845 +////////////////////////////////////////////////////////////////////////////////
   4.846 +template <class T> std::string & arda::Vector4<T>::getstring(std::string & s) const
   4.847 +   {
   4.848 +   s.clear();
   4.849 +   std::stringstream ss;
   4.850 +   ss << "[ " << x << ", " << y << ", " << z << ", " << w << " ]";
   4.851 +   s = ss.str();
   4.852 +   return s;   
   4.853 +   }
   4.854 +
   4.855 +
   4.856  #endif // VECTOR_H_
     5.1 --- a/src/Vector.cpp	Tue Sep 06 11:26:39 2011 -0500
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,95 +0,0 @@
     5.4 -#include "Vector.h"
     5.5 -
     5.6 -#include <iostream>
     5.7 -#include <string>
     5.8 -#include <sstream>
     5.9 -
    5.10 -////////////////////////////////////////////////////////////////////////////////
    5.11 -std::string & arda::Vector::getstring2v(Vector2i v, std::string & s)
    5.12 -   {
    5.13 -   s.clear();
    5.14 -   std::stringstream ss;
    5.15 -   ss << "[ " << v[0] << ", " << v[1] << " ]";
    5.16 -   s = ss.str();
    5.17 -   return s;   
    5.18 -   }
    5.19 -
    5.20 -////////////////////////////////////////////////////////////////////////////////
    5.21 -std::string & arda::Vector::getstring2v(Vector2f v, std::string & s)
    5.22 -   {
    5.23 -   s.clear();
    5.24 -   std::stringstream ss;
    5.25 -   ss << "[ " << v[0] << ", " << v[1] << " ]";
    5.26 -   s = ss.str();
    5.27 -   return s;   
    5.28 -   }
    5.29 -
    5.30 -////////////////////////////////////////////////////////////////////////////////
    5.31 -std::string & arda::Vector::getstring2v(Vector2d v, std::string & s)
    5.32 -   {
    5.33 -   s.clear();
    5.34 -   std::stringstream ss;
    5.35 -   ss << "[ " << v[0] << ", " << v[1] << " ]";
    5.36 -   s = ss.str();
    5.37 -   return s;   
    5.38 -   }
    5.39 -
    5.40 -////////////////////////////////////////////////////////////////////////////////
    5.41 -std::string & arda::Vector::getstring3v(Vector3i v, std::string & s)
    5.42 -   {
    5.43 -   s.clear();
    5.44 -   std::stringstream ss;
    5.45 -   ss << "[ " << v[0] << ", " << v[1] << ", " << v[2] << " ]";
    5.46 -   s = ss.str();
    5.47 -   return s;   
    5.48 -   }
    5.49 -
    5.50 -////////////////////////////////////////////////////////////////////////////////
    5.51 -std::string & arda::Vector::getstring3v(Vector3f v, std::string & s)
    5.52 -   {
    5.53 -   s.clear();
    5.54 -   std::stringstream ss;
    5.55 -   ss << "[ " << v[0] << ", " << v[1] << ", " << v[2] << " ]";
    5.56 -   s = ss.str();
    5.57 -   return s;   
    5.58 -   }
    5.59 -
    5.60 -////////////////////////////////////////////////////////////////////////////////
    5.61 -std::string & arda::Vector::getstring3v(Vector3d v, std::string & s)
    5.62 -   {
    5.63 -   s.clear();
    5.64 -   std::stringstream ss;
    5.65 -   ss << "[ " << v[0] << ", " << v[1] << ", " << v[2] << " ]";
    5.66 -   s = ss.str();
    5.67 -   return s;   
    5.68 -   }
    5.69 -
    5.70 -////////////////////////////////////////////////////////////////////////////////
    5.71 -std::string & arda::Vector::getstring4v(Vector4i v, std::string & s)
    5.72 -   {
    5.73 -   s.clear();
    5.74 -   std::stringstream ss;
    5.75 -   ss << "[ " << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << " ]";
    5.76 -   s = ss.str();
    5.77 -   return s;   
    5.78 -   }
    5.79 -
    5.80 -////////////////////////////////////////////////////////////////////////////////
    5.81 -std::string & arda::Vector::getstring4v(Vector4f v, std::string & s)
    5.82 -   {
    5.83 -   s.clear();
    5.84 -   std::stringstream ss;
    5.85 -   ss << "[ " << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << " ]";
    5.86 -   s = ss.str();
    5.87 -   return s;   
    5.88 -   }
    5.89 -
    5.90 -////////////////////////////////////////////////////////////////////////////////
    5.91 -std::string & arda::Vector::getstring4v(Vector4d v, std::string & s)
    5.92 -   {
    5.93 -   s.clear();
    5.94 -   std::stringstream ss;
    5.95 -   ss << "[ " << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << " ]";
    5.96 -   s = ss.str();
    5.97 -   return s;   
    5.98 -   }
     6.1 --- a/src/main.cpp	Tue Sep 06 11:26:39 2011 -0500
     6.2 +++ b/src/main.cpp	Wed Sep 28 12:48:42 2011 -0500
     6.3 @@ -5,272 +5,417 @@
     6.4  using namespace std;
     6.5  
     6.6  #include "Math.h"
     6.7 -using namespace arda::Vector;
     6.8 -using namespace arda::Matrix;
     6.9 +using namespace arda;
    6.10  
    6.11  ////////////////////////////////////////////////////////////////////////////////
    6.12  void test_vector(void)
    6.13     {
    6.14     string s1, s2;
    6.15  
    6.16 -   // Vector::scale*()
    6.17     {
    6.18     cout << "===============================================================" << endl <<
    6.19 -	 "Testing Vector::scale*()" << endl;
    6.20 +	 "Testing Vector constructors" << endl;
    6.21 +   Vector2i v2i_1;
    6.22 +   Vector2i v2i_2(1);
    6.23 +   Vector2i v2i_3(1, 2);
    6.24 +   Vector2i v2i_4(v2i_3);
    6.25  
    6.26 -   Vector2i v2i = { 1, 2 };
    6.27 -   cout << setw(40) << "v2i: " << getstring2v(v2i, s1) << endl;
    6.28 -   scale2v(v2i, 2);
    6.29 -   cout << setw(40) << "scale2v(v2i, 2): " << getstring2v(v2i, s1) << endl;
    6.30 -   scale2v(v2i, 2.4);
    6.31 -   cout << setw(40) << "scale2v(v2i, 2.4): " << getstring2v(v2i, s1) << endl;
    6.32 -   scale2v(scale2v(v2i, 2), 3);
    6.33 -   cout << setw(40) << "scale2v(scale2v(v2i, 2), 3): " << getstring2v(v2i, s1) << endl;
    6.34 +   cout << setw(40) << "v2i_1: " << v2i_1.getstring(s1) << endl;
    6.35 +   cout << setw(40) << "v2i_2: " << v2i_2.getstring(s1) << endl;
    6.36 +   cout << setw(40) << "v2i_3: " << v2i_3.getstring(s1) << endl;
    6.37 +   cout << setw(40) << "v2i_4: " << v2i_4.getstring(s1) << endl;
    6.38  
    6.39 +   Vector3f v3f_1;
    6.40 +   Vector3f v3f_2(1);
    6.41 +   Vector3f v3f_3(1, 2, 3);
    6.42 +   Vector3f v3f_4(v3f_3);
    6.43  
    6.44 -   Vector3f v3f = { 3.0, 4.1, 5.2 };
    6.45 -   cout << setw(40) << "v3f: " << getstring3v(v3f, s1) << endl;
    6.46 -   scale3v(v3f, 2.2f);
    6.47 -   cout << setw(40) << "scale3v(v3f,  2.2f): " << getstring3v(v3f, s1) << endl;
    6.48 -   scale3v(v3f, 2);
    6.49 -   cout << setw(40) << "scale3v(v2f, 2): " << getstring3v(v3f, s1) << endl;
    6.50 +   cout << setw(40) << "v3f_1: " << v3f_1.getstring(s1) << endl;
    6.51 +   cout << setw(40) << "v3f_2: " << v3f_2.getstring(s1) << endl;
    6.52 +   cout << setw(40) << "v3f_3: " << v3f_3.getstring(s1) << endl;
    6.53 +   cout << setw(40) << "v3f_4: " << v3f_4.getstring(s1) << endl;
    6.54  
    6.55 -   Vector4d v4d = { 6.0L, 7.1L, 8.2L, 9.3L };
    6.56 -   cout << setw(40) << "vd4: " << getstring4v(v4d, s1) << endl;
    6.57 -   scale4v(v4d, 2.0);
    6.58 -   cout << setw(40) << "scale4v(v4d, 2.0): " << getstring4v(v4d, s1) << endl;
    6.59 -   scale4v(v4d, 2);
    6.60 -   cout << setw(40) << "scale4v(v4d, 2): " << getstring4v(v4d, s1) << endl;
    6.61 +   Vector4d v4d_1;
    6.62 +   Vector4d v4d_2(1);
    6.63 +   Vector4d v4d_3(1, 2, 3, 4);
    6.64 +   Vector4d v4d_4(v4d_3);
    6.65 +
    6.66 +   cout << setw(40) << "v4d_1: " << v4d_1.getstring(s1) << endl;
    6.67 +   cout << setw(40) << "v4d_2: " << v4d_2.getstring(s1) << endl;
    6.68 +   cout << setw(40) << "v4d_3: " << v4d_3.getstring(s1) << endl;
    6.69 +   cout << setw(40) << "v4d_4: " << v4d_4.getstring(s1) << endl;
    6.70     }
    6.71  
    6.72 -
    6.73 -   // Vector::dot*()
    6.74     {
    6.75     cout << "===============================================================" << endl <<
    6.76 -	 "Testing Vector::dot*()" << endl;
    6.77 +	 "Testing Vector array indexing" << endl;
    6.78 +   Vector2i v2i(1,2);
    6.79 +   Vector3f v3f(1.1f, 2.2f, 3.3f);
    6.80 +   Vector4d v4d(1.1, 2.2, 3.3, 4.4);
    6.81  
    6.82 -   Vector2i v2i[2] = { { 1, 2 }, { 3, 4 } };
    6.83 -   cout << setw(40) << "v2i[0]: " << getstring2v(v2i[0], s1) << endl;
    6.84 -   cout << setw(40) << "v2i[1]: " << getstring2v(v2i[1], s1) << endl;
    6.85 -   cout << setw(40) << "dot2v(v2i[0], v2i[1]): " << dot2v(v2i[0], v2i[1]) << endl;
    6.86 -   
    6.87 -   Vector3f v3f[3] = { { 1.1f, 2.2f, 3.3f }, { 4.4f, 5.5f, 6.6f } };
    6.88 -   cout << setw(40) << "v3f[0]: " << getstring3v(v3f[0], s1) << endl;
    6.89 -   cout << setw(40) << "v3f[1]: " << getstring3v(v3f[1], s1) << endl;
    6.90 -   cout << setw(40) << "dot3v(v3f[0], v3f[1]): " << dot3v(v3f[0], v3f[1]) << endl;
    6.91 -   
    6.92 -   Vector4d v4d[3] = { { 1.1, 2.2, 3.3, 4.4 }, { 5.5, 6.6, 7.7, 8.8 } };
    6.93 -   cout << setw(40) << "v4d[0]: " << getstring4v(v4d[0], s1) << endl;
    6.94 -   cout << setw(40) << "v4d[1]: " << getstring4v(v4d[1], s1) <<  endl;
    6.95 -   cout << setw(40) << "dot4v(v4d[0], v4d[1]): " << dot4v(v4d[0], v4d[1]) << endl;
    6.96 -   
    6.97 +   cout << setw(40) << "v2i: " << v2i[0] << ", " << v2i[1] << endl;
    6.98 +   cout << setw(40) << "v3f: " << v3f[0] << ", " << v3f[1] << ", " << v3f[2] << endl;
    6.99 +   cout << setw(40) << "v4d: " << v4d[0] << ", " << v4d[1] << ", " << v4d[2] << ", " << v4d[3] << endl;
   6.100     }
   6.101  
   6.102 -   // Vector::length*()
   6.103     {
   6.104     cout << "===============================================================" << endl <<
   6.105 -	 "Testing Vector::length*()" << endl;
   6.106 +	 "Testing Vector assignment" << endl;
   6.107 +   Vector2i v2i(1,2);
   6.108 +   Vector3f v3f(1.1f, 2.2f, 3.3f);
   6.109 +   Vector4d v4d(1.1, 2.2, 3.3, 4.4);
   6.110 +   Vector2i v2i_2;
   6.111 +   Vector3f v3f_2;
   6.112 +   Vector4d v4d_2;
   6.113  
   6.114 -   Vector2i v2i = { 1, 2 };
   6.115 -   cout << setw(40) << "v2i: " << getstring2v(v2i, s1) << endl;
   6.116 -   cout << setw(40) << "length2v(v2i): " << length2v(v2i) << endl;
   6.117 -   
   6.118 -   Vector3f v3f = { 1.1f, 2.2f, 3.3f };
   6.119 -   cout << setw(40) << "v3f: " << getstring3v(v3f, s1) << endl;
   6.120 -   cout << setw(40) << "length3v(v3f): " << length3v(v3f) << endl;
   6.121 -   
   6.122 -   Vector4d v4d = { 1.1, 2.2, 3.3, 4.4 };
   6.123 -   cout << setw(40) << "v4d: " << getstring4v(v4d, s1) << endl;
   6.124 -   cout << setw(40) << "length4v(v4d): " << length4v(v4d) << endl;
   6.125 -   
   6.126 +   cout << "Before assignment" << endl;
   6.127 +   cout << setw(40) << "v2i: " << v2i.getstring(s1) << endl;
   6.128 +   cout << setw(40) << "v3f: " << v3f.getstring(s1) << endl;
   6.129 +   cout << setw(40) << "v4d: " << v4d.getstring(s1) << endl;
   6.130 +   cout << setw(40) << "v2i_2: " << v2i_2.getstring(s1) << endl;
   6.131 +   cout << setw(40) << "v3f_2: " << v3f_2.getstring(s1) << endl;
   6.132 +   cout << setw(40) << "v4d_2: " << v4d_2.getstring(s1) << endl;
   6.133 +
   6.134 +   v2i_2 = v2i;
   6.135 +   v3f_2 = v3f;
   6.136 +   v4d_2 = v4d;
   6.137 +   cout << "After assignment by =" << endl;
   6.138 +   cout << setw(40) << "v2i_2: " << v2i_2.getstring(s1) << endl;
   6.139 +   cout << setw(40) << "v3f_2: " << v3f_2.getstring(s1) << endl;
   6.140 +   cout << setw(40) << "v4d_2: " << v4d_2.getstring(s1) << endl;
   6.141 +
   6.142 +   v2i_2.assign(1, 1);
   6.143 +   v3f_2.assign(2.2, 2.2, 2.2);
   6.144 +   v4d_2.assign(3.3, 3.3, 3.3, 3.3);
   6.145 +   cout << "After assignment by assign()" << endl;
   6.146 +   cout << setw(40) << "v2i_2: " << v2i_2.getstring(s1) << endl;
   6.147 +   cout << setw(40) << "v3f_2: " << v3f_2.getstring(s1) << endl;
   6.148 +   cout << setw(40) << "v4d_2: " << v4d_2.getstring(s1) << endl;
   6.149     }
   6.150  
   6.151 -   // Vector::add*()
   6.152     {
   6.153     cout << "===============================================================" << endl <<
   6.154 -	 "Testing Vector::add*()" << endl;
   6.155 +	 "Testing Vector comparison" << endl;
   6.156 +   Vector2i v2i(1,2);
   6.157 +   Vector3f v3f(1.1f, 2.2f, 3.3f);
   6.158 +   Vector4d v4d(1.1, 2.2, 3.3, 4.4);
   6.159 +   Vector2i v2i_2;
   6.160 +   Vector3f v3f_2;
   6.161 +   Vector4d v4d_2;
   6.162  
   6.163 -   Vector2i v2i[3] = { { 1, 2 }, { 3, 4 } };
   6.164 -   cout << setw(40) << "v2i[0]: " << getstring2v(v2i[0], s1) << endl;
   6.165 -   cout << setw(40) << "v2i[1]: " << getstring2v(v2i[1], s1) << endl;
   6.166 -   add2v(v2i[0], v2i[1]);
   6.167 -   cout << setw(40) << "add2v(v2i[0], v2i[1]): " << getstring2v(v2i[0], s1) << endl;
   6.168 -   cout << setw(40) << "length2v(add2v(v2i[0], v2i[1])): " << length2v(add2v(v2i[0], v2i[1])) << endl;
   6.169 -
   6.170 -   Vector3f v3f[3] = { { 1.1f, 2.2f, 3.3f }, { 4.4f, 5.5f, 6.6f } };
   6.171 -   cout << setw(40) << "v3f[0]: " << getstring3v(v3f[0], s1) << endl;
   6.172 -   cout << setw(40) << "v3f[1]: " << getstring3v(v3f[1], s1) << endl;
   6.173 -   add3v(v3f[0], v3f[1]);
   6.174 -   cout << setw(40) << "add3v(v3f[0], v3f[1]): " << getstring3v(v3f[0], s1) << endl;
   6.175 -   cout << setw(40) << "length3v(add3v(v3f[0], v3f[1])): " << length3v(add3v(v3f[0], v3f[1])) << endl;
   6.176 -
   6.177 -   Vector4d v4d[3] = { { 1.1, 2.2, 3.3, 4.4 }, { 5.5, 6.6, 7.7, 8.8 } };
   6.178 -   cout << setw(40) << "v4d[0]: " << getstring4v(v4d[0], s1) << endl;
   6.179 -   cout << setw(40) << "v4d[1]: " << getstring4v(v4d[1], s1) << endl;
   6.180 -   add4v(v4d[0], v4d[1]);
   6.181 -   cout << setw(40) << "add4v(v4d[0], v4d[1]): " << getstring4v(v4d[0], s1) << endl;
   6.182 -   cout << setw(40) << "length4v(add4v(v4d[0], v4d[1])): " << length4v(add4v(v4d[0], v4d[1])) << endl;
   6.183 -
   6.184 +   cout << setw(40) << "v2i: " << v2i.getstring(s1) << endl;
   6.185 +   cout << setw(40) << "v3f: " << v3f.getstring(s1) << endl;
   6.186 +   cout << setw(40) << "v4d: " << v4d.getstring(s1) << endl;
   6.187 +   cout << setw(40) << "v2i_2: " << v2i_2.getstring(s1) << endl;
   6.188 +   cout << setw(40) << "v3f_2: " << v3f_2.getstring(s1) << endl;
   6.189 +   cout << setw(40) << "v4d_2: " << v4d_2.getstring(s1) << endl;
   6.190 +   cout << boolalpha;
   6.191 +   cout << setw(40) << "v2i == v2i_2: " << (v2i == v2i_2) << endl;
   6.192 +   cout << setw(40) << "v3f == v3f_2: " << (v3f == v3f_2) << endl;
   6.193 +   cout << setw(40) << "v4d == v4d_2: " << (v4d == v4d_2) << endl;
   6.194 +   cout << setw(40) << "v2i != v2i_2: " << (v2i != v2i_2) << endl;
   6.195 +   cout << setw(40) << "v3f != v3f_2: " << (v3f != v3f_2) << endl;
   6.196 +   cout << setw(40) << "v4d != v4d_2: " << (v4d != v4d_2) << endl;
   6.197     }
   6.198  
   6.199 -   // Vector::normalize*()
   6.200     {
   6.201     cout << "===============================================================" << endl <<
   6.202 -	 "Testing Vector::normalize*()" << endl;
   6.203 +	 "Testing Vector addition" << endl;
   6.204 +   Vector2i v2i(1,2);
   6.205 +   Vector3f v3f(1.1f, 2.2f, 3.3f);
   6.206 +   Vector4d v4d(1.1, 2.2, 3.3, 4.4);
   6.207 +   Vector2i v2i_2(3,4);
   6.208 +   Vector3f v3f_2(4.4, 5.5, 6.6);
   6.209 +   Vector4d v4d_2(5.5, 6.6, 7.7, 8.8);
   6.210 +   Vector2i v2i_3;
   6.211 +   Vector3f v3f_3 ;
   6.212 +   Vector4d v4d_3;
   6.213  
   6.214 -   Vector2f v2f = { 1.1, 2.2 };
   6.215 -   cout << setw(40) << "v2f: " << getstring2v(v2f, s1) << endl;
   6.216 -   normalize2v(v2f);
   6.217 -   cout << setw(40) << "normalize2v(v2f): " << getstring2v(v2f, s1) << endl;
   6.218 -   scale2v(normalize2v(v2f), 2.0);
   6.219 -   cout << setw(40) << "scale(normalize2v(v2f), 2.0): " << getstring2v(v2f, s1) << endl;
   6.220 -   
   6.221 -   Vector3f v3f = { 1.1f, 2.2f, 3.3f };
   6.222 -   cout << setw(40) << "v3f: " << getstring3v(v3f, s1) << endl;
   6.223 -   normalize3v(v3f);
   6.224 -   cout << setw(40) << "normalize3v(v3f): " << getstring3v(v3f, s1) << endl;
   6.225 -   scale3v(normalize3v(v3f), 2.0);
   6.226 -   cout << setw(40) << "scale(normalize3v(v3f), 2.0): " << getstring3v(v3f, s1) << endl;
   6.227 -   
   6.228 -   Vector4d v4d = { 1.1, 2.2, 3.3, 4.4 };
   6.229 -   cout << setw(40) << "v4d: " << getstring4v(v4d, s1) << endl;
   6.230 -   normalize4v(v4d);
   6.231 -   cout << setw(40) << "normalize4v(v4d): " << getstring4v(v4d, s1) << endl;
   6.232 -   scale4v(normalize4v(v4d), 2.0);
   6.233 -   cout << setw(40) << "scale4v(normalize4v(v4d), 2.0): " << getstring4v(v4d, s1) << endl;
   6.234 -   
   6.235 +   cout << setw(40) << "v2i: " << v2i.getstring(s1) << endl;
   6.236 +   cout << setw(40) << "v3f: " << v3f.getstring(s1) << endl;
   6.237 +   cout << setw(40) << "v4d: " << v4d.getstring(s1) << endl;
   6.238 +   cout << setw(40) << "v2i_2: " << v2i_2.getstring(s1) << endl;
   6.239 +   cout << setw(40) << "v3f_2: " << v3f_2.getstring(s1) << endl;
   6.240 +   cout << setw(40) << "v4d_2: " << v4d_2.getstring(s1) << endl;
   6.241 +   v2i_3 = v2i + v2i_2;
   6.242 +   v3f_3 = v3f + v3f_2;
   6.243 +   v4d_3 = v4d + v4d_2;
   6.244 +   cout << setw(40) << "v2i_3 = v2i + v2i_2: " << v2i_3.getstring(s1) << endl;
   6.245 +   cout << setw(40) << "v3f_3 = v3f + v3f_2: " << v3f_3.getstring(s1) << endl;
   6.246 +   cout << setw(40) << "v4d_3 = v4d + v4d_2: " << v4d_3.getstring(s1) << endl;
   6.247 +   v2i_3 += v2i_2;
   6.248 +   v3f_3 += v3f_2;
   6.249 +   v4d_3 += v4d_3;
   6.250 +   cout << setw(40) << "v2i_3 += v2i_2: " << v2i_3.getstring(s1) << endl;
   6.251 +   cout << setw(40) << "v3f_3 += v3f_2: " << v3f_3.getstring(s1) << endl;
   6.252 +   cout << setw(40) << "v4d_3 += v4d_3: " << v4d_3.getstring(s1) << endl;
   6.253     }
   6.254  
   6.255 -   // Vector::cross()
   6.256     {
   6.257     cout << "===============================================================" << endl <<
   6.258 -	 "Testing Vector::cross()" << endl;
   6.259 +	 "Testing Vector subtraction" << endl;
   6.260 +   Vector2i v2i(1,2);
   6.261 +   Vector3f v3f(1.1f, 2.2f, 3.3f);
   6.262 +   Vector4d v4d(1.1, 2.2, 3.3, 4.4);
   6.263 +   Vector2i v2i_2(3,4);
   6.264 +   Vector3f v3f_2(4.4, 5.5, 6.6);
   6.265 +   Vector4d v4d_2(5.5, 6.6, 7.7, 8.8);
   6.266 +   Vector2i v2i_3;
   6.267 +   Vector3f v3f_3;
   6.268 +   Vector4d v4d_3;
   6.269  
   6.270 -   Vector3f v3f[3] = { { 1.1f, 2.2f, 3.3f }, { 4.4f, 5.5f, 6.6f }, { 0.0f, 0.0f, 0.0f } };
   6.271 -   cout << setw(40) << "v3f[0]: " << getstring3v(v3f[0], s1) << endl;
   6.272 -   cout << setw(40) << "v3f[1]: " << getstring3v(v3f[1], s1) << endl;
   6.273 -   cross(v3f[0], v3f[1], v3f[2]);
   6.274 -   cout << setw(40) << "cross(v3f[0], v3f[1], v3f[2]): " << getstring3v(v3f[2], s1) << endl;
   6.275 -
   6.276 -   Vector3d v3d[3] = { { 1.1, 2.2, 3.3 }, { 4.4, 5.5, 6.6 }, { 0.0, 0.0, 0.0 } };
   6.277 -   cout << setw(40) << "v3d[0]: " << getstring3v(v3d[0], s1) << endl;
   6.278 -   cout << setw(40) << "v3d[1]: " << getstring3v(v3d[1], s1) << endl;
   6.279 -   cross(v3d[0], v3d[1], v3d[2]);
   6.280 -   cout << setw(40) << "cross(v3d[0], v3d[1], v3d[2]): " << getstring3v(v3d[2], s1) << endl;
   6.281 -
   6.282 +   cout << setw(40) << "v2i: " << v2i.getstring(s1) << endl;
   6.283 +   cout << setw(40) << "v3f: " << v3f.getstring(s1) << endl;
   6.284 +   cout << setw(40) << "v4d: " << v4d.getstring(s1) << endl;
   6.285 +   cout << setw(40) << "v2i_2: " << v2i_2.getstring(s1) << endl;
   6.286 +   cout << setw(40) << "v3f_2: " << v3f_2.getstring(s1) << endl;
   6.287 +   cout << setw(40) << "v4d_2: " << v4d_2.getstring(s1) << endl;
   6.288 +   v2i_3 = v2i - v2i_2;
   6.289 +   v3f_3 = v3f - v3f_2;
   6.290 +   v4d_3 = v4d - v4d_2;
   6.291 +   cout << setw(40) << "v2i_3 = v2i - v2i_2: " << v2i_3.getstring(s1) << endl;
   6.292 +   cout << setw(40) << "v3f_3 = v3f - v3f_2: " << v3f_3.getstring(s1) << endl;
   6.293 +   cout << setw(40) << "v4d_3 = v4d - v4d_2: " << v4d_3.getstring(s1) << endl;
   6.294 +   v2i_3 -= v2i_2;
   6.295 +   v3f_3 -= v3f_2;
   6.296 +   v4d_3 -= v4d_3;
   6.297 +   cout << setw(40) << "v2i_3 -= v2i_2: " << v2i_3.getstring(s1) << endl;
   6.298 +   cout << setw(40) << "v3f_3 -= v3f_2: " << v3f_3.getstring(s1) << endl;
   6.299 +   cout << setw(40) << "v4d_3 -= v4d_3: " << v4d_3.getstring(s1) << endl;
   6.300     }
   6.301  
   6.302 -
   6.303 -   // Vector::cross()
   6.304     {
   6.305     cout << "===============================================================" << endl <<
   6.306 -	 "Testing Vector::get_angle*()" << endl;
   6.307 +	 "Testing Vector scalar multiplication" << endl;
   6.308 +   Vector2i v2i(1,2);
   6.309 +   Vector3f v3f(1.1f, 2.2f, 3.3f);
   6.310 +   Vector4d v4d(1.1, 2.2, 3.3, 4.4);
   6.311 +   Vector2i v2i_2;
   6.312 +   Vector3f v3f_2;
   6.313 +   Vector4d v4d_2;
   6.314 +   int i = 2;
   6.315 +   float f = 2.f;
   6.316 +   double d = 2.0;
   6.317  
   6.318 -   Vector3i v3i[2] = { { 1, 2, 3 }, { 4, 5, 6 } };
   6.319 -   cout << setw(40) << "v3i[0]: " << getstring3v(v3i[0], s1) << endl;
   6.320 -   cout << setw(40) << "v3i[1]: " << getstring3v(v3i[1], s1) << endl;
   6.321 -   cout << setw(40) << "get_angle3v(v3i[0], v3i[1]): " << get_angle3v(v3i[0], v3i[1]) << endl;
   6.322 -
   6.323 -   Vector3f v3f[2] = { { 1.1f, 2.2f, 3.3f }, { 4.4f, 5.5f, 6.6f } };
   6.324 -   cout << setw(40) << "v3f[0]: " << getstring3v(v3f[0], s1) << endl;
   6.325 -   cout << setw(40) << "v3f[1]: " << getstring3v(v3f[1], s1) << endl;
   6.326 -   cout << setw(40) << "get_angle3v(v3f[0], v3f[1]): " << get_angle3v(v3f[0], v3f[1]) << endl;
   6.327 -   normalize3v(v3f[0]);
   6.328 -   normalize3v(v3f[1]);
   6.329 -   cout << setw(40) << "v3f[0]: " << getstring3v(v3f[0], s1) << endl;
   6.330 -   cout << setw(40) << "v3f[1]: " << getstring3v(v3f[1], s1) << endl;
   6.331 -   cout << setw(40) << "get_angle3n(v3f[0], v3f[1]): " << get_angle3n(v3f[0], v3f[1]) << endl;
   6.332 -
   6.333 -   Vector3d v3d[2] = { { 1.1, 2.2, 3.3 }, { 4.4, 5.5, 6.6 } };
   6.334 -   cout << setw(40) << "v3d[0]: " << getstring3v(v3d[0], s1) << endl;
   6.335 -   cout << setw(40) << "v3d[1]: " << getstring3v(v3d[1], s1) << endl;
   6.336 -   cout << setw(40) << "get_angle3v(v3d[0], v3d[1]): " << get_angle3v(v3d[0], v3d[1]) << endl;
   6.337 -   normalize3v(v3d[0]);
   6.338 -   normalize3v(v3d[1]);
   6.339 -   cout << setw(40) << "v3d[0]: " << getstring3v(v3d[0], s1) << endl;
   6.340 -   cout << setw(40) << "v3d[1]: " << getstring3v(v3d[1], s1) << endl;
   6.341 -   cout << setw(40) << "get_angle3n(v3d[0], v3d[1]): " << get_angle3n(v3d[0], v3d[1]) << endl;
   6.342 +   cout << setw(40) << "v2i: " << v2i.getstring(s1) << endl;
   6.343 +   cout << setw(40) << "v3f: " << v3f.getstring(s1) << endl;
   6.344 +   cout << setw(40) << "v4d: " << v4d.getstring(s1) << endl;
   6.345 +   cout << setw(40) << "v2i_2: " << v2i_2.getstring(s1) << endl;
   6.346 +   cout << setw(40) << "v3f_2: " << v3f_2.getstring(s1) << endl;
   6.347 +   cout << setw(40) << "v4d_2: " << v4d_2.getstring(s1) << endl;
   6.348 +   v2i_2 = v2i * i;
   6.349 +   v3f_2 = v3f * f;
   6.350 +   v4d_2 = v4d * d;
   6.351 +   cout << setw(40) << "v2i_2 = v2i * i: " << v2i_2.getstring(s1) << endl;
   6.352 +   cout << setw(40) << "v3f_2 = v3f * f: " << v3f_2.getstring(s1) << endl;
   6.353 +   cout << setw(40) << "v4d_2 = v4d * d: " << v4d_2.getstring(s1) << endl;
   6.354 +   v2i_2 *= i;
   6.355 +   v3f_2 *= f;
   6.356 +   v4d_2 *= d;
   6.357 +   cout << setw(40) << "v2i_2 *= i: " << v2i_2.getstring(s1) << endl;
   6.358 +   cout << setw(40) << "v3f_2 *= f: " << v3f_2.getstring(s1) << endl;
   6.359 +   cout << setw(40) << "v4d_2 *= d: " << v4d_2.getstring(s1) << endl;
   6.360     }
   6.361  
   6.362 -   // Vector::subtract*()
   6.363     {
   6.364     cout << "===============================================================" << endl <<
   6.365 -	 "Testing Vector::subtract*()" << endl;
   6.366 +	 "Testing Vector scalar division" << endl;
   6.367 +   Vector2i v2i(1,2);
   6.368 +   Vector3f v3f(1.1f, 2.2f, 3.3f);
   6.369 +   Vector4d v4d(1.1, 2.2, 3.3, 4.4);
   6.370 +   Vector2i v2i_2;
   6.371 +   Vector3f v3f_2;
   6.372 +   Vector4d v4d_2;
   6.373 +   int i = 2;
   6.374 +   float f = 2.f;
   6.375 +   double d = 2.0;
   6.376  
   6.377 -   Vector2i v2i[3] = { { 1, 2 }, { 3, 4 } };
   6.378 -   cout << setw(40) << "v2i[0]: " << getstring2v(v2i[0], s1) << endl;
   6.379 -   cout << setw(40) << "v2i[1]: " << getstring2v(v2i[1], s1) << endl;
   6.380 -   subtract2v(v2i[0], v2i[1]);
   6.381 -   cout << setw(40) << "subtract2v(v2i[0], v2i[1]): " << getstring2v(v2i[0], s1) << endl;
   6.382 -   cout << setw(40) << "length2v(subtract2v(v2i[0], v2i[1])): " << length2v(subtract2v(v2i[0], v2i[1])) << endl;
   6.383 -
   6.384 -   Vector3f v3f[3] = { { 1.1f, 2.2f, 3.3f }, { 4.4f, 5.5f, 6.6f } };
   6.385 -   cout << setw(40) << "v3f[0]: " << getstring3v(v3f[0], s1) << endl;
   6.386 -   cout << setw(40) << "v3f[1]: " << getstring3v(v3f[1], s1) << endl;
   6.387 -   subtract3v(v3f[0], v3f[1]);
   6.388 -   cout << setw(40) << "subtract3v(v3f[0], v3f[1]): " << getstring3v(v3f[0], s1) << endl;
   6.389 -   cout << setw(40) << "length3v(subtract3v(v3f[0], v3f[1])): " << length3v(subtract3v(v3f[0], v3f[1])) << endl;
   6.390 -
   6.391 -   Vector4d v4d[3] = { { 1.1, 2.2, 3.3, 4.4 }, { 5.5, 6.6, 7.7, 8.8 } };
   6.392 -   cout << setw(40) << "v4d[0]: " << getstring4v(v4d[0], s1) << endl;
   6.393 -   cout << setw(40) << "v4d[1]: " << getstring4v(v4d[1], s1) << endl;
   6.394 -   subtract4v(v4d[0], v4d[1]);
   6.395 -   cout << setw(40) << "subtract4v(v4d[0], v4d[1]): " << getstring4v(v4d[0], s1) << endl;
   6.396 -   cout << setw(40) << "length4v(subtract4v(v4d[0], v4d[1])): " << length4v(subtract4v(v4d[0], v4d[1])) << endl;
   6.397 -
   6.398 +   cout << setw(40) << "v2i: " << v2i.getstring(s1) << endl;
   6.399 +   cout << setw(40) << "v3f: " << v3f.getstring(s1) << endl;
   6.400 +   cout << setw(40) << "v4d: " << v4d.getstring(s1) << endl;
   6.401 +   cout << setw(40) << "v2i_2: " << v2i_2.getstring(s1) << endl;
   6.402 +   cout << setw(40) << "v3f_2: " << v3f_2.getstring(s1) << endl;
   6.403 +   cout << setw(40) << "v4d_2: " << v4d_2.getstring(s1) << endl;
   6.404 +   v2i_2 = v2i / i;
   6.405 +   v3f_2 = v3f / f;
   6.406 +   v4d_2 = v4d / d;
   6.407 +   cout << setw(40) << "v2i_2 = v2i / i: " << v2i_2.getstring(s1) << endl;
   6.408 +   cout << setw(40) << "v3f_2 = v3f / f: " << v3f_2.getstring(s1) << endl;
   6.409 +   cout << setw(40) << "v4d_2 = v4d / d: " << v4d_2.getstring(s1) << endl;
   6.410 +   v2i_2 /= i;
   6.411 +   v3f_2 /= f;
   6.412 +   v4d_2 /= d;
   6.413 +   cout << setw(40) << "v2i_2 /= i: " << v2i_2.getstring(s1) << endl;
   6.414 +   cout << setw(40) << "v3f_2 /= f: " << v3f_2.getstring(s1) << endl;
   6.415 +   cout << setw(40) << "v4d_2 /= d: " << v4d_2.getstring(s1) << endl;
   6.416     }
   6.417  
   6.418 -   // Vector::assign*()
   6.419     {
   6.420     cout << "===============================================================" << endl <<
   6.421 -	 "Testing Vector::assign*()" << endl;
   6.422 -
   6.423 -   Vector2i v2i[3] = { { 1, 2 }, { 3, 4 } };
   6.424 -   cout << setw(40) << "v2i[0]: " << getstring2v(v2i[0], s1) << endl;
   6.425 -   cout << setw(40) << "v2i[1]: " << getstring2v(v2i[1], s1) << endl;
   6.426 -   assign2v(v2i[0], v2i[1]);
   6.427 -   cout << setw(40) << "assign2v(v2i[0], v2i[1]): " << getstring2v(v2i[0], s1) << endl;
   6.428 -
   6.429 -   Vector3f v3f[3] = { { 1.1f, 2.2f, 3.3f }, { 4.4f, 5.5f, 6.6f } };
   6.430 -   cout << setw(40) << "v3f[0]: " << getstring3v(v3f[0], s1) << endl;
   6.431 -   cout << setw(40) << "v3f[1]: " << getstring3v(v3f[1], s1) << endl;
   6.432 -   assign3v(v3f[0], v3f[1]);
   6.433 -   cout << setw(40) << "assign3v(v3f[0], v3f[1]): " << getstring3v(v3f[0], s1) << endl;
   6.434 -
   6.435 -   Vector4d v4d[3] = { { 1.1, 2.2, 3.3, 4.4 }, { 5.5, 6.6, 7.7, 8.8 } };
   6.436 -   cout << setw(40) << "v4d[0]: " << getstring4v(v4d[0], s1) << endl;
   6.437 -   cout << setw(40) << "v4d[1]: " << getstring4v(v4d[1], s1) << endl;
   6.438 -   assign4v(v4d[0], v4d[1]);
   6.439 -   cout << setw(40) << "assign4v(v4d[0], v4d[1]): " << getstring4v(v4d[0], s1) << endl;
   6.440 -
   6.441 +	 "Testing Vector cross product" << endl;
   6.442 +   Vector3f v3f(1.1f, 2.2f, 3.3f);
   6.443 +   Vector3f v3f_2(4.4, 5.5, 6.6);
   6.444 +   Vector3f v3f_3;
   6.445 +   Vector3f v3f_4;
   6.446 +   cout << setw(40) << "v3f: " << v3f.getstring(s1) << endl;
   6.447 +   cout << setw(40) << "v3f_2: " << v3f_2.getstring(s1) << endl;
   6.448 +   cout << setw(40) << "v3f_3: " << v3f_3.getstring(s1) << endl;
   6.449 +   v3f.cross(v3f_2, v3f_3);
   6.450 +   cout << setw(40) << "v3f.cross(v3f_2, v3f_3): " << v3f_3.getstring(s1) << endl;
   6.451 +   v3f_4 = 2.0 * v3f.cross(v3f_2);
   6.452 +   cout << setw(40) << "2.0 * v3f.cross(v3f_2,): " << v3f_4.getstring(s1) << endl;
   6.453 +   v3f_4.assign(0,0,0);
   6.454 +   v3f.cross(v3f_2, v3f_4);
   6.455 +   cout << setw(40) << "v3f.cross(v3f_2, v3f_4): " << v3f_4.getstring(s1) << endl;
   6.456     }
   6.457  
   6.458 -   // Vector::proj*()
   6.459     {
   6.460     cout << "===============================================================" << endl <<
   6.461 -	 "Testing Vector::proj*()" << endl;
   6.462 +	 "Testing Vector dot product" << endl;
   6.463 +   Vector2i v2i(1, 2);
   6.464 +   Vector2i v2i_2(3, 4);
   6.465 +   Vector3f v3f(1.1f, 2.2f, 3.3f);
   6.466 +   Vector3f v3f_2(4.4, 5.5, 6.6);
   6.467 +   Vector4d v4d(1.1, 2.2, 3.3, 4.4);
   6.468 +   Vector4d v4d_2(5.5, 6.6, 7.7, 8.8);
   6.469 +   int i;
   6.470 +   float f;
   6.471 +   double d;
   6.472 +   cout << setw(40) << "v2i: " << v2i.getstring(s1) << endl;
   6.473 +   cout << setw(40) << "v2i_2: " << v2i_2.getstring(s1) << endl;
   6.474 +   cout << setw(40) << "v3f: " << v3f.getstring(s1) << endl;
   6.475 +   cout << setw(40) << "v3f_2: " << v3f_2.getstring(s1) << endl;
   6.476 +   cout << setw(40) << "v4d: " << v4d.getstring(s1) << endl;
   6.477 +   cout << setw(40) << "v4d_2: " << v4d_2.getstring(s1) << endl;
   6.478 +   i = v2i.dot(v2i_2);
   6.479 +   cout << setw(40) << "i = v2i.dot(v2i_2): " << i << endl;
   6.480 +   f = v3f.dot(v3f_2);
   6.481 +   cout << setw(40) << "f = v3f.dot(v3f_2): " << f << endl;
   6.482 +   d = v4d.dot(v4d_2);
   6.483 +   cout << setw(40) << "d = v4d.dot(v4d_2): " << d << endl;
   6.484 +   }
   6.485  
   6.486 -   Vector2f v2f[3] = { { 1.1f, 2.2f }, { 3.3f, 4.4f } };
   6.487 -   Vector2f v2fres;
   6.488 -   cout << setw(40) << "v2f[0]: " << getstring2v(v2f[0], s1) << endl;
   6.489 -   cout << setw(40) << "v2f[1]: " << getstring2v(v2f[1], s1) << endl;
   6.490 -   proj3v(v2f[0], v2f[1], v2fres);
   6.491 -   cout << setw(40) << "proj3v(v2f[0], v2f[1], v2fres): " << getstring2v(v2fres, s1) << endl;
   6.492 +   {
   6.493 +   cout << "===============================================================" << endl <<
   6.494 +	 "Testing Vector length" << endl;
   6.495 +   Vector2i v2i(1, 2);
   6.496 +   Vector3f v3f(1.1f, 2.2f, 3.3f);
   6.497 +   Vector4d v4d(1.1, 2.2, 3.3, 4.4);
   6.498 +   cout << setw(40) << "v2i: " << v2i.getstring(s1) << endl;
   6.499 +   cout << setw(40) << "v3f: " << v3f.getstring(s1) << endl;
   6.500 +   cout << setw(40) << "v4d: " << v4d.getstring(s1) << endl;
   6.501 +   cout << setw(40) << "v2i.length(): " << v2i.length() << endl;
   6.502 +   cout << setw(40) << "v3f.length(): " << v3f.length() << endl;
   6.503 +   cout << setw(40) << "v4d.length(): " << v4d.length() << endl;
   6.504 +   }
   6.505  
   6.506 -   Vector3f v3f[3] = { { 1.1f, 2.2f, 3.3f }, { 4.4f, 5.5f, 6.6f } };
   6.507 -   Vector3f v3fres;
   6.508 -   cout << setw(40) << "v3f[0]: " << getstring3v(v3f[0], s1) << endl;
   6.509 -   cout << setw(40) << "v3f[1]: " << getstring3v(v3f[1], s1) << endl;
   6.510 -   proj3v(v3f[0], v3f[1], v3fres);
   6.511 -   cout << setw(40) << "proj3v(v3f[0], v3f[1], v3fres): " << getstring3v(v3fres, s1) << endl;
   6.512 +   {
   6.513 +   cout << "===============================================================" << endl <<
   6.514 +	 "Testing Vector normalize" << endl;
   6.515 +   Vector2f v2f(1.1, 2.2);
   6.516 +   Vector3f v3f(1.1f, 2.2f, 3.3f);
   6.517 +   Vector4d v4d(1.1, 2.2, 3.3, 4.4);
   6.518 +   cout << setw(40) << "v2f: " << v2f.getstring(s1) << endl;
   6.519 +   cout << setw(40) << "v3f: " << v3f.getstring(s1) << endl;
   6.520 +   cout << setw(40) << "v4d: " << v4d.getstring(s1) << endl;
   6.521 +   v2f.normalize();
   6.522 +   cout << setw(40) << "v2f.normalize() " << v2f.getstring(s1) << endl;
   6.523 +   v3f.normalize();
   6.524 +   cout << setw(40) << "v3f.normalize() " << v3f.getstring(s1) << endl;
   6.525 +   v4d.normalize();
   6.526 +   cout << setw(40) << "v4d.normalize() " << v4d.getstring(s1) << endl;
   6.527 +   cout << setw(40) << "v2f.length(): " << v2f.length() << endl;
   6.528 +   cout << setw(40) << "v3f.length(): " << v3f.length() << endl;
   6.529 +   cout << setw(40) << "v4d.length(): " << v4d.length() << endl;
   6.530 +   }
   6.531  
   6.532 -   Vector4d v4d[3] = { { 1.1, 2.2, 3.3, 4.4 }, { 5.5, 6.6, 7.7, 8.8 } };
   6.533 -   Vector4d v4dres;
   6.534 -   cout << setw(40) << "v4d[0]: " << getstring4v(v4d[0], s1) << endl;
   6.535 -   cout << setw(40) << "v4d[1]: " << getstring4v(v4d[1], s1) << endl;
   6.536 -   proj4v(v4d[0], v4d[1], v4dres);
   6.537 -   cout << setw(40) << "proj4v(v4d[0], v4d[1], v4dres): " << getstring4v(v4dres, s1) << endl;
   6.538 +   {
   6.539 +   cout << "===============================================================" << endl <<
   6.540 +	 "Testing Vector get_angle" << endl;
   6.541 +   Vector2i v2i(1, 2);
   6.542 +   Vector2i v2i_2(3, 4);
   6.543 +   Vector3f v3f(1.1f, 2.2f, 3.3f);
   6.544 +   Vector3f v3f_2(4.4, 5.5, 6.6);
   6.545 +   Vector4d v4d(1.1, 2.2, 3.3, 4.4);
   6.546 +   Vector4d v4d_2(5.5, 6.6, 7.7, 8.8);
   6.547 +   double d;
   6.548 +   cout << setw(40) << "v2i: " << v2i.getstring(s1) << endl;
   6.549 +   cout << setw(40) << "v2i_2: " << v2i_2.getstring(s1) << endl;
   6.550 +   cout << setw(40) << "v3f: " << v3f.getstring(s1) << endl;
   6.551 +   cout << setw(40) << "v3f_2: " << v3f_2.getstring(s1) << endl;
   6.552 +   cout << setw(40) << "v4d: " << v4d.getstring(s1) << endl;
   6.553 +   cout << setw(40) << "v4d_2: " << v4d_2.getstring(s1) << endl;
   6.554 +   d = v2i.get_angle(v2i_2);
   6.555 +   cout << setw(40) << "d = v2i.get_angle(v2i_2): " << d << endl;
   6.556 +   d = v3f.get_angle(v3f_2);
   6.557 +   cout << setw(40) << "d = v3f.get_angle(v3f_2): " << d << endl;
   6.558 +   d = v4d.get_angle(v4d_2);
   6.559 +   cout << setw(40) << "d = v4d.get_angle(v4d_2): " << d << endl;
   6.560 +   }
   6.561  
   6.562 +   {
   6.563 +   cout << "===============================================================" << endl <<
   6.564 +	 "Testing Vector get_anglen" << endl;
   6.565 +   Vector2f v2f(1.1, 2.2);
   6.566 +   Vector2f v2f_2(3.3, 4.4);
   6.567 +   Vector3f v3f(1.1f, 2.2f, 3.3f);
   6.568 +   Vector3f v3f_2(4.4, 5.5, 6.6);
   6.569 +   Vector4d v4d(1.1, 2.2, 3.3, 4.4);
   6.570 +   Vector4d v4d_2(5.5, 6.6, 7.7, 8.8);
   6.571 +   double d;
   6.572 +   v2f.normalize();
   6.573 +   v2f_2.normalize();
   6.574 +   v3f.normalize();
   6.575 +   v3f_2.normalize();
   6.576 +   v4d.normalize();
   6.577 +   v4d_2.normalize();
   6.578 +   cout << setw(40) << "v2f: " << v2f.getstring(s1) << endl;
   6.579 +   cout << setw(40) << "v2f_2: " << v2f_2.getstring(s1) << endl;
   6.580 +   cout << setw(40) << "v3f: " << v3f.getstring(s1) << endl;
   6.581 +   cout << setw(40) << "v3f_2: " << v3f_2.getstring(s1) << endl;
   6.582 +   cout << setw(40) << "v4d: " << v4d.getstring(s1) << endl;
   6.583 +   cout << setw(40) << "v4d_2: " << v4d_2.getstring(s1) << endl;
   6.584 +   d = v2f.get_anglen(v2f_2);
   6.585 +   cout << setw(40) << "d = v2f.get_anglen(v2f_2): " << d << endl;
   6.586 +   d = v3f.get_anglen(v3f_2);
   6.587 +   cout << setw(40) << "d = v3f.get_anglen(v3f_2): " << d << endl;
   6.588 +   d = v4d.get_anglen(v4d_2);
   6.589 +   cout << setw(40) << "d = v4d.get_anglen(v4d_2): " << d << endl;
   6.590 +   }
   6.591 +
   6.592 +   {
   6.593 +   cout << "===============================================================" << endl <<
   6.594 +	 "Testing Vector get_proj" << endl;
   6.595 +   Vector2f v2f(1.1, 2.2);
   6.596 +   Vector2f v2f_2(3.3, 4.4);
   6.597 +   Vector2f v2f_3;
   6.598 +   Vector3f v3f(1.1f, 2.2f, 3.3f);
   6.599 +   Vector3f v3f_2(4.4, 5.5, 6.6);
   6.600 +   Vector3f v3f_3;
   6.601 +   Vector4d v4d(1.1, 2.2, 3.3, 4.4);
   6.602 +   Vector4d v4d_2(5.5, 6.6, 7.7, 8.8);
   6.603 +   Vector4d v4d_3;
   6.604 +   cout << setw(40) << "v2f: " << v2f.getstring(s1) << endl;
   6.605 +   cout << setw(40) << "v2f_2: " << v2f_2.getstring(s1) << endl;
   6.606 +   cout << setw(40) << "v3f: " << v3f.getstring(s1) << endl;
   6.607 +   cout << setw(40) << "v3f_2: " << v3f_2.getstring(s1) << endl;
   6.608 +   cout << setw(40) << "v4d: " << v4d.getstring(s1) << endl;
   6.609 +   cout << setw(40) << "v4d_2: " << v4d_2.getstring(s1) << endl;
   6.610 +   v2f_3 = v2f.proj(v2f_2);
   6.611 +   cout << setw(40) << "v2f_3 = v2f.proj(v3f_2): " << v2f_3.getstring(s1) << endl;
   6.612 +   v3f_3 = v3f.proj(v3f_2);
   6.613 +   cout << setw(40) << "v3f_3 = v3f.proj(v3f_2): " << v3f_3.getstring(s1) << endl;
   6.614 +   v4d_3 = v4d.proj(v4d_2);
   6.615 +   cout << setw(40) << "v4d_3 = v4d.proj(v4d_2): " << v4d_3.getstring(s1) << endl;
   6.616 +   v2f_3.assign(0,0);
   6.617 +   v3f_3.assign(0,0,0);
   6.618 +   v4d_3.assign(0,0,0,0);
   6.619 +   v2f.proj(v2f_2, v2f_3);
   6.620 +   cout << setw(40) << "v2f.proj(v2f_2, v2f_3): " << v2f_3.getstring(s1) << endl;
   6.621 +   v3f.proj(v3f_2, v3f_3);
   6.622 +   cout << setw(40) << "v3f.proj(v3f_2, v3f_3): " << v3f_3.getstring(s1) << endl;
   6.623 +   v4d.proj(v4d_2, v4d_3);
   6.624 +   cout << setw(40) << "v4d.proj(v4d_2, v4d_3): " << v4d_3.getstring(s1) << endl;
   6.625     }
   6.626  
   6.627     }
   6.628 @@ -278,254 +423,7 @@
   6.629  ////////////////////////////////////////////////////////////////////////////////
   6.630  void test_matrix(void)
   6.631     {
   6.632 -   std::string s;
   6.633 -
   6.634 -   {
   6.635 -   cout << "===============================================================" << endl <<
   6.636 -	 "Testing Matrix::assign*()" << endl;
   6.637 -   Matrix2i m2i[2] = { { 0, 0, 
   6.638 -			 0, 0 }, 
   6.639 -		       { 1, 2, 
   6.640 -			 3, 4 } };
   6.641 -   Matrix3f m3f[2] = { { 0.0f, 0.0f, 0.0f, 
   6.642 -			 0.0f, 0.0f, 0.0f, 
   6.643 -			 0.0f, 0.0f, 0.0f }, 
   6.644 -		       { 1.1f, 2.2f, 3.3f, 
   6.645 -			 4.4f, 5.5f, 6.6f, 
   6.646 -			 7.7f, 8.8f, 9.9f } };
   6.647 -   Matrix4d m4d[2] = { { 0.0, 0.0, 0.0, 0.0, 
   6.648 -			 0.0, 0.0, 0.0, 0.0, 
   6.649 -			 0.0, 0.0, 0.0, 0.0, 
   6.650 -			 0.0, 0.0, 0.0, 0.0 }, 
   6.651 -		       { 1.1, 2.2, 3.3, 4.4, 
   6.652 -			 5.5, 6.6, 7.7, 8.8, 
   6.653 -			 9.9, 10.10, 11.11, 12.12,
   6.654 -			 13.13, 14.14, 15.15, 16.16 } };
   6.655 -   cout << setw(40) << "m2i[0]" << getstring2m(m2i[0], s) << endl;
   6.656 -   cout << setw(40) << "m2i[1]" << getstring2m(m2i[1], s) << endl;
   6.657 -   assign2m(m2i[0], m2i[1]);
   6.658 -   cout << setw(40) << "assign2m(m2i[0], m2i[1])" << getstring2m(m2i[0], s) << endl;
   6.659 -
   6.660 -   cout << setw(40) << "m3f[0]" << getstring3m(m3f[0], s) << endl;
   6.661 -   cout << setw(40) << "m3f[1]" << getstring3m(m3f[1], s) << endl;
   6.662 -   assign3m(m3f[0], m3f[1]);
   6.663 -   cout << setw(40) << "assign3m(m3f[0], m3f[1])" << getstring3m(m3f[0], s) << endl;
   6.664 -
   6.665 -   cout << setw(40) << "m4d[0]" << getstring4m(m4d[0], s) << endl;
   6.666 -   cout << setw(40) << "m4d[1]" << getstring4m(m4d[1], s) << endl;
   6.667 -   assign4m(m4d[0], m4d[1]);
   6.668 -   cout << setw(40) << "assign4m(m3d[0], m3d[1])" << getstring4m(m4d[0], s) << endl;
   6.669 -   }
   6.670 -
   6.671 -   {
   6.672 -   cout << "===============================================================" << endl <<
   6.673 -	 "Testing Matrix::add*()" << endl;
   6.674 -   Matrix2i m2i[2] = { { 1, 2, 
   6.675 -			 3, 4 },
   6.676 -		       { 5, 6, 
   6.677 -			 7, 8 } };
   6.678 -   Matrix3f m3f[2] = { { 1.1f, 2.2f, 3.3f, 
   6.679 -			 4.4f, 5.5f, 6.6f, 
   6.680 -			 7.7f, 8.8f, 9.9f },
   6.681 -		       { 10.10f, 11.11f, 12.12f, 
   6.682 -			 13.13f, 14.14f, 15.15f, 
   6.683 -			 16.16f, 17.17f, 18.18f } };
   6.684 -   Matrix4d m4d[2] = { { 1.1, 2.2, 3.3, 4.4, 
   6.685 -			 5.5, 6.6, 7.7, 8.8, 
   6.686 -			 9.9, 10.10, 11.11, 12.12,
   6.687 -			 13.13, 14.14, 15.15, 16.16 },
   6.688 -		       { 17.17, 18.18, 19.19, 20.20, 
   6.689 -			 21.21, 22.22, 23.23, 24.24, 
   6.690 -			 25.25, 26.26, 27.27, 28.28,
   6.691 -			 29.29, 30.30, 31.31, 32.32 } };
   6.692 -   cout << setw(40) << "m2i[0]" << getstring2m(m2i[0], s) << endl;
   6.693 -   cout << setw(40) << "m2i[1]" << getstring2m(m2i[1], s) << endl;
   6.694 -   add2m(m2i[0], m2i[1]);
   6.695 -   cout << setw(40) << "add2m(m2i[0], m2i[1])" << getstring2m(m2i[0], s) << endl;
   6.696 -
   6.697 -   cout << setw(40) << "m3f[0]" << getstring3m(m3f[0], s) << endl;
   6.698 -   cout << setw(40) << "m3f[1]" << getstring3m(m3f[1], s) << endl;
   6.699 -   add3m(m3f[0], m3f[1]);
   6.700 -   cout << setw(40) << "add3m(m3f[0], m3f[1])" << getstring3m(m3f[0], s) << endl;
   6.701 -
   6.702 -   cout << setw(40) << "m4d[0]" << getstring4m(m4d[0], s) << endl;
   6.703 -   cout << setw(40) << "m4d[1]" << getstring4m(m4d[1], s) << endl;
   6.704 -   add4m(m4d[0], m4d[1]);
   6.705 -   cout << setw(40) << "add4m(m3d[0], m3d[1])" << getstring4m(m4d[0], s) << endl;
   6.706 -   }
   6.707 -
   6.708 -   {
   6.709 -   cout << "===============================================================" << endl <<
   6.710 -	 "Testing Matrix::subtract*()" << endl;
   6.711 -   Matrix2i m2i[2] = { { 1, 2, 
   6.712 -			 3, 4 },
   6.713 -		       { 5, 6, 
   6.714 -			 7, 8 } };
   6.715 -   Matrix3f m3f[2] = { { 1.1f, 2.2f, 3.3f, 
   6.716 -			 4.4f, 5.5f, 6.6f, 
   6.717 -			 7.7f, 8.8f, 9.9f },
   6.718 -		       { 10.10f, 11.11f, 12.12f, 
   6.719 -			 13.13f, 14.14f, 15.15f, 
   6.720 -			 16.16f, 17.17f, 18.18f } };
   6.721 -   Matrix4d m4d[2] = { { 1.1, 2.2, 3.3, 4.4, 
   6.722 -			 5.5, 6.6, 7.7, 8.8, 
   6.723 -			 9.9, 10.10, 11.11, 12.12,
   6.724 -			 13.13, 14.14, 15.15, 16.16 },
   6.725 -		       { 17.17, 18.18, 19.19, 20.20, 
   6.726 -			 21.21, 22.22, 23.23, 24.24, 
   6.727 -			 25.25, 26.26, 27.27, 28.28,
   6.728 -			 29.29, 30.30, 31.31, 32.32 } };
   6.729 -   cout << setw(40) << "m2i[0]" << getstring2m(m2i[0], s) << endl;
   6.730 -   cout << setw(40) << "m2i[1]" << getstring2m(m2i[1], s) << endl;
   6.731 -   subtract2m(m2i[0], m2i[1]);
   6.732 -   cout << setw(40) << "subtract2m(m2i[0], m2i[1])" << getstring2m(m2i[0], s) << endl;
   6.733 -
   6.734 -   cout << setw(40) << "m3f[0]" << getstring3m(m3f[0], s) << endl;
   6.735 -   cout << setw(40) << "m3f[1]" << getstring3m(m3f[1], s) << endl;
   6.736 -   subtract3m(m3f[0], m3f[1]);
   6.737 -   cout << setw(40) << "subtract3m(m3f[0], m3f[1])" << getstring3m(m3f[0], s) << endl;
   6.738 -
   6.739 -   cout << setw(40) << "m4d[0]" << getstring4m(m4d[0], s) << endl;
   6.740 -   cout << setw(40) << "m4d[1]" << getstring4m(m4d[1], s) << endl;
   6.741 -   subtract4m(m4d[0], m4d[1]);
   6.742 -   cout << setw(40) << "subtract4m(m3d[0], m3d[1])" << getstring4m(m4d[0], s) << endl;
   6.743 -   }
   6.744 -
   6.745 -   {
   6.746 -   cout << "===============================================================" << endl <<
   6.747 -	 "Testing Matrix::scale*()" << endl;
   6.748 -   Matrix2i m2i = { 1, 2, 
   6.749 -		    3, 4 };
   6.750 -   Matrix3f m3f = { 1.1f, 2.2f, 3.3f, 
   6.751 -		    4.4f, 5.5f, 6.6f, 
   6.752 -		    7.7f, 8.8f, 9.9f };
   6.753 -   Matrix4d m4d = { 1.1, 2.2, 3.3, 4.4, 
   6.754 -		    5.5, 6.6, 7.7, 8.8, 
   6.755 -		    9.9, 10.10, 11.11, 12.12,
   6.756 -		    13.13, 14.14, 15.15, 16.16 };
   6.757 -   cout << setw(40) << "m2i" << getstring2m(m2i, s) << endl;
   6.758 -   cout << setw(40) << "scale2m(m2i, 2)" << getstring2m(scale2m(m2i, 2), s) << endl;
   6.759 -
   6.760 -   cout << setw(40) << "m3f" << getstring3m(m3f, s) << endl;
   6.761 -   cout << setw(40) << "scale3m(m3f, 2.2f)" << getstring3m(scale3m(m3f, 2.2f), s) << endl;
   6.762 -
   6.763 -   cout << setw(40) << "m4d" << getstring4m(m4d, s) << endl;
   6.764 -   cout << setw(40) << "scale4m(m3d, 2.2)" << getstring4m(scale4m(m4d, 2.2), s) << endl;
   6.765 -   }
   6.766 -
   6.767 -   {
   6.768 -   cout << "===============================================================" << endl <<
   6.769 -	 "Testing Matrix::multvec*()" << endl;
   6.770 -   Vector2i v2ires;
   6.771 -   Vector3f v3fres;
   6.772 -   Vector4d v4dres;
   6.773 -   Vector2i v2i = { 1, 2 };
   6.774 -   Vector3f v3f = { 1.1f, 2.2f, 3.3f };
   6.775 -   Vector4d v4d = { 1.1, 2.2, 3.3, 4.4 };
   6.776 -   Matrix2i m2i = { 1, 2, 
   6.777 -		    3, 4 };
   6.778 -   Matrix3f m3f = { 1.1f, 2.2f, 3.3f, 
   6.779 -		    4.4f, 5.5f, 6.6f, 
   6.780 -		    7.7f, 8.8f, 9.9f };
   6.781 -   Matrix4d m4d = { 1.1, 2.2, 3.3, 4.4, 
   6.782 -		    5.5, 6.6, 7.7, 8.8, 
   6.783 -		    9.9, 10.10, 11.11, 12.12,
   6.784 -		    13.13, 14.14, 15.15, 16.16 };
   6.785 -   cout << setw(40) << "v2i" << getstring2v(v2i, s) << endl;
   6.786 -   cout << setw(40) << "m2i" << getstring2m(m2i, s) << endl;
   6.787 -   cout << setw(40) << "multvec2mv(m2i, v2i, v2ires)" << 
   6.788 -	 getstring2v(multvec2mv(m2i, v2i, v2ires), s) << endl;
   6.789 -   cout << setw(40) << "multvec2mv(m2i, v2i, v2ires)" << 
   6.790 -	 getstring2v(multvec2vm(v2i, m2i, v2ires), s) << endl;
   6.791 -
   6.792 -   cout << setw(40) << "v3f" << getstring3v(v3f, s) << endl;
   6.793 -   cout << setw(40) << "m3f" << getstring3m(m3f, s) << endl;
   6.794 -   cout << setw(40) << "multvec3mv(m3f, v3f, v3fres)" << 
   6.795 -	 getstring3v(multvec3mv(m3f, v3f, v3fres), s) << endl;
   6.796 -   cout << setw(40) << "multvec3mv(m3f, v3f, v3fres)" << 
   6.797 -	 getstring3v(multvec3vm(v3f, m3f, v3fres), s) << endl;
   6.798 -
   6.799 -   cout << setw(40) << "v4d" << getstring4v(v4d, s) << endl;
   6.800 -   cout << setw(40) << "m4d" << getstring4m(m4d, s) << endl;
   6.801 -   cout << setw(40) << "multvec4mv(m4d, v4d, v4dres)" << 
   6.802 -	 getstring4v(multvec4mv(m4d, v4d, v4dres), s) << endl;
   6.803 -   cout << setw(40) << "multvec4mv(m4d, v4d, v4dres)" << 
   6.804 -	 getstring4v(multvec4vm(v4d, m4d, v4dres), s) << endl;
   6.805 -
   6.806 -   }
   6.807 -
   6.808 -
   6.809 -   {
   6.810 -   cout << "===============================================================" << endl <<
   6.811 -	 "Testing Matrix::multmat*()" << endl;
   6.812 -   Matrix2i m2ires;
   6.813 -   Matrix3f m3fres;
   6.814 -   Matrix4d m4dres;
   6.815 -   Matrix2i m2i[2] = { { 1, 2, 
   6.816 -			 3, 4 },
   6.817 -		       { 5, 6, 
   6.818 -			 7, 8 } };
   6.819 -   Matrix3f m3f[2] = { { 1.1f, 2.2f, 3.3f, 
   6.820 -			 4.4f, 5.5f, 6.6f, 
   6.821 -			 7.7f, 8.8f, 9.9f },
   6.822 -		       { 10.10f, 11.11f, 12.12f, 
   6.823 -			 13.13f, 14.14f, 15.15f, 
   6.824 -			 16.16f, 17.17f, 18.18f } };
   6.825 -   Matrix4d m4d[2] = { { 1.1, 2.2, 3.3, 4.4, 
   6.826 -			 5.5, 6.6, 7.7, 8.8, 
   6.827 -			 9.9, 10.10, 11.11, 12.12,
   6.828 -			 13.13, 14.14, 15.15, 16.16 },
   6.829 -		       { 17.17, 18.18, 19.19, 20.20, 
   6.830 -			 21.21, 22.22, 23.23, 24.24, 
   6.831 -			 25.25, 26.26, 27.27, 28.28,
   6.832 -			 29.29, 30.30, 31.31, 32.32 } };
   6.833 -   cout << setw(40) << "m2i[0]" << getstring2m(m2i[0], s) << endl;
   6.834 -   cout << setw(40) << "m2i[1]" << getstring2m(m2i[1], s) << endl;
   6.835 -   multmat2(m2i[0], m2i[1], m2ires);
   6.836 -   cout << setw(40) << "multmat2(m2i[0], m2i[1], m21res)" << 
   6.837 -	 getstring2m(m2ires, s) << endl;
   6.838 -
   6.839 -   cout << setw(40) << "m3f[0]" << getstring3m(m3f[0], s) << endl;
   6.840 -   cout << setw(40) << "m3f[1]" << getstring3m(m3f[1], s) << endl;
   6.841 -   multmat3(m3f[0], m3f[1], m3fres);
   6.842 -   cout << setw(40) << "multmat3(m3f[0], m3f[1], m3fres)" << 
   6.843 -	 getstring3m(m3fres, s) << endl;
   6.844 -
   6.845 -   cout << setw(40) << "m4d[0]" << getstring4m(m4d[0], s) << endl;
   6.846 -   cout << setw(40) << "m4d[1]" << getstring4m(m4d[1], s) << endl;
   6.847 -   multmat4(m4d[0], m4d[1], m4dres);
   6.848 -   cout << setw(40) << "multmat4(m4d[0], m4d[1], m4dres)" << 
   6.849 -	 getstring4m(m4dres, s) << endl;
   6.850 -   }
   6.851 -
   6.852 -   {
   6.853 -   cout << "===============================================================" << endl <<
   6.854 -	 "Testing Matrix::transpose*()" << endl;
   6.855 -   Matrix2i m2ires;
   6.856 -   Matrix3f m3fres;
   6.857 -   Matrix4d m4dres;
   6.858 -   Matrix2i m2i = { 1, 2, 
   6.859 -		    3, 4 };
   6.860 -   Matrix3f m3f = { 1.1f, 2.2f, 3.3f, 
   6.861 -		    4.4f, 5.5f, 6.6f, 
   6.862 -		    7.7f, 8.8f, 9.9f };
   6.863 -   Matrix4d m4d = { 1.1, 2.2, 3.3, 4.4, 
   6.864 -		    5.5, 6.6, 7.7, 8.8, 
   6.865 -		    9.9, 10.10, 11.11, 12.12,
   6.866 -		    13.13, 14.14, 15.15, 16.16 };
   6.867 -   cout << setw(40) << "m2i" << getstring2m(m2i, s) << endl;
   6.868 -   cout << setw(40) << "transpose2(m2i, m2ires)" << 
   6.869 -	 getstring2m(transpose2(m2i, m2ires), s) << endl;
   6.870 -
   6.871 -   cout << setw(40) << "m3f" << getstring3m(m3f, s) << endl;
   6.872 -   cout << setw(40) << "transpose3(m3f, m3fres)" << 
   6.873 -	 getstring3m(transpose3(m3f, m3fres), s) << endl;
   6.874 -
   6.875 -   cout << setw(40) << "m4d" << getstring4m(m4d, s) << endl;
   6.876 -   cout << setw(40) << "transpose4(m4d, m4dres)" << 
   6.877 -	 getstring4m(transpose4(m4d, m4dres), s) << endl;
   6.878 -
   6.879 -   }
   6.880 +   string s;
   6.881     }
   6.882  
   6.883  ////////////////////////////////////////////////////////////////////////////////