BWAPI
|
00001 #pragma once 00002 00003 #include <boost/type_traits.hpp> 00004 00005 // TODO templated version of arithmetic operator? 00006 00012 template<class T> 00013 class Vector2 00014 { 00015 static_assert<boost::is_signed<T>::value || boost::is_float<T>::value> arithmetic_operations_assume_signed_types; 00016 static_assert<boost::is_scalar<T>::value> arithmetic_operations_assume_scalar_types; 00017 00018 public: 00024 Vector2(const T& x, const T& y) : m_X(x), m_Y(y) { } 00025 00032 template<class U> 00033 Vector2(const U& x, const U& y) : m_X(static_cast<T>(x)), m_Y(static_cast<T>(y)) { } 00034 00040 template<class U> 00041 Vector2(const Vector2<U>& other) 00042 :m_X(static_cast<T>(other.x())) 00043 ,m_Y(static_cast<T>(other.y())) 00044 { 00045 } 00046 00053 template<class U> 00054 Vector2<T>& operator=(const Vector2<U>& other) 00055 { 00056 m_X = static_cast<T>(other.x()); 00057 m_Y = static_cast<T>(other.y()); 00058 return *this; 00059 } 00060 00061 T& x() { return m_X; } 00062 T& y() { return m_Y; } 00063 00064 T x() const { return m_X; } 00065 T y() const { return m_Y; } 00066 00072 Vector2<T> operator+(const Vector2<T>& other) const 00073 { 00074 return Vector2<T>(m_X + other.m_X, m_Y + other.m_Y); 00075 } 00076 00082 Vector2<T>& operator+=(const Vector2<T>& other) 00083 { 00084 m_X += other.m_X; 00085 m_Y += other.m_Y; 00086 return *this; 00087 } 00088 00094 Vector2<T> operator-(const Vector2<T>& other) const 00095 { 00096 return Vector2<T>(m_X - other.m_X, m_Y - other.m_Y); 00097 } 00098 00104 Vector2<T>& operator-=(const Vector2<T>& other) 00105 { 00106 m_X -= other.m_X; 00107 m_Y -= other.m_Y; 00108 return *this; 00109 } 00110 00115 Vector2<T> operator-() const 00116 { 00117 return Vector2<T>(-m_X, -m_Y); 00118 } 00119 00120 // TODO use least restrictive type for return value 00127 template<class U> 00128 Vector2<T> operator*(const U& val) const 00129 { 00130 static_assert<boost::is_scalar<U>::value> multiplication_by_a_scalar_value; 00131 unused(multiplication_by_a_scalar_value); 00132 00133 return Vector2<T>(static_cast<T>(val * m_X), static_cast<T>(val * m_Y)); 00134 } 00135 00142 template<class U> 00143 Vector2<T>& operator*=(const U& val) 00144 { 00145 static_assert<boost::is_scalar<U>::value> multiplication_by_a_scalar_value; 00146 unused(multiplication_by_a_scalar_value); 00147 00148 m_X *= val; 00149 m_Y *= val; 00150 return *this; 00151 } 00152 00158 T dot(const Vector2<T>& other) const 00159 { 00160 return (m_X * other.m_X) + (m_Y * other.m_Y); 00161 } 00162 00167 Vector2<T> perpendicular() const 00168 { 00169 return Vector2<T>(-m_Y, m_X); 00170 } 00171 00177 bool operator==(const Vector2<T>& other) const 00178 { 00179 return m_X == other.m_X && m_Y == other.m_Y; 00180 } 00181 00187 bool operator!=(const Vector2<T>& other) const 00188 { 00189 return !(*this == other); 00190 } 00191 00196 double squared_length() const 00197 { 00198 return static_cast<double>(dot(*this)); 00199 } 00200 00205 double length() const 00206 { 00207 return sqrt(squared_length()); 00208 } 00209 00215 double squared_distance_to(const Vector2<T>& other) const 00216 { 00217 return (*this - other).squared_length(); 00218 } 00219 00225 double distance_to(const Vector2<T>& other) const 00226 { 00227 return sqrt(squared_distance_to(other)); 00228 } 00229 00230 private: 00231 T m_X; 00232 T m_Y; 00233 }; 00234 00243 template<class T, class U> 00244 Vector2<T> operator*(const U& val, const Vector2<T>& vec) 00245 { 00246 static_assert<boost::is_scalar<U>::value> multiplication_by_a_scalar_value; 00247 unused(multiplication_by_a_scalar_value); 00248 00249 return vec * val; 00250 }; 00251 00252 typedef Vector2<int> Vector2i; 00253 typedef Vector2<float> Vector2f; 00254 typedef Vector2<double> Vector2d;