# HG changeset patch # User Eris Caffee # Date 1315158368 18000 # Node ID f6e6f3c8f7eb463287b355aa78d6e0222221b44a # Parent f4e384b966b9d8f4375eb768c3fc86c4d34b19e4 Vectors done diff -r f4e384b966b9 -r f6e6f3c8f7eb include/Math.h --- a/include/Math.h Tue Aug 30 11:08:12 2011 -0500 +++ b/include/Math.h Sun Sep 04 12:46:08 2011 -0500 @@ -1,8 +1,7 @@ #ifndef MATH_H_ #define MATH_H_ -#include -#include +#include "Vector.h" namespace arda { @@ -20,212 +19,15 @@ // experts in the field. //////////////////////////////////////////////////////////////////////////////// - // Vectors + // Angles - namespace Vector + namespace Angles { + // This many decimals is enough to cover even IEEE quad precision (128 bit) + // reals. Run on PA-RISC lately? :) + const double PI = 3.14159265358979323846264338327950288; + } - typedef int Vector2i[2]; - typedef float Vector2f[2]; - typedef double Vector2d[2]; - - typedef int Vector3i[3]; - typedef float Vector3f[3]; - typedef double Vector3d[3]; - - typedef int Vector4i[4]; - typedef float Vector4f[4]; - typedef double Vector4d[4]; - - ////////////////////////////////////////////////////////////////////////// - // vectostr*(Vector v) - // Returns a C string representation of the vector. - // This is one of the few non-inline Vector functions. - - std::string & vectostr2(Vector2i v, std::string & s); - std::string & vectostr2(Vector2f v, std::string & s); - std::string & vectostr2(Vector2d v, std::string & s); - std::string & vectostr3(Vector3i v, std::string & s); - std::string & vectostr3(Vector3f v, std::string & s); - std::string & vectostr3(Vector3d v, std::string & s); - std::string & vectostr4(Vector4i v, std::string & s); - std::string & vectostr4(Vector4f v, std::string & s); - std::string & vectostr4(Vector4d v, std::string & s); - - ////////////////////////////////////////////////////////////////////////// - // scale*(Vector v, scalar s) - // Multiply a vector by a scalar. - // Returns v so that the result may be passed to other functions. - - inline int * scale2(Vector2i v, const int s) - { v[0] = v[0] * s ; v[1] = v[1] * s; return v; } - inline int * scale2(Vector2i v, const float s) - { v[0] = v[0] * s ; v[1] = v[1] * s; return v; } - inline int * scale2(Vector2i v, const double s) - { v[0] = v[0] * s ; v[1] = v[1] * s; return v; } - - inline float * scale2(Vector2f v, const int s) - { v[0] = v[0] * s ; v[1] = v[1] * s; return v; } - inline float * scale2(Vector2f v, const float s) - { v[0] = v[0] * s ; v[1] = v[1] * s; return v; } - inline float * scale2(Vector2f v, const double s) - { v[0] = v[0] * s ; v[1] = v[1] * s; return v; } - - inline double * scale2(Vector2d v, const int s) - { v[0] = v[0] * s ; v[1] = v[1] * s; return v; } - inline double * scale2(Vector2d v, const float s) - { v[0] = v[0] * s ; v[1] = v[1] * s; return v; } - inline double * scale2(Vector2d v, const double s) - { v[0] = v[0] * s ; v[1] = v[1] * s; return v; } - - - inline int * scale3(Vector3i v, const int s) - { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; } - inline int * scale3(Vector3i v, const float s) - { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; } - inline int * scale3(Vector3i v, const double s) - { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; } - - inline float * scale3(Vector3f v, const int s) - { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; } - inline float * scale3(Vector3f v, const float s) - { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; } - inline float * scale3(Vector3f v, const double s) - { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; } - - inline double * scale3(Vector3d v, const int s) - { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; } - inline double * scale3(Vector3d v, const float s) - { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; } - inline double * scale3(Vector3d v, const double s) - { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; } - - - inline int * scale4(Vector4i v, const int s) - { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; v[3] = v[3] * s; return v; } - inline int * scale4(Vector4i v, const float s) - { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; v[3] = v[3] * s; return v; } - inline int * scale4(Vector4i v, const double s) - { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; v[3] = v[3] * s; return v; } - - inline float * scale4(Vector4f v, const int s) - { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; v[3] = v[3] * s; return v; } - inline float * scale4(Vector4f v, const float s) - { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; v[3] = v[3] * s; return v; } - inline float * scale4(Vector4f v, const double s) - { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; v[3] = v[3] * s; return v; } - - inline double * scale4(Vector4d v, const int s) - { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; v[3] = v[3] * s; return v; } - inline double * scale4(Vector4d v, const float s) - { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; v[3] = v[3] * s; return v; } - inline double * scale4(Vector4d v, const double s) - { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; v[3] = v[3] * s; return v; } - - - ////////////////////////////////////////////////////////////////////////// - // dot*(Vector v1, Vector v2) - // The dot product of two vectors, which must be the same type - // Returns a long for int vectors, a double for floating point vectors. - - inline long dot2(Vector2i v1, Vector2i v2) - { return (long) v1[0]*v2[0] + (long) v1[1]*v2[1]; } - inline double dot2(Vector2f v1, Vector2f v2) - { return (double) v1[0]*v2[0] + (double) v1[1]*v2[1]; } - inline double dot2(Vector2d v1, Vector2d v2) - { return v1[0]*v2[0] + v1[1]*v2[1]; } - - inline long dot3(Vector3i v1, Vector3i v2) - { return (long) v1[0]*v2[0] + (long) v1[1]*v2[1] + (long) v1[2]*v2[2]; } - inline double dot3(Vector3f v1, Vector3f v2) - { return (double) v1[0]*v2[0] + (double) v1[1]*v2[1] + (double) v1[2]*v2[2]; } - inline double dot3(Vector3d v1, Vector3d v2) - { return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; } - - inline long dot4(Vector4i v1, Vector4i v2) - { return (long) v1[0]*v2[0] + (long) v1[1]*v2[1] + (long) v1[2]*v2[2] + (long) v1[3]*v2[3]; } - inline double dot4(Vector4f v1, Vector4f v2) - { return (double) v1[0]*v2[0] + (double) v1[1]*v2[1] + (double) v1[2]*v2[2] + (double) v1[3]*v2[3]; } - inline double dot4(Vector4d v1, Vector4d v2) - { return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2] + v1[3]*v2[3]; } - - - ////////////////////////////////////////////////////////////////////////// - // length*(Vector v) - // Get the length of a vector. - // Returns a float for float for float vectors, and a double for - // int and double vectors. - - inline double length2(Vector2i v) - { return sqrt((dot2(v, v))); } - inline float length2(Vector2f v) - { return sqrtf((dot2(v, v))); } - inline double length2(Vector2d v) - { return sqrt((dot2(v, v))); } - - inline double length3(Vector3i v) - { return sqrt((dot3(v, v))); } - inline float length3(Vector3f v) - { return sqrtf((dot3(v, v))); } - inline double length3(Vector3d v) - { return sqrt((dot3(v, v))); } - - inline double length4(Vector4i v) - { return sqrt((dot4(v, v))); } - inline float length4(Vector4f v) - { return sqrtf((dot4(v, v))); } - inline double length4(Vector4d v) - { return sqrt((dot4(v, v))); } - - - ////////////////////////////////////////////////////////////////////////// - // add*(Vector v1, Vector v2, Vector vres) - // Add two vectors together. - // Returns vres so that the result may be used in further - // calculations. - - inline int * add2(Vector2i v1, Vector2i v2, Vector2i vres) - { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; return vres; } - inline float * add2(Vector2f v1, Vector2f v2, Vector2f vres) - { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; return vres; } - inline double * add2(Vector2d v1, Vector2d v2, Vector2d vres) - { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; return vres; } - - inline int * add3(Vector3i v1, Vector3i v2, Vector3i vres) - { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; vres[2] = v1[2] + v2[2]; return vres; } - inline float * add3(Vector3f v1, Vector3f v2, Vector3f vres) - { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; vres[2] = v1[2] + v2[2]; return vres; } - inline double * add3(Vector3d v1, Vector3d v2, Vector3d vres) - { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; vres[2] = v1[2] + v2[2]; return vres; } - - inline int * add4(Vector4i v1, Vector4i v2, Vector4i vres) - { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; vres[2] = v1[2] + v2[2]; vres[3] = v1[3] + v2[3]; return vres;} - inline float * add4(Vector4f v1, Vector4f v2, Vector4f vres) - { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; vres[2] = v1[2] + v2[2]; vres[3] = v1[3] + v2[3]; return vres; } - inline double * add4(Vector4d v1, Vector4d v2, Vector4d vres) - { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; vres[2] = v1[2] + v2[2]; vres[3] = v1[3] + v2[3]; return vres; } - - ////////////////////////////////////////////////////////////////////////// - // normalize*(Vector v) - // Normalizes the vecor. Only defined for floating point vectors. - // Returns the vector. - - inline float * normalize2(Vector2f v) - { float l = length2(v); v[0] /= l; v[1] /= l; return v; } - inline double * normalize2(Vector2d v) - { double l = length2(v); v[0] /= l; v[1] /= l; return v; } - - inline float * normalize3(Vector3f v) - { float l = length3(v); v[0] /= l; v[1] /= l; v[2] /= l; return v; } - inline double * normalize3(Vector3d v) - { double l = length3(v); v[0] /= l; v[1] /= l; v[2] /= l; return v; } - - inline float * normalize4(Vector4f v) - { float l = length4(v); v[0] /= l; v[1] /= l; v[2] /= l; v[3] /= l; return v; } - inline double * normalize4(Vector4d v) - { double l = length4(v); v[0] /= l; v[1] /= l; v[2] /= l; v[3] /= l; return v; } - } - -} // namespace arda + } // namespace arda #endif diff -r f4e384b966b9 -r f6e6f3c8f7eb include/Vector.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/Vector.h Sun Sep 04 12:46:08 2011 -0500 @@ -0,0 +1,421 @@ +#ifndef VECTOR_H_ +#define VECTOR_H_ + +#include +#include + +namespace arda + { + + //////////////////////////////////////////////////////////////////////////////// + // Vectors + // + // Supported operations on vectors + // + // assign*() Assign the value of one vector to another. + // add*() Add two vectors + // cross() Cross product of two 3-space vectors. + // dot*() Dot product. + // get_angle*() Calculate angle between two vectors. + // length*() Length of a vector (the Euclidean norm). + // normalize*() Normalize the vector. + // proj*() Calculate the projection of one vector onto another. + // scale*() Multiply vector by a scalar. + // subtract*() A convenience function to avoid writing add(v1, scale(v2, -1)) + // vectostr*() Returns a printable string representation of the vector. + // + // All functions except vectostr are defined inline. + + namespace Vector + { + + typedef int Vector2i[2]; + typedef float Vector2f[2]; + typedef double Vector2d[2]; + + typedef int Vector3i[3]; + typedef float Vector3f[3]; + typedef double Vector3d[3]; + + typedef int Vector4i[4]; + typedef float Vector4f[4]; + typedef double Vector4d[4]; + + ////////////////////////////////////////////////////////////////////////// + // vectostr*(Vector v) + // Returns a C string representation of the vector. + // This is one of the few non-inline Vector functions. + + std::string & vectostr2(Vector2i v, std::string & s); + std::string & vectostr2(Vector2f v, std::string & s); + std::string & vectostr2(Vector2d v, std::string & s); + std::string & vectostr3(Vector3i v, std::string & s); + std::string & vectostr3(Vector3f v, std::string & s); + std::string & vectostr3(Vector3d v, std::string & s); + std::string & vectostr4(Vector4i v, std::string & s); + std::string & vectostr4(Vector4f v, std::string & s); + std::string & vectostr4(Vector4d v, std::string & s); + + ////////////////////////////////////////////////////////////////////////// + // scale*(Vector v, scalar s) + // Multiply a vector by a scalar. + // Returns v so that the result may be passed to other functions. + + inline int * scale2(Vector2i v, const int s) + { v[0] = v[0] * s ; v[1] = v[1] * s; return v; } + inline int * scale2(Vector2i v, const float s) + { v[0] = v[0] * s ; v[1] = v[1] * s; return v; } + inline int * scale2(Vector2i v, const double s) + { v[0] = v[0] * s ; v[1] = v[1] * s; return v; } + + inline float * scale2(Vector2f v, const int s) + { v[0] = v[0] * s ; v[1] = v[1] * s; return v; } + inline float * scale2(Vector2f v, const float s) + { v[0] = v[0] * s ; v[1] = v[1] * s; return v; } + inline float * scale2(Vector2f v, const double s) + { v[0] = v[0] * s ; v[1] = v[1] * s; return v; } + + inline double * scale2(Vector2d v, const int s) + { v[0] = v[0] * s ; v[1] = v[1] * s; return v; } + inline double * scale2(Vector2d v, const float s) + { v[0] = v[0] * s ; v[1] = v[1] * s; return v; } + inline double * scale2(Vector2d v, const double s) + { v[0] = v[0] * s ; v[1] = v[1] * s; return v; } + + + inline int * scale3(Vector3i v, const int s) + { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; } + inline int * scale3(Vector3i v, const float s) + { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; } + inline int * scale3(Vector3i v, const double s) + { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; } + + inline float * scale3(Vector3f v, const int s) + { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; } + inline float * scale3(Vector3f v, const float s) + { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; } + inline float * scale3(Vector3f v, const double s) + { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; } + + inline double * scale3(Vector3d v, const int s) + { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; } + inline double * scale3(Vector3d v, const float s) + { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; } + inline double * scale3(Vector3d v, const double s) + { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; return v; } + + + inline int * scale4(Vector4i v, const int s) + { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; v[3] = v[3] * s; return v; } + inline int * scale4(Vector4i v, const float s) + { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; v[3] = v[3] * s; return v; } + inline int * scale4(Vector4i v, const double s) + { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; v[3] = v[3] * s; return v; } + + inline float * scale4(Vector4f v, const int s) + { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; v[3] = v[3] * s; return v; } + inline float * scale4(Vector4f v, const float s) + { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; v[3] = v[3] * s; return v; } + inline float * scale4(Vector4f v, const double s) + { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; v[3] = v[3] * s; return v; } + + inline double * scale4(Vector4d v, const int s) + { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; v[3] = v[3] * s; return v; } + inline double * scale4(Vector4d v, const float s) + { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; v[3] = v[3] * s; return v; } + inline double * scale4(Vector4d v, const double s) + { v[0] = v[0] * s ; v[1] = v[1] * s; v[2] = v[2] * s; v[3] = v[3] * s; return v; } + + + ////////////////////////////////////////////////////////////////////////// + // dot*(Vector v1, Vector v2) + // The dot product of two vectors, which must be the same type + // Returns a long for int vectors, a double for floating point vectors. + + inline long dot2(Vector2i v1, Vector2i v2) + { return (long) v1[0]*v2[0] + (long) v1[1]*v2[1]; } + inline double dot2(Vector2f v1, Vector2f v2) + { return (double) v1[0]*v2[0] + (double) v1[1]*v2[1]; } + inline double dot2(Vector2d v1, Vector2d v2) + { return v1[0]*v2[0] + v1[1]*v2[1]; } + + inline long dot3(Vector3i v1, Vector3i v2) + { return (long) v1[0]*v2[0] + (long) v1[1]*v2[1] + (long) v1[2]*v2[2]; } + inline double dot3(Vector3f v1, Vector3f v2) + { return (double) v1[0]*v2[0] + (double) v1[1]*v2[1] + (double) v1[2]*v2[2]; } + inline double dot3(Vector3d v1, Vector3d v2) + { return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; } + + inline long dot4(Vector4i v1, Vector4i v2) + { return (long) v1[0]*v2[0] + (long) v1[1]*v2[1] + (long) v1[2]*v2[2] + (long) v1[3]*v2[3]; } + inline double dot4(Vector4f v1, Vector4f v2) + { return (double) v1[0]*v2[0] + (double) v1[1]*v2[1] + (double) v1[2]*v2[2] + (double) v1[3]*v2[3]; } + inline double dot4(Vector4d v1, Vector4d v2) + { return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2] + v1[3]*v2[3]; } + + + ////////////////////////////////////////////////////////////////////////// + // length*(Vector v) + // Get the length of a vector. + // Returns a float for float for float vectors, and a double for + // int and double vectors. + + inline double length2(Vector2i v) + { return sqrt((dot2(v, v))); } + inline double length2(Vector2f v) + { return sqrtf((dot2(v, v))); } + inline double length2(Vector2d v) + { return sqrt((dot2(v, v))); } + + inline double length3(Vector3i v) + { return sqrt((dot3(v, v))); } + inline double length3(Vector3f v) + { return sqrtf((dot3(v, v))); } + inline double length3(Vector3d v) + { return sqrt((dot3(v, v))); } + + inline double length4(Vector4i v) + { return sqrt((dot4(v, v))); } + inline double length4(Vector4f v) + { return sqrtf((dot4(v, v))); } + inline double length4(Vector4d v) + { return sqrt((dot4(v, v))); } + + + ////////////////////////////////////////////////////////////////////////// + // add*(Vector v1, Vector v2, Vector vres) + // Add two vectors together. + // Returns vres so that the result may be used in further + // calculations. + + inline int * add2(Vector2i v1, Vector2i v2, Vector2i vres) + { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; return vres; } + inline float * add2(Vector2f v1, Vector2f v2, Vector2f vres) + { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; return vres; } + inline double * add2(Vector2d v1, Vector2d v2, Vector2d vres) + { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; return vres; } + + inline int * add3(Vector3i v1, Vector3i v2, Vector3i vres) + { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; vres[2] = v1[2] + v2[2]; return vres; } + inline float * add3(Vector3f v1, Vector3f v2, Vector3f vres) + { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; vres[2] = v1[2] + v2[2]; return vres; } + inline double * add3(Vector3d v1, Vector3d v2, Vector3d vres) + { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; vres[2] = v1[2] + v2[2]; return vres; } + + inline int * add4(Vector4i v1, Vector4i v2, Vector4i vres) + { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; vres[2] = v1[2] + v2[2]; vres[3] = v1[3] + v2[3]; return vres;} + inline float * add4(Vector4f v1, Vector4f v2, Vector4f vres) + { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; vres[2] = v1[2] + v2[2]; vres[3] = v1[3] + v2[3]; return vres; } + inline double * add4(Vector4d v1, Vector4d v2, Vector4d vres) + { vres[0] = v1[0] + v2[0]; vres[1] = v1[1] + v2[1]; vres[2] = v1[2] + v2[2]; vres[3] = v1[3] + v2[3]; return vres; } + + ////////////////////////////////////////////////////////////////////////// + // normalize*(Vector v) + // Normalizes the vecor. Only defined for floating point vectors. + // Returns the vector. + + inline float * normalize2(Vector2f v) + { double l = length2(v); v[0] /= l; v[1] /= l; return v; } + inline double * normalize2(Vector2d v) + { double l = length2(v); v[0] /= l; v[1] /= l; return v; } + + inline float * normalize3(Vector3f v) + { double l = length3(v); v[0] /= l; v[1] /= l; v[2] /= l; return v; } + inline double * normalize3(Vector3d v) + { double l = length3(v); v[0] /= l; v[1] /= l; v[2] /= l; return v; } + + inline float * normalize4(Vector4f v) + { double l = length4(v); v[0] /= l; v[1] /= l; v[2] /= l; v[3] /= l; return v; } + inline double * normalize4(Vector4d v) + { double l = length4(v); v[0] /= l; v[1] /= l; v[2] /= l; v[3] /= l; return v; } + + ////////////////////////////////////////////////////////////////////////// + // cross(Vector3 v) + // Only defined for floating point 3 vectors. + // Returns the result vector. + + inline float * cross(Vector3f v1, Vector3f v2, Vector3f vres) + { + vres[0] = v1[1]*v2[2] - v2[1]*v1[2]; + vres[1] = -v1[0]*v2[2] + v2[0]*v1[2]; + vres[2] = v1[0]*v2[1] - v2[0]*v1[1]; + return vres; + } + + inline double * cross(Vector3d v1, Vector3d v2, Vector3d vres) + { + vres[0] = v1[1]*v2[2] - v2[1]*v1[2]; + vres[1] = -v1[0]*v2[2] + v2[0]*v1[2]; + vres[2] = v1[0]*v2[1] - v2[0]*v1[1]; + return vres; + } + + ////////////////////////////////////////////////////////////////////////// + // get_angle*(Vector3 v1, Vector3 v2) + // Returns the angle in radians between the two vectors. + // + // get_angle[234]n() take pre-normalized vectors as arguments and will + // fail otherwise. This version is not defined for interger + // vectors since you can't normalize an integer vector. + // get_angle[234]() take arbitrary vectors as arguments. + // + // I started out with two version of get_angle3: + // get_angle3_1 implemented as + // return acos(dot3(v1, v2)/(length3(v1)*length3(v2))); + // get_angle3_2 implemented as + // double tmp = dot3(v1, v2); + // return acos(sqrtf(tmp*tmp/(dot3(v1,v1)*dot3(v2,v2)))); + // + // I ran timing tests, since I expected the second one - the one I chose to + // use, in the end - to be faster since it only resulted in one sqrt call + // instead of two. Here are the results + // + // get_angle3_1 44.753006890 seconds for 500,000,000 iterations. + // get_angle3_2 36.940170102 seconds for 500,000,000 iterations. + // + // Faster? Yes. About 7 nanoseconds vs 9. A ridiculous optimization + // to worry about? Eh. I might as well use it. + + inline double get_angle2n(Vector2f v1, Vector2f v2) + { return acos(dot2(v1, v2)); } + inline double get_angle2n(Vector2d v1, Vector2d v2) + { return acos(dot2(v1, v2)); } + inline double get_angle2(Vector2i v1, Vector2i v2) + { + double tmp = dot2(v1, v2); + return acos(sqrtf(tmp*tmp/(dot2(v1,v1)*dot2(v2,v2)))); + } + inline double get_angle2(Vector2f v1, Vector2f v2) + { + double tmp = dot2(v1, v2); + return acos(sqrtf(tmp*tmp/(dot2(v1,v1)*dot2(v2,v2)))); + } + inline double get_angle2(Vector2d v1, Vector2d v2) + { + double tmp = dot2(v1, v2); + return acos(sqrtf(tmp*tmp/(dot2(v1,v1)*dot2(v2,v2)))); + } + + inline double get_angle3n(Vector3f v1, Vector3f v2) + { return acos(dot3(v1, v2)); } + inline double get_angle3n(Vector3d v1, Vector3d v2) + { return acos(dot3(v1, v2)); } + inline double get_angle3(Vector3i v1, Vector3i v2) + { + double tmp = dot3(v1, v2); + return acos(sqrtf(tmp*tmp/(dot3(v1,v1)*dot3(v2,v2)))); + } + inline double get_angle3(Vector3f v1, Vector3f v2) + { + double tmp = dot3(v1, v2); + return acos(sqrtf(tmp*tmp/(dot3(v1,v1)*dot3(v2,v2)))); + } + inline double get_angle3(Vector3d v1, Vector3d v2) + { + double tmp = dot3(v1, v2); + return acos(sqrtf(tmp*tmp/(dot3(v1,v1)*dot3(v2,v2)))); + } + + inline double get_angle4n(Vector4f v1, Vector4f v2) + { return acos(dot4(v1, v2)); } + inline double get_angle4n(Vector4d v1, Vector4d v2) + { return acos(dot4(v1, v2)); } + inline double get_angle4(Vector4i v1, Vector4i v2) + { + double tmp = dot4(v1, v2); + return acos(sqrtf(tmp*tmp/(dot4(v1,v1)*dot4(v2,v2)))); + } + inline double get_angle4(Vector4f v1, Vector4f v2) + { + double tmp = dot4(v1, v2); + return acos(sqrtf(tmp*tmp/(dot4(v1,v1)*dot4(v2,v2)))); + } + inline double get_angle4(Vector4d v1, Vector4d v2) + { + double tmp = dot4(v1, v2); + return acos(sqrtf(tmp*tmp/(dot4(v1,v1)*dot4(v2,v2)))); + } + + ////////////////////////////////////////////////////////////////////////// + // subtract*(Vector v1, Vector v2, Vector vres) + // Subtract v2 from v1 and store result in vres. + // Equivalent to add(v1, scale(v2, -1), vres). + // Returns vres so that the result may be used in further + // calculations. + + inline int * subtract2(Vector2i v1, Vector2i v2, Vector2i vres) + { vres[0] = v1[0] - v2[0]; vres[1] = v1[1] - v2[1]; return vres; } + inline float * subtract2(Vector2f v1, Vector2f v2, Vector2f vres) + { vres[0] = v1[0] - v2[0]; vres[1] = v1[1] - v2[1]; return vres; } + inline double * subtract2(Vector2d v1, Vector2d v2, Vector2d vres) + { vres[0] = v1[0] - v2[0]; vres[1] = v1[1] - v2[1]; return vres; } + + inline int * subtract3(Vector3i v1, Vector3i v2, Vector3i vres) + { vres[0] = v1[0] - v2[0]; vres[1] = v1[1] - v2[1]; vres[2] = v1[2] - v2[2]; return vres; } + inline float * subtract3(Vector3f v1, Vector3f v2, Vector3f vres) + { vres[0] = v1[0] - v2[0]; vres[1] = v1[1] - v2[1]; vres[2] = v1[2] - v2[2]; return vres; } + inline double * subtract3(Vector3d v1, Vector3d v2, Vector3d vres) + { vres[0] = v1[0] - v2[0]; vres[1] = v1[1] - v2[1]; vres[2] = v1[2] - v2[2]; return vres; } + + inline int * subtract4(Vector4i v1, Vector4i v2, Vector4i vres) + { vres[0] = v1[0] - v2[0]; vres[1] = v1[1] - v2[1]; vres[2] = v1[2] - v2[2]; vres[3] = v1[3] - v2[3]; return vres;} + inline float * subtract4(Vector4f v1, Vector4f v2, Vector4f vres) + { vres[0] = v1[0] - v2[0]; vres[1] = v1[1] - v2[1]; vres[2] = v1[2] - v2[2]; vres[3] = v1[3] - v2[3]; return vres; } + inline double * subtract4(Vector4d v1, Vector4d v2, Vector4d vres) + { vres[0] = v1[0] - v2[0]; vres[1] = v1[1] - v2[1]; vres[2] = v1[2] - v2[2]; vres[3] = v1[3] - v2[3]; return vres; } + + + ////////////////////////////////////////////////////////////////////////// + // assign*(Vector v1, Vector v2) + // Copies the value of v2 into v1. + // Returns v1. + + inline int * assign2(Vector2i v1, Vector2i v2) + { v1[0] = v2[0]; v1[1] = v2[1]; return v1; } + inline float * assign2(Vector2f v1, Vector2f v2) + { v1[0] = v2[0]; v1[1] = v2[1]; return v1; } + inline double * assign2(Vector2d v1, Vector2d v2) + { v1[0] = v2[0]; v1[1] = v2[1]; return v1; } + + inline int * assign3(Vector3i v1, Vector3i v2) + { v1[0] = v2[0]; v1[1] = v2[1]; v1[2] = v2[2]; return v1; } + inline float * assign3(Vector3f v1, Vector3f v2) + { v1[0] = v2[0]; v1[1] = v2[1]; v1[2] = v2[2]; return v1; } + inline double * assign3(Vector3d v1, Vector3d v2) + { v1[0] = v2[0]; v1[1] = v2[1]; v1[2] = v2[2]; return v1; } + + inline int * assign4(Vector4i v1, Vector4i v2) + { v1[0] = v2[0]; v1[1] = v2[1]; v1[2] = v2[2]; v1[3] = v2[3]; return v1; } + inline float * assign4(Vector4f v1, Vector4f v2) + { v1[0] = v2[0]; v1[1] = v2[1]; v1[2] = v2[2]; v1[3] = v2[3]; return v1; } + inline double * assign4(Vector4d v1, Vector4d v2) + { v1[0] = v2[0]; v1[1] = v2[1]; v1[2] = v2[2]; v1[3] = v2[3]; return v1; } + + + ////////////////////////////////////////////////////////////////////////// + // proj*(Vector v1, Vector v2, Vector vres) + // Calculates the projection of v1 onto v2 and returns the result + // in vres. + // Only defined for floating point vectors. + // Returns vres. + + inline float * proj2(Vector2f v1, Vector2f v2, Vector2f vres) + { assign2(vres, v2); scale2(vres, (dot2(v1, vres)/dot2(vres,vres))); return vres; } + inline double * proj2(Vector2d v1, Vector2d v2, Vector2d vres) + { assign2(vres, v2); scale2(vres, (dot2(v1, vres)/dot2(vres,vres))); return vres; } + + inline float * proj3(Vector3f v1, Vector3f v2, Vector3f vres) + { assign3(vres, v2); scale3(vres, (dot3(v1, vres)/dot3(vres,vres))); return vres; } + inline double * proj3(Vector3d v1, Vector3d v2, Vector3d vres) + { assign3(vres, v2); scale3(vres, (dot3(v1, vres)/dot3(vres,vres))); return vres; } + + inline float * proj4(Vector4f v1, Vector4f v2, Vector4f vres) + { assign4(vres, v2); scale4(vres, (dot4(v1, vres)/dot4(vres,vres))); return vres; } + inline double * proj4(Vector4d v1, Vector4d v2, Vector4d vres) + { assign4(vres, v2); scale4(vres, (dot4(v1, vres)/dot4(vres,vres))); return vres; } + + } // Vector + + } // namespace arda + +#endif // VECTOR_H_ diff -r f4e384b966b9 -r f6e6f3c8f7eb notes --- a/notes Tue Aug 30 11:08:12 2011 -0500 +++ b/notes Sun Sep 04 12:46:08 2011 -0500 @@ -3,16 +3,17 @@ Operations to support +* vector to string * dot * length (norm) * vector addition * scalar multiplication * normalize -cross +* cross +* angle between two vectors +assignment +projection of one vector onto another. triple product i.e. dot(u, cross(v, w)) Is this really that common? -angle between two vectors -projection of one vector onto another. -* vector to string Class with operator overloading? diff -r f4e384b966b9 -r f6e6f3c8f7eb src/main.cpp --- a/src/main.cpp Tue Aug 30 11:08:12 2011 -0500 +++ b/src/main.cpp Sun Sep 04 12:46:08 2011 -0500 @@ -113,7 +113,7 @@ } - // Vector::add*() + // Vector::normalize*() { cout << "===============================================================" << endl << "Testing Vector::normalize*()" << endl; @@ -141,4 +141,138 @@ } + // Vector::cross() + { + cout << "===============================================================" << endl << + "Testing Vector::cross()" << endl; + + Vector3f v3f[3] = { { 1.1f, 2.2f, 3.3f }, { 4.4f, 5.5f, 6.6f }, { 0.0f, 0.0f, 0.0f } }; + cout << setw(40) << "v3f[0]: " << vectostr3(v3f[0], s1) << endl; + cout << setw(40) << "v3f[1]: " << vectostr3(v3f[1], s1) << endl; + cross(v3f[0], v3f[1], v3f[2]); + cout << setw(40) << "cross(v3f[0], v3f[1], v3f[2]): " << vectostr3(v3f[2], s1) << endl; + + Vector3d v3d[3] = { { 1.1, 2.2, 3.3 }, { 4.4, 5.5, 6.6 }, { 0.0, 0.0, 0.0 } }; + cout << setw(40) << "v3d[0]: " << vectostr3(v3d[0], s1) << endl; + cout << setw(40) << "v3d[1]: " << vectostr3(v3d[1], s1) << endl; + cross(v3d[0], v3d[1], v3d[2]); + cout << setw(40) << "cross(v3d[0], v3d[1], v3d[2]): " << vectostr3(v3d[2], s1) << endl; + } + + + // Vector::cross() + { + cout << "===============================================================" << endl << + "Testing Vector::get_angle*()" << endl; + + Vector3i v3i[2] = { { 1, 2, 3 }, { 4, 5, 6 } }; + cout << setw(40) << "v3i[0]: " << vectostr3(v3i[0], s1) << endl; + cout << setw(40) << "v3i[1]: " << vectostr3(v3i[1], s1) << endl; + cout << setw(40) << "get_angle3(v3i[0], v3i[1]): " << get_angle3(v3i[0], v3i[1]) << endl; + + Vector3f v3f[2] = { { 1.1f, 2.2f, 3.3f }, { 4.4f, 5.5f, 6.6f } }; + cout << setw(40) << "v3f[0]: " << vectostr3(v3f[0], s1) << endl; + cout << setw(40) << "v3f[1]: " << vectostr3(v3f[1], s1) << endl; + cout << setw(40) << "get_angle3(v3f[0], v3f[1]): " << get_angle3(v3f[0], v3f[1]) << endl; + normalize3(v3f[0]); + normalize3(v3f[1]); + cout << setw(40) << "v3f[0]: " << vectostr3(v3f[0], s1) << endl; + cout << setw(40) << "v3f[1]: " << vectostr3(v3f[1], s1) << endl; + cout << setw(40) << "get_angle3n(v3f[0], v3f[1]): " << get_angle3n(v3f[0], v3f[1]) << endl; + + Vector3d v3d[2] = { { 1.1, 2.2, 3.3 }, { 4.4, 5.5, 6.6 } }; + cout << setw(40) << "v3d[0]: " << vectostr3(v3d[0], s1) << endl; + cout << setw(40) << "v3d[1]: " << vectostr3(v3d[1], s1) << endl; + cout << setw(40) << "get_angle3(v3d[0], v3d[1]): " << get_angle3(v3d[0], v3d[1]) << endl; + normalize3(v3d[0]); + normalize3(v3d[1]); + cout << setw(40) << "v3d[0]: " << vectostr3(v3d[0], s1) << endl; + cout << setw(40) << "v3d[1]: " << vectostr3(v3d[1], s1) << endl; + cout << setw(40) << "get_angle3n(v3d[0], v3d[1]): " << get_angle3n(v3d[0], v3d[1]) << endl; + } + + // Vector::subtract*() + { + cout << "===============================================================" << endl << + "Testing Vector::subtract*()" << endl; + + Vector2i v2i[3] = { { 1, 2 }, { 3, 4 } }; + Vector2i v2ires; + cout << setw(40) << "v2i[0]: " << vectostr2(v2i[0], s1) << endl; + cout << setw(40) << "v2i[1]: " << vectostr2(v2i[1], s1) << endl; + subtract2(v2i[0], v2i[1], v2ires); + cout << setw(40) << "subtract2(v2i[0], v2i[1], v2ires): " << vectostr2(v2ires, s1) << endl; + cout << setw(40) << "length2(subtract2(v2i[0], v2i[1], v2ires)): " << length2(subtract2(v2i[0], v2i[1], v2ires)) << endl; + + Vector3f v3f[3] = { { 1.1f, 2.2f, 3.3f }, { 4.4f, 5.5f, 6.6f } }; + Vector3f v3fres; + cout << setw(40) << "v3f[0]: " << vectostr3(v3f[0], s1) << endl; + cout << setw(40) << "v3f[1]: " << vectostr3(v3f[1], s1) << endl; + subtract3(v3f[0], v3f[1], v3fres); + cout << setw(40) << "subtract3(v3f[0], v3f[1], v3fres): " << vectostr3(v3fres, s1) << endl; + cout << setw(40) << "length3(subtract3(v3f[0], v3f[1], v3fres)): " << length3(subtract3(v3f[0], v3f[1], v3fres)) << endl; + + Vector4d v4d[3] = { { 1.1, 2.2, 3.3, 4.4 }, { 5.5, 6.6, 7.7, 8.8 } }; + Vector4d v4dres; + cout << setw(40) << "v4d[0]: " << vectostr4(v4d[0], s1) << endl; + cout << setw(40) << "v4d[1]: " << vectostr4(v4d[1], s1) << endl; + subtract4(v4d[0], v4d[1], v4dres); + cout << setw(40) << "subtract4(v4d[0], v4d[1], v4dres): " << vectostr4(v4dres, s1) << endl; + cout << setw(40) << "length4(subtract4(v4d[0], v4d[1], v4dres)): " << length4(subtract4(v4d[0], v4d[1], v4dres)) << endl; + + } + + // Vector::assign*() + { + cout << "===============================================================" << endl << + "Testing Vector::assign*()" << endl; + + Vector2i v2i[3] = { { 1, 2 }, { 3, 4 } }; + cout << setw(40) << "v2i[0]: " << vectostr2(v2i[0], s1) << endl; + cout << setw(40) << "v2i[1]: " << vectostr2(v2i[1], s1) << endl; + assign2(v2i[0], v2i[1]); + cout << setw(40) << "assign2(v2i[0], v2i[1]): " << vectostr2(v2i[0], s1) << endl; + + Vector3f v3f[3] = { { 1.1f, 2.2f, 3.3f }, { 4.4f, 5.5f, 6.6f } }; + cout << setw(40) << "v3f[0]: " << vectostr3(v3f[0], s1) << endl; + cout << setw(40) << "v3f[1]: " << vectostr3(v3f[1], s1) << endl; + assign3(v3f[0], v3f[1]); + cout << setw(40) << "assign3(v3f[0], v3f[1]): " << vectostr3(v3f[0], s1) << endl; + + Vector4d v4d[3] = { { 1.1, 2.2, 3.3, 4.4 }, { 5.5, 6.6, 7.7, 8.8 } }; + cout << setw(40) << "v4d[0]: " << vectostr4(v4d[0], s1) << endl; + cout << setw(40) << "v4d[1]: " << vectostr4(v4d[1], s1) << endl; + assign4(v4d[0], v4d[1]); + cout << setw(40) << "assign4(v4d[0], v4d[1]): " << vectostr4(v4d[0], s1) << endl; + + } + + // Vector::proj*() + { + cout << "===============================================================" << endl << + "Testing Vector::proj*()" << endl; + + Vector2f v2f[3] = { { 1.1f, 2.2f }, { 3.3f, 4.4f } }; + Vector2f v2fres; + cout << setw(40) << "v2f[0]: " << vectostr2(v2f[0], s1) << endl; + cout << setw(40) << "v2f[1]: " << vectostr2(v2f[1], s1) << endl; + proj3(v2f[0], v2f[1], v2fres); + cout << setw(40) << "proj3(v2f[0], v2f[1], v2fres): " << vectostr2(v2fres, s1) << endl; + + Vector3f v3f[3] = { { 1.1f, 2.2f, 3.3f }, { 4.4f, 5.5f, 6.6f } }; + Vector3f v3fres; + cout << setw(40) << "v3f[0]: " << vectostr3(v3f[0], s1) << endl; + cout << setw(40) << "v3f[1]: " << vectostr3(v3f[1], s1) << endl; + proj3(v3f[0], v3f[1], v3fres); + cout << setw(40) << "proj3(v3f[0], v3f[1], v3fres): " << vectostr3(v3fres, s1) << endl; + + Vector4d v4d[3] = { { 1.1, 2.2, 3.3, 4.4 }, { 5.5, 6.6, 7.7, 8.8 } }; + Vector4d v4dres; + cout << setw(40) << "v4d[0]: " << vectostr4(v4d[0], s1) << endl; + cout << setw(40) << "v4d[1]: " << vectostr4(v4d[1], s1) << endl; + proj4(v4d[0], v4d[1], v4dres); + cout << setw(40) << "proj4(v4d[0], v4d[1], v4dres): " << vectostr4(v4dres, s1) << endl; + + } + }