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