1 // Copyright (C) 2002-2007 Nikolaus Gebhardt
2 // This file is part of the "Irrlicht Engine".
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
5 #ifndef __IRR_POINT_2D_H_INCLUDED__
6 #define __IRR_POINT_2D_H_INCLUDED__
16 //! 2d vector template class with lots of operators and methods.
22 vector2d() : X(0), Y(0) {}
23 vector2d(T nx
, T ny
) : X(nx
), Y(ny
) {}
24 vector2d(const vector2d
<T
>& other
) : X(other
.X
), Y(other
.Y
) {}
28 vector2d
<T
> operator-() const { return vector2d
<T
>(-X
, -Y
); }
30 vector2d
<T
>& operator=(const vector2d
<T
>& other
) { X
= other
.X
; Y
= other
.Y
; return *this; }
32 vector2d
<T
> operator+(const vector2d
<T
>& other
) const { return vector2d
<T
>(X
+ other
.X
, Y
+ other
.Y
); }
33 vector2d
<T
>& operator+=(const vector2d
<T
>& other
) { X
+=other
.X
; Y
+=other
.Y
; return *this; }
34 vector2d
<T
> operator+(const T v
) const { return vector2d
<T
>(X
+ v
, Y
+ v
); }
35 vector2d
<T
>& operator+=(const T v
) { X
+=v
; Y
+=v
; return *this; }
37 vector2d
<T
> operator-(const vector2d
<T
>& other
) const { return vector2d
<T
>(X
- other
.X
, Y
- other
.Y
); }
38 vector2d
<T
>& operator-=(const vector2d
<T
>& other
) { X
-=other
.X
; Y
-=other
.Y
; return *this; }
39 vector2d
<T
> operator-(const T v
) const { return vector2d
<T
>(X
- v
, Y
- v
); }
40 vector2d
<T
>& operator-=(const T v
) { X
-=v
; Y
-=v
; return *this; }
42 vector2d
<T
> operator*(const vector2d
<T
>& other
) const { return vector2d
<T
>(X
* other
.X
, Y
* other
.Y
); }
43 vector2d
<T
>& operator*=(const vector2d
<T
>& other
) { X
*=other
.X
; Y
*=other
.Y
; return *this; }
44 vector2d
<T
> operator*(const T v
) const { return vector2d
<T
>(X
* v
, Y
* v
); }
45 vector2d
<T
>& operator*=(const T v
) { X
*=v
; Y
*=v
; return *this; }
47 vector2d
<T
> operator/(const vector2d
<T
>& other
) const { return vector2d
<T
>(X
/ other
.X
, Y
/ other
.Y
); }
48 vector2d
<T
>& operator/=(const vector2d
<T
>& other
) { X
/=other
.X
; Y
/=other
.Y
; return *this; }
49 vector2d
<T
> operator/(const T v
) const { return vector2d
<T
>(X
/ v
, Y
/ v
); }
50 vector2d
<T
>& operator/=(const T v
) { X
/=v
; Y
/=v
; return *this; }
52 bool operator<=(const vector2d
<T
>&other
) const { return X
<=other
.X
&& Y
<=other
.Y
; }
53 bool operator>=(const vector2d
<T
>&other
) const { return X
>=other
.X
&& Y
>=other
.Y
; }
55 bool operator<(const vector2d
<T
>&other
) const { return X
<other
.X
&& Y
<other
.Y
; }
56 bool operator>(const vector2d
<T
>&other
) const { return X
>other
.X
&& Y
>other
.Y
; }
58 bool operator==(const vector2d
<T
>& other
) const { return other
.X
==X
&& other
.Y
==Y
; }
59 bool operator!=(const vector2d
<T
>& other
) const { return other
.X
!=X
|| other
.Y
!=Y
; }
63 //! returns if this vector equals the other one, taking floating point rounding errors into account
64 bool equals(const vector2d
<T
>& other
) const
66 return core::equals(X
, other
.X
) && core::equals(Y
, other
.Y
);
69 void set(T nx
, T ny
) {X
=nx
; Y
=ny
; }
70 void set(const vector2d
<T
>& p
) { X
=p
.X
; Y
=p
.Y
;}
72 //! Returns the length of the vector
73 //! \return Returns the length of the vector.
74 T
getLength() const { return (T
)sqrt((f64
)(X
*X
+ Y
*Y
)); }
76 //! Returns the squared length of this vector
77 /** This is useful because it is much faster than getLength(). */
78 T
getLengthSQ() const { return X
*X
+ Y
*Y
; }
80 //! Returns the dot product of this vector with another.
81 T
dotProduct(const vector2d
<T
>& other
) const
83 return X
*other
.X
+ Y
*other
.Y
;
86 //! Returns distance from another point. Here, the vector is interpreted
87 //! as a point in 2 dimensional space.
88 T
getDistanceFrom(const vector2d
<T
>& other
) const
90 return vector2d
<T
>(X
- other
.X
, Y
- other
.Y
).getLength();
93 //! Returns squared distance from another point. Here, the vector is
94 //! interpreted as a point in 2 dimensional space.
95 T
getDistanceFromSQ(const vector2d
<T
>& other
) const
97 return vector2d
<T
>(X
- other
.X
, Y
- other
.Y
).getLengthSQ();
100 //! rotates the point around a center by an amount of degrees.
101 void rotateBy(f64 degrees
, const vector2d
<T
>& center
)
103 degrees
*= DEGTORAD64
;
104 T cs
= (T
)cos(degrees
);
105 T sn
= (T
)sin(degrees
);
110 set(X
*cs
- Y
*sn
, X
*sn
+ Y
*cs
);
116 //! normalizes the vector.
117 vector2d
<T
>& normalize()
122 l
= core::reciprocal_squareroot ( (f32
)l
);
128 //! Calculates the angle of this vector in grad in the trigonometric sense.
129 //! This method has been suggested by Pr3t3nd3r.
130 //! \return Returns a value between 0 and 360.
131 f64
getAngleTrig() const
134 return Y
< 0 ? 270 : 90;
137 return X
< 0 ? 180 : 0;
141 return atan(Y
/X
) * RADTODEG64
;
143 return 180.0-atan(Y
/-X
) * RADTODEG64
;
146 return 360.0-atan(-Y
/X
) * RADTODEG64
;
148 return 180.0+atan(-Y
/-X
) * RADTODEG64
;
151 //! Calculates the angle of this vector in grad in the counter trigonometric sense.
152 //! \return Returns a value between 0 and 360.
153 inline f64
getAngle() const
155 if (Y
== 0) // corrected thanks to a suggestion by Jox
156 return X
< 0 ? 180 : 0;
158 return Y
< 0 ? 90 : 270;
160 f64 tmp
= Y
/ getLength();
161 tmp
= atan(sqrt(1 - tmp
*tmp
) / tmp
) * RADTODEG64
;
178 //! Calculates the angle between this vector and another one in grad.
179 //! \return Returns a value between 0 and 90.
180 inline f64
getAngleWith(const vector2d
<T
>& b
) const
182 f64 tmp
= X
*b
.X
+ Y
*b
.Y
;
187 tmp
= tmp
/ sqrt((f64
)((X
*X
+ Y
*Y
) * (b
.X
*b
.X
+ b
.Y
*b
.Y
)));
191 return atan(sqrt(1 - tmp
*tmp
) / tmp
) * RADTODEG64
;
194 //! Returns if this vector interpreted as a point is on a line between two other points.
195 /** It is assumed that the point is on the line. */
196 //! \param begin: Beginning vector to compare between.
197 //! \param end: Ending vector to compare between.
198 //! \return True if this vector is between begin and end. False if not.
199 bool isBetweenPoints(const vector2d
<T
>& begin
, const vector2d
<T
>& end
) const
201 T f
= (end
- begin
).getLengthSQ();
202 return getDistanceFromSQ(begin
) < f
&&
203 getDistanceFromSQ(end
) < f
;
206 //! returns interpolated vector
207 //! \param other: other vector to interpolate between
208 //! \param d: value between 0.0f and 1.0f.
209 vector2d
<T
> getInterpolated(const vector2d
<T
>& other
, f32 d
) const
212 return vector2d
<T
>(other
.X
*inv
+ X
*d
, other
.Y
*inv
+ Y
*d
);
215 //! Returns (quadratically) interpolated vector between this and the two given ones.
216 /** \param v2: second vector to interpolate with
217 \param v3: third vector to interpolate with
218 \param d: value between 0.0f and 1.0f. */
219 vector2d
<T
> getInterpolated_quadratic(const vector2d
<T
>& v2
, const vector2d
<T
>& v3
, const T d
) const
221 // this*(1-d)*(1-d) + 2 * v2 * (1-d) + v3 * d * d;
222 const T inv
= (T
) 1.0 - d
;
223 const T mul0
= inv
* inv
;
224 const T mul1
= (T
) 2.0 * d
* inv
;
225 const T mul2
= d
* d
;
227 return vector2d
<T
> ( X
* mul0
+ v2
.X
* mul1
+ v3
.X
* mul2
,
228 Y
* mul0
+ v2
.Y
* mul1
+ v3
.Y
* mul2
);
231 //! sets this vector to the linearly interpolated vector between a and b.
232 /** \param a: first vector to interpolate with
233 \param b: second vector to interpolate with
234 \param t: value between 0.0f and 1.0f. */
235 void interpolate(const vector2d
<T
>& a
, const vector2d
<T
>& b
, const f32 t
)
237 X
= b
.X
+ ( ( a
.X
- b
.X
) * t
);
238 Y
= b
.Y
+ ( ( a
.Y
- b
.Y
) * t
);
245 //! Typedef for f32 2d vector.
246 typedef vector2d
<f32
> vector2df
;
247 //! Typedef for integer 2d vector.
248 typedef vector2d
<s32
> vector2di
;
250 template<class S
, class T
> vector2d
<T
> operator*(const S scalar
, const vector2d
<T
>& vector
) { return vector
*scalar
; }
252 } // end namespace core
253 } // end namespace irr