00001 #ifndef VECTOR2_H_ 00002 #define VECTOR2_H_ 00003 00004 /* greebo: This file contains the templated class definition of the three-component vector 00005 * 00006 * BasicVector2: A vector with three components of type <Element> 00007 * 00008 * The BasicVector2 is equipped with the most important operators like *, *= and so on. 00009 * 00010 * Note: The most commonly used Vector2 is a BasicVector2<float>, this is also defined in this file 00011 * 00012 * Note: that the multiplication of a Vector2 with another one (Vector2*Vector2) does NOT 00013 * result in an inner product but in a component-wise scaling. Use the .dot() method to 00014 * execute an inner product of two vectors. 00015 */ 00016 00017 #include "lrint.h" 00018 #include <cmath> 00019 #include <float.h> 00020 #include <sstream> 00021 00022 template<typename Element> 00023 class BasicVector2 00024 { 00025 // This is where the components of the vector are stored. 00026 Element m_elements[2]; 00027 00028 public: 00029 // Constructor with no arguments 00030 BasicVector2 () 00031 { 00032 } 00033 00036 BasicVector2 (const Element& x_, const Element& y_) 00037 { 00038 x() = x_; 00039 y() = y_; 00040 } 00041 00042 // Return NON-CONSTANT references to the vector components 00043 Element& x () 00044 { 00045 return m_elements[0]; 00046 } 00047 Element& y () 00048 { 00049 return m_elements[1]; 00050 } 00051 00052 // Return CONSTANT references to the vector components 00053 const Element& x () const 00054 { 00055 return m_elements[0]; 00056 } 00057 const Element& y () const 00058 { 00059 return m_elements[1]; 00060 } 00061 00062 Element& operator[] (std::size_t i) 00063 { 00064 return m_elements[i]; 00065 } 00066 const Element& operator[] (std::size_t i) const 00067 { 00068 return m_elements[i]; 00069 } 00070 00071 Element* data () 00072 { 00073 return m_elements; 00074 } 00075 const Element* data () const 00076 { 00077 return m_elements; 00078 } 00079 00082 bool operator== (const BasicVector2& other) const 00083 { 00084 return (other.x() == x() && other.y() == y()); 00085 } 00086 00089 bool operator!= (const BasicVector2& other) const 00090 { 00091 return !(*this == other); 00092 } 00093 00094 /* Define the negation operator - 00095 * All the vector's components are negated 00096 */ 00097 BasicVector2<Element> operator- () const 00098 { 00099 return BasicVector2<Element> (-m_elements[0], -m_elements[1]); 00100 } 00101 00102 /* Define the addition operators + and += with any other BasicVector2 of type OtherElement 00103 * The vectors are added to each other element-wise 00104 */ 00105 template<typename OtherElement> 00106 BasicVector2<Element> operator+ (const BasicVector2<OtherElement>& other) const 00107 { 00108 return BasicVector2<Element> (m_elements[0] + static_cast<Element> (other.x()), m_elements[1] 00109 + static_cast<Element> (other.y())); 00110 } 00111 00112 template<typename OtherElement> 00113 void operator+= (const BasicVector2<OtherElement>& other) 00114 { 00115 m_elements[0] += static_cast<Element> (other.x()); 00116 m_elements[1] += static_cast<Element> (other.y()); 00117 } 00118 00119 /* Define the substraction operators - and -= with any other BasicVector2 of type OtherElement 00120 * The vectors are substracted from each other element-wise 00121 */ 00122 template<typename OtherElement> 00123 BasicVector2<Element> operator- (const BasicVector2<OtherElement>& other) const 00124 { 00125 return BasicVector2<Element> (m_elements[0] - static_cast<Element> (other.x()), m_elements[1] 00126 - static_cast<Element> (other.y())); 00127 } 00128 00129 template<typename OtherElement> 00130 void operator-= (const BasicVector2<OtherElement>& other) 00131 { 00132 m_elements[0] -= static_cast<Element> (other.x()); 00133 m_elements[1] -= static_cast<Element> (other.y()); 00134 } 00135 00136 /* Define the multiplication operators * and *= with another Vector2 of type OtherElement 00137 * 00138 * The vectors are multiplied element-wise 00139 * 00140 * greebo: This is mathematically kind of senseless, as this is a mixture of 00141 * a dot product and scalar multiplication. It can be used to scale each 00142 * vector component by a different factor, so maybe this comes in handy. 00143 */ 00144 template<typename OtherElement> 00145 BasicVector2<Element> operator* (const BasicVector2<OtherElement>& other) const 00146 { 00147 return BasicVector2<Element> (m_elements[0] * static_cast<Element> (other.x()), m_elements[1] 00148 * static_cast<Element> (other.y())); 00149 } 00150 00151 template<typename OtherElement> 00152 void operator*= (const BasicVector2<OtherElement>& other) 00153 { 00154 m_elements[0] *= static_cast<Element> (other.x()); 00155 m_elements[1] *= static_cast<Element> (other.y()); 00156 } 00157 00158 /* Define the multiplications * and *= with a scalar 00159 */ 00160 template<typename OtherElement> 00161 BasicVector2<Element> operator* (const OtherElement& other) const 00162 { 00163 Element factor = static_cast<Element> (other); 00164 return BasicVector2<Element> (m_elements[0] * factor, m_elements[1] * factor); 00165 } 00166 00167 template<typename OtherElement> 00168 void operator*= (const OtherElement& other) 00169 { 00170 Element factor = static_cast<Element> (other); 00171 m_elements[0] *= factor; 00172 m_elements[1] *= factor; 00173 } 00174 00175 /* Define the division operators / and /= with another Vector2 of type OtherElement 00176 * The vectors are divided element-wise 00177 */ 00178 template<typename OtherElement> 00179 BasicVector2<Element> operator/ (const BasicVector2<OtherElement>& other) const 00180 { 00181 return BasicVector2<Element> (m_elements[0] / static_cast<Element> (other.x()), m_elements[1] 00182 / static_cast<Element> (other.y())); 00183 } 00184 00185 template<typename OtherElement> 00186 void operator/= (const BasicVector2<OtherElement>& other) 00187 { 00188 m_elements[0] /= static_cast<Element> (other.x()); 00189 m_elements[1] /= static_cast<Element> (other.y()); 00190 } 00191 00192 /* Define the scalar divisions / and /= 00193 */ 00194 template<typename OtherElement> 00195 BasicVector2<Element> operator/ (const OtherElement& other) const 00196 { 00197 Element divisor = static_cast<Element> (other); 00198 return BasicVector2<Element> (m_elements[0] / divisor, m_elements[1] / divisor); 00199 } 00200 00201 template<typename OtherElement> 00202 void operator/= (const OtherElement& other) 00203 { 00204 Element divisor = static_cast<Element> (other); 00205 m_elements[0] /= divisor; 00206 m_elements[1] /= divisor; 00207 } 00208 00214 double getLength () const 00215 { 00216 double lenSquared = m_elements[0] * m_elements[0] + m_elements[1] * m_elements[1]; 00217 return sqrt(lenSquared); 00218 } 00219 00222 double getLengthSquared () const 00223 { 00224 double lenSquared = m_elements[0] * m_elements[0] + m_elements[1] * m_elements[1]; 00225 return lenSquared; 00226 } 00227 00228 /* Scalar product this vector with another Vector2, 00229 * returning the projection of <self> onto <other> 00230 * 00231 * @param other 00232 * The Vector2 to dot-product with this Vector2. 00233 * 00234 * @returns 00235 * The inner product (a scalar): a[0]*b[0] + a[1]*b[1] 00236 */ 00237 template<typename OtherT> 00238 Element dot (const BasicVector2<OtherT>& other) const 00239 { 00240 return Element(m_elements[0] * other.x() + m_elements[1] * other.y()); 00241 } 00242 00243 /* Cross-product this vector with another Vector2, returning the scalar result 00244 * 00245 * @param other 00246 * The Vector2 to cross-product with this Vector2. 00247 * 00248 * @returns 00249 * The cross-product of the two vectors, a scalar: a[0]*b[1] - b[0]*a[1] 00250 */ 00251 template<typename OtherT> 00252 Element crossProduct (const BasicVector2<OtherT>& other) const 00253 { 00254 return Element(m_elements[0] * other.y() - m_elements[1] * other.x()); 00255 } 00256 00260 std::string toString () const 00261 { 00262 std::stringstream ss; 00263 ss << m_elements[0] << " " << m_elements[1]; 00264 return ss.str(); 00265 } 00266 }; 00267 00268 // ========================================================================================== 00269 00270 // A 2-element vector stored in single-precision floating-point. 00271 typedef BasicVector2<float> Vector2; 00272 00273 #endif /*VECTOR2_H_*/