Fix issue in Rocket.lua script.
[Cafu-Engine.git] / Libs / Math3D / Vector2.hpp
blobb5fb79204a53ff78746a0460c7e91306756ee623
1 /*
2 Cafu Engine, http://www.cafu.de/
3 Copyright (c) Carsten Fuchs and other contributors.
4 This project is licensed under the terms of the MIT license.
5 */
7 #ifndef CAFU_MATH_VECTOR2_HPP_INCLUDED
8 #define CAFU_MATH_VECTOR2_HPP_INCLUDED
10 #include "Errors.hpp"
12 #include <cassert>
13 #include <cmath>
14 #include <iomanip>
15 #include <limits>
16 #include <sstream>
19 /// This class represents a 2-dimensional vector.
20 template<class T>
21 class Vector2T
23 public:
25 T x; ///< The x-component of this vector.
26 T y; ///< The y-component of this vector.
30 /// The default constructor. It initializes all components to zero.
31 Vector2T() : x(0), y(0) { }
33 /// This constructor initializes the components from x_ and y_ respectively.
34 Vector2T(T x_, T y_) : x(x_), y(y_) { }
36 /// This constructor initializes the components from an array of (at least) two Ts.
37 template<class C> explicit Vector2T(const C Values[]) : x(T(Values[0])), y(T(Values[1])) { }
41 /// Returns true if the vector is valid, that is, all components are non-NANs.
42 bool IsValid() const
44 return true;
47 /// Component access by index number (0 to 1) rather than by name.
48 /// @param Index Index of the component to access. Can only be 0 or 1 (for x or y).
49 /// @throws InvalidOperationE if Index is not 0 or 1.
50 T& operator [] (unsigned int Index)
52 switch (Index)
54 case 0: return x;
55 case 1: return y;
56 default: throw InvalidOperationE();
60 /// Component access by index number (0 to 1) rather than by name.
61 /// @param Index Index of the component to access. Can only be 0 or 1 (for x or y).
62 /// @throws InvalidOperationE if Index is not 0 or 1.
63 const T& operator [] (unsigned int Index) const
65 switch (Index)
67 case 0: return x;
68 case 1: return y;
69 default: throw InvalidOperationE();
75 /// Gets this Vector2T<T> as a Vector2T<float>, so that the cast is explicitly visible in user code.
76 Vector2T<float> AsVectorOfFloat() const
78 #ifdef _WIN32
79 assert(typeid(T)!=typeid(float));
80 #endif
82 return Vector2T<float>(float(x), float(y));
85 /// Gets this Vector2T<T> as a Vector2T<double>, so that the cast is explicitly visible in user code.
86 Vector2T<double> AsVectorOfDouble() const
88 #ifdef _WIN32
89 assert(typeid(T)!=typeid(double));
90 #endif
92 return Vector2T<double>(double(x), double(y));
97 /// @name Group of const inspector methods. They are all const and thus do not modify this object.
98 //@{
100 /// Returns the square of the length of this vector.
101 T GetLengthSqr() const { return x*x + y*y; }
103 /// Returns whether this vector is equal to B within tolerance Epsilon, that is, whether it is geometrically closer to B than Epsilon.
104 /// @param B Vector to compare to.
105 /// @param Epsilon Tolerance value.
106 /// @see operator ==
107 bool IsEqual(const Vector2T<T>& B, const T Epsilon) const
109 return (*this-B).GetLengthSqr() <= Epsilon*Epsilon;
112 /// Returns a copy of this vector scaled by s, that is, the scalar product (Skalarmultiplikation) of this vector and s.
113 /// @param s Scale factor to scale this vector by.
114 /// @see Also see the operator *, which does exactly the same.
115 Vector2T<T> GetScaled(const T s) const
117 return Vector2T<T>(x*s, y*s);
120 /// Returns a copy of this vector non-uniformely scaled by S.
121 Vector2T<T> GetScaled(const Vector2T<T>& S) const
123 return Vector2T<T>(x*S.x, y*S.y);
126 //@}
130 /// @name Group of (constructive) binary operators that do not modify their operands.
131 //@{
133 /// Returns whether this vector and B are truly (bit-wise) identical.
134 /// Use this operator with care, as it comes *without* any epsilon threshold for taking rounding errors into account.
135 /// @param B Vector to compare to.
136 /// @see IsEqual()
137 bool operator == (const Vector2T<T>& B) const
139 return x==B.x &&
140 y==B.y;
143 /// Returns whether this vector and B are not equal (bit-wise).
144 /// Use this operator with care, as it comes *without* any epsilon threshold for taking rounding errors into account.
145 /// @param B Vector to compare to.
146 /// @see IsEqual()
147 bool operator != (const Vector2T<T>& B) const
149 return x!=B.x ||
150 y!=B.y;
153 /// Returns the sum of this Vector2T<T> and B.
154 Vector2T<T> operator + (const Vector2T<T>& B) const
156 return Vector2T<T>(x+B.x, y+B.y);
159 /// Returns the difference between this Vector2T<T> and B.
160 Vector2T<T> operator - (const Vector2T<T>& B) const
162 return Vector2T<T>(x-B.x, y-B.y);
165 /// The unary minus operator. B=-A is quasi identical with B=A.GetScaled(-1).
166 Vector2T<T> operator - () const
168 return Vector2T<T>(-x, -y);
171 /// Returns a copy of this vector scaled by s, that is, the scalar product (Skalarmultiplikation) of this vector and s.
172 /// @param s Factor to multiply this vector with.
173 /// @see GetScaled(), which does exactly the same.
174 Vector2T<T> operator * (const T s) const
176 return GetScaled(s);
179 /// Returns a copy of this vector divided by s, that is, the scalar product (Skalarmultiplikation) of this vector and 1/s.
180 Vector2T<T> operator / (const T s) const
182 // Cannot multiply by the reciprocal, because that won't work with integers.
183 return Vector2T<T>(x/s, y/s);
186 /// Returns the dot product (Skalarprodukt) of this vector and B.
187 T dot(const Vector2T<T>& B) const
189 return x*B.x + y*B.y;
192 //@}
196 /// @name Group of operators that modify this vector.
197 //@{
199 /// Adds B to this vector.
200 Vector2T<T>& operator += (const Vector2T<T>& B)
202 x+=B.x;
203 y+=B.y;
205 return *this;
208 /// Subtracts B from this vector.
209 Vector2T<T>& operator -= (const Vector2T<T>& B)
211 x-=B.x;
212 y-=B.y;
214 return *this;
217 /// Scales this vector by s.
218 Vector2T<T>& operator *= (const T s)
220 x*=s;
221 y*=s;
223 return *this;
226 /// Divides this vector by s. Assumes that s is not 0.
227 Vector2T<T>& operator /= (const T s)
229 // Cannot multiply by the reciprocal, because that won't work with integers.
230 x/=s;
231 y/=s;
233 return *this;
236 //@}
240 /// Returns A scaled by r, that is, the scalar product (Skalarmultiplikation) of A and r.
241 template<class T> inline Vector2T<T> scale(const Vector2T<T>& A, const T r)
243 return Vector2T<T>(A.x*r, A.y*r);
246 /// Returns A, non-uniformely scaled by R.
247 template<class T> inline Vector2T<T> scale(const Vector2T<T>& A, const Vector2T<T>& R)
249 return Vector2T<T>(A.x*R.x, A.y*R.y);
252 /// Returns the dot product (Skalarprodukt) of A and B.
253 template<class T> inline T dot(const Vector2T<T>& A, const Vector2T<T>& B)
255 return A.x*B.x + A.y*B.y;
258 /// Returns the length of A.
259 template<class T> inline T length(const Vector2T<T>& A)
261 return sqrt(dot(A, A));
264 /// Returns the length of A. This is a specialized version of the generic length<T> function for floats.
265 template<> inline float length(const Vector2T<float>& A)
267 return sqrtf(dot(A, A));
270 /// Returns the normalized (unit length) version of A.
271 /// @throws DivisionByZeroE if length(A)<=Epsilon.
272 template<class T> inline Vector2T<T> normalize(const Vector2T<T>& A, const T Epsilon)
274 const T Length=length(A);
276 // I'm using <= here rather than only <, so that Epsilon==0 yields a meaningful test (e.g. if T==int).
277 if (Length<=Epsilon) throw DivisionByZeroE();
279 return A/Length;
282 /// Returns the normalized (unit length) version of A if length(A)>Epsilon, or the (0, 0, 0) vector otherwise.
283 template<class T> inline Vector2T<T> normalizeOr0(const Vector2T<T>& A, const T Epsilon=0)
285 const T Length=length(A);
287 return (Length>Epsilon) ? scale(A, T(1.0)/Length) : Vector2T<T>(0, 0, 0);
290 template<class T> inline std::string convertToString(const Vector2T<T>& A)
292 // From MSDN documentation: "digits10 returns the number of decimal digits that the type can represent without loss of precision."
293 // For floats, that's usually 6, for doubles, that's usually 15. However, we want to use the number of *significant* decimal digits here,
294 // see http://www.open-std.org/JTC1/sc22/wg21/docs/papers/2006/n2005.pdf for details.
295 const int sigdigits=std::numeric_limits<T>::digits10 + 3;
297 std::ostringstream out;
299 out << std::setprecision(sigdigits) << "(" << A.x << ", " << A.y << ")";
301 return out.str();
305 template<class T> inline std::ostream& operator << (std::ostream& os, const Vector2T<T>& A)
307 return os << "(" << A.x << ", " << A.y << ")";
311 typedef Vector2T<float> Vector2fT;
312 typedef Vector2T<double> Vector2dT;
314 #endif