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.
7 #ifndef CAFU_MATH_VECTOR2_HPP_INCLUDED
8 #define CAFU_MATH_VECTOR2_HPP_INCLUDED
19 /// This class represents a 2-dimensional vector.
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.
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
)
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
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
79 assert(typeid(T
)!=typeid(float));
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
89 assert(typeid(T
)!=typeid(double));
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.
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.
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
);
130 /// @name Group of (constructive) binary operators that do not modify their operands.
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.
137 bool operator == (const Vector2T
<T
>& B
) const
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.
147 bool operator != (const Vector2T
<T
>& B
) const
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
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
;
196 /// @name Group of operators that modify this vector.
199 /// Adds B to this vector.
200 Vector2T
<T
>& operator += (const Vector2T
<T
>& B
)
208 /// Subtracts B from this vector.
209 Vector2T
<T
>& operator -= (const Vector2T
<T
>& B
)
217 /// Scales this vector by s.
218 Vector2T
<T
>& operator *= (const T s
)
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.
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();
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
<< ")";
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
;