aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/include/vector2d.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/irrlicht-1.8.1/include/vector2d.h')
-rw-r--r--src/others/irrlicht-1.8.1/include/vector2d.h342
1 files changed, 342 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/include/vector2d.h b/src/others/irrlicht-1.8.1/include/vector2d.h
new file mode 100644
index 0000000..360da8f
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/include/vector2d.h
@@ -0,0 +1,342 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt
2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h
4
5#ifndef __IRR_POINT_2D_H_INCLUDED__
6#define __IRR_POINT_2D_H_INCLUDED__
7
8#include "irrMath.h"
9#include "dimension2d.h"
10
11namespace irr
12{
13namespace core
14{
15
16
17//! 2d vector template class with lots of operators and methods.
18/** As of Irrlicht 1.6, this class supercedes position2d, which should
19 be considered deprecated. */
20template <class T>
21class vector2d
22{
23public:
24 //! Default constructor (null vector)
25 vector2d() : X(0), Y(0) {}
26 //! Constructor with two different values
27 vector2d(T nx, T ny) : X(nx), Y(ny) {}
28 //! Constructor with the same value for both members
29 explicit vector2d(T n) : X(n), Y(n) {}
30 //! Copy constructor
31 vector2d(const vector2d<T>& other) : X(other.X), Y(other.Y) {}
32
33 vector2d(const dimension2d<T>& other) : X(other.Width), Y(other.Height) {}
34
35 // operators
36
37 vector2d<T> operator-() const { return vector2d<T>(-X, -Y); }
38
39 vector2d<T>& operator=(const vector2d<T>& other) { X = other.X; Y = other.Y; return *this; }
40
41 vector2d<T>& operator=(const dimension2d<T>& other) { X = other.Width; Y = other.Height; return *this; }
42
43 vector2d<T> operator+(const vector2d<T>& other) const { return vector2d<T>(X + other.X, Y + other.Y); }
44 vector2d<T> operator+(const dimension2d<T>& other) const { return vector2d<T>(X + other.Width, Y + other.Height); }
45 vector2d<T>& operator+=(const vector2d<T>& other) { X+=other.X; Y+=other.Y; return *this; }
46 vector2d<T> operator+(const T v) const { return vector2d<T>(X + v, Y + v); }
47 vector2d<T>& operator+=(const T v) { X+=v; Y+=v; return *this; }
48 vector2d<T>& operator+=(const dimension2d<T>& other) { X += other.Width; Y += other.Height; return *this; }
49
50 vector2d<T> operator-(const vector2d<T>& other) const { return vector2d<T>(X - other.X, Y - other.Y); }
51 vector2d<T> operator-(const dimension2d<T>& other) const { return vector2d<T>(X - other.Width, Y - other.Height); }
52 vector2d<T>& operator-=(const vector2d<T>& other) { X-=other.X; Y-=other.Y; return *this; }
53 vector2d<T> operator-(const T v) const { return vector2d<T>(X - v, Y - v); }
54 vector2d<T>& operator-=(const T v) { X-=v; Y-=v; return *this; }
55 vector2d<T>& operator-=(const dimension2d<T>& other) { X -= other.Width; Y -= other.Height; return *this; }
56
57 vector2d<T> operator*(const vector2d<T>& other) const { return vector2d<T>(X * other.X, Y * other.Y); }
58 vector2d<T>& operator*=(const vector2d<T>& other) { X*=other.X; Y*=other.Y; return *this; }
59 vector2d<T> operator*(const T v) const { return vector2d<T>(X * v, Y * v); }
60 vector2d<T>& operator*=(const T v) { X*=v; Y*=v; return *this; }
61
62 vector2d<T> operator/(const vector2d<T>& other) const { return vector2d<T>(X / other.X, Y / other.Y); }
63 vector2d<T>& operator/=(const vector2d<T>& other) { X/=other.X; Y/=other.Y; return *this; }
64 vector2d<T> operator/(const T v) const { return vector2d<T>(X / v, Y / v); }
65 vector2d<T>& operator/=(const T v) { X/=v; Y/=v; return *this; }
66
67 //! sort in order X, Y. Equality with rounding tolerance.
68 bool operator<=(const vector2d<T>&other) const
69 {
70 return (X<other.X || core::equals(X, other.X)) ||
71 (core::equals(X, other.X) && (Y<other.Y || core::equals(Y, other.Y)));
72 }
73
74 //! sort in order X, Y. Equality with rounding tolerance.
75 bool operator>=(const vector2d<T>&other) const
76 {
77 return (X>other.X || core::equals(X, other.X)) ||
78 (core::equals(X, other.X) && (Y>other.Y || core::equals(Y, other.Y)));
79 }
80
81 //! sort in order X, Y. Difference must be above rounding tolerance.
82 bool operator<(const vector2d<T>&other) const
83 {
84 return (X<other.X && !core::equals(X, other.X)) ||
85 (core::equals(X, other.X) && Y<other.Y && !core::equals(Y, other.Y));
86 }
87
88 //! sort in order X, Y. Difference must be above rounding tolerance.
89 bool operator>(const vector2d<T>&other) const
90 {
91 return (X>other.X && !core::equals(X, other.X)) ||
92 (core::equals(X, other.X) && Y>other.Y && !core::equals(Y, other.Y));
93 }
94
95 bool operator==(const vector2d<T>& other) const { return equals(other); }
96 bool operator!=(const vector2d<T>& other) const { return !equals(other); }
97
98 // functions
99
100 //! Checks if this vector equals the other one.
101 /** Takes floating point rounding errors into account.
102 \param other Vector to compare with.
103 \return True if the two vector are (almost) equal, else false. */
104 bool equals(const vector2d<T>& other) const
105 {
106 return core::equals(X, other.X) && core::equals(Y, other.Y);
107 }
108
109 vector2d<T>& set(T nx, T ny) {X=nx; Y=ny; return *this; }
110 vector2d<T>& set(const vector2d<T>& p) { X=p.X; Y=p.Y; return *this; }
111
112 //! Gets the length of the vector.
113 /** \return The length of the vector. */
114 T getLength() const { return core::squareroot( X*X + Y*Y ); }
115
116 //! Get the squared length of this vector
117 /** This is useful because it is much faster than getLength().
118 \return The squared length of the vector. */
119 T getLengthSQ() const { return X*X + Y*Y; }
120
121 //! Get the dot product of this vector with another.
122 /** \param other Other vector to take dot product with.
123 \return The dot product of the two vectors. */
124 T dotProduct(const vector2d<T>& other) const
125 {
126 return X*other.X + Y*other.Y;
127 }
128
129 //! Gets distance from another point.
130 /** Here, the vector is interpreted as a point in 2-dimensional space.
131 \param other Other vector to measure from.
132 \return Distance from other point. */
133 T getDistanceFrom(const vector2d<T>& other) const
134 {
135 return vector2d<T>(X - other.X, Y - other.Y).getLength();
136 }
137
138 //! Returns squared distance from another point.
139 /** Here, the vector is interpreted as a point in 2-dimensional space.
140 \param other Other vector to measure from.
141 \return Squared distance from other point. */
142 T getDistanceFromSQ(const vector2d<T>& other) const
143 {
144 return vector2d<T>(X - other.X, Y - other.Y).getLengthSQ();
145 }
146
147 //! rotates the point anticlockwise around a center by an amount of degrees.
148 /** \param degrees Amount of degrees to rotate by, anticlockwise.
149 \param center Rotation center.
150 \return This vector after transformation. */
151 vector2d<T>& rotateBy(f64 degrees, const vector2d<T>& center=vector2d<T>())
152 {
153 degrees *= DEGTORAD64;
154 const f64 cs = cos(degrees);
155 const f64 sn = sin(degrees);
156
157 X -= center.X;
158 Y -= center.Y;
159
160 set((T)(X*cs - Y*sn), (T)(X*sn + Y*cs));
161
162 X += center.X;
163 Y += center.Y;
164 return *this;
165 }
166
167 //! Normalize the vector.
168 /** The null vector is left untouched.
169 \return Reference to this vector, after normalization. */
170 vector2d<T>& normalize()
171 {
172 f32 length = (f32)(X*X + Y*Y);
173 if ( length == 0 )
174 return *this;
175 length = core::reciprocal_squareroot ( length );
176 X = (T)(X * length);
177 Y = (T)(Y * length);
178 return *this;
179 }
180
181 //! Calculates the angle of this vector in degrees in the trigonometric sense.
182 /** 0 is to the right (3 o'clock), values increase counter-clockwise.
183 This method has been suggested by Pr3t3nd3r.
184 \return Returns a value between 0 and 360. */
185 f64 getAngleTrig() const
186 {
187 if (Y == 0)
188 return X < 0 ? 180 : 0;
189 else
190 if (X == 0)
191 return Y < 0 ? 270 : 90;
192
193 if ( Y > 0)
194 if (X > 0)
195 return atan((irr::f64)Y/(irr::f64)X) * RADTODEG64;
196 else
197 return 180.0-atan((irr::f64)Y/-(irr::f64)X) * RADTODEG64;
198 else
199 if (X > 0)
200 return 360.0-atan(-(irr::f64)Y/(irr::f64)X) * RADTODEG64;
201 else
202 return 180.0+atan(-(irr::f64)Y/-(irr::f64)X) * RADTODEG64;
203 }
204
205 //! Calculates the angle of this vector in degrees in the counter trigonometric sense.
206 /** 0 is to the right (3 o'clock), values increase clockwise.
207 \return Returns a value between 0 and 360. */
208 inline f64 getAngle() const
209 {
210 if (Y == 0) // corrected thanks to a suggestion by Jox
211 return X < 0 ? 180 : 0;
212 else if (X == 0)
213 return Y < 0 ? 90 : 270;
214
215 // don't use getLength here to avoid precision loss with s32 vectors
216 // avoid floating-point trouble as sqrt(y*y) is occasionally larger than y, so clamp
217 const f64 tmp = core::clamp(Y / sqrt((f64)(X*X + Y*Y)), -1.0, 1.0);
218 const f64 angle = atan( core::squareroot(1 - tmp*tmp) / tmp) * RADTODEG64;
219
220 if (X>0 && Y>0)
221 return angle + 270;
222 else
223 if (X>0 && Y<0)
224 return angle + 90;
225 else
226 if (X<0 && Y<0)
227 return 90 - angle;
228 else
229 if (X<0 && Y>0)
230 return 270 - angle;
231
232 return angle;
233 }
234
235 //! Calculates the angle between this vector and another one in degree.
236 /** \param b Other vector to test with.
237 \return Returns a value between 0 and 90. */
238 inline f64 getAngleWith(const vector2d<T>& b) const
239 {
240 f64 tmp = (f64)(X*b.X + Y*b.Y);
241
242 if (tmp == 0.0)
243 return 90.0;
244
245 tmp = tmp / core::squareroot((f64)((X*X + Y*Y) * (b.X*b.X + b.Y*b.Y)));
246 if (tmp < 0.0)
247 tmp = -tmp;
248 if ( tmp > 1.0 ) // avoid floating-point trouble
249 tmp = 1.0;
250
251 return atan(sqrt(1 - tmp*tmp) / tmp) * RADTODEG64;
252 }
253
254 //! Returns if this vector interpreted as a point is on a line between two other points.
255 /** It is assumed that the point is on the line.
256 \param begin Beginning vector to compare between.
257 \param end Ending vector to compare between.
258 \return True if this vector is between begin and end, false if not. */
259 bool isBetweenPoints(const vector2d<T>& begin, const vector2d<T>& end) const
260 {
261 if (begin.X != end.X)
262 {
263 return ((begin.X <= X && X <= end.X) ||
264 (begin.X >= X && X >= end.X));
265 }
266 else
267 {
268 return ((begin.Y <= Y && Y <= end.Y) ||
269 (begin.Y >= Y && Y >= end.Y));
270 }
271 }
272
273 //! Creates an interpolated vector between this vector and another vector.
274 /** \param other The other vector to interpolate with.
275 \param d Interpolation value between 0.0f (all the other vector) and 1.0f (all this vector).
276 Note that this is the opposite direction of interpolation to getInterpolated_quadratic()
277 \return An interpolated vector. This vector is not modified. */
278 vector2d<T> getInterpolated(const vector2d<T>& other, f64 d) const
279 {
280 f64 inv = 1.0f - d;
281 return vector2d<T>((T)(other.X*inv + X*d), (T)(other.Y*inv + Y*d));
282 }
283
284 //! Creates a quadratically interpolated vector between this and two other vectors.
285 /** \param v2 Second vector to interpolate with.
286 \param v3 Third vector to interpolate with (maximum at 1.0f)
287 \param d Interpolation value between 0.0f (all this vector) and 1.0f (all the 3rd vector).
288 Note that this is the opposite direction of interpolation to getInterpolated() and interpolate()
289 \return An interpolated vector. This vector is not modified. */
290 vector2d<T> getInterpolated_quadratic(const vector2d<T>& v2, const vector2d<T>& v3, f64 d) const
291 {
292 // this*(1-d)*(1-d) + 2 * v2 * (1-d) + v3 * d * d;
293 const f64 inv = 1.0f - d;
294 const f64 mul0 = inv * inv;
295 const f64 mul1 = 2.0f * d * inv;
296 const f64 mul2 = d * d;
297
298 return vector2d<T> ( (T)(X * mul0 + v2.X * mul1 + v3.X * mul2),
299 (T)(Y * mul0 + v2.Y * mul1 + v3.Y * mul2));
300 }
301
302 //! Sets this vector to the linearly interpolated vector between a and b.
303 /** \param a first vector to interpolate with, maximum at 1.0f
304 \param b second vector to interpolate with, maximum at 0.0f
305 \param d Interpolation value between 0.0f (all vector b) and 1.0f (all vector a)
306 Note that this is the opposite direction of interpolation to getInterpolated_quadratic()
307 */
308 vector2d<T>& interpolate(const vector2d<T>& a, const vector2d<T>& b, f64 d)
309 {
310 X = (T)((f64)b.X + ( ( a.X - b.X ) * d ));
311 Y = (T)((f64)b.Y + ( ( a.Y - b.Y ) * d ));
312 return *this;
313 }
314
315 //! X coordinate of vector.
316 T X;
317
318 //! Y coordinate of vector.
319 T Y;
320};
321
322 //! Typedef for f32 2d vector.
323 typedef vector2d<f32> vector2df;
324
325 //! Typedef for integer 2d vector.
326 typedef vector2d<s32> vector2di;
327
328 template<class S, class T>
329 vector2d<T> operator*(const S scalar, const vector2d<T>& vector) { return vector*scalar; }
330
331 // These methods are declared in dimension2d, but need definitions of vector2d
332 template<class T>
333 dimension2d<T>::dimension2d(const vector2d<T>& other) : Width(other.X), Height(other.Y) { }
334
335 template<class T>
336 bool dimension2d<T>::operator==(const vector2d<T>& other) const { return Width == other.X && Height == other.Y; }
337
338} // end namespace core
339} // end namespace irr
340
341#endif
342