1 /* Copyright 2011 Jukka Jyl�nki
2
3    Licensed under the Apache License, Version 2.0 (the "License");
4    you may not use this file except in compliance with the License.
5    You may obtain a copy of the License at
6
7        http://www.apache.org/licenses/LICENSE-2.0
8
9    Unless required by applicable law or agreed to in writing, software
10    distributed under the License is distributed on an "AS IS" BASIS,
11    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12    See the License for the specific language governing permissions and
13    limitations under the License. */
14
15 /** @file float2.h
16         @author Jukka Jyl�nki
17         @brief A 2D (x,y) ordered pair. */
18 #pragma once
19
20 #ifdef MATH_ENABLE_STL_SUPPORT
21 #include <string>
22 #include <vector>
23 #endif
24
25 #include "Math/MathFwd.h"
26
27 #ifdef MATH_QT_INTEROP
28 #include <QVector2D>
29 #endif
30
31 #ifdef MATH_OGRE_INTEROP
32 #include <OgreVector2.h>
33 #endif
34
35 MATH_BEGIN_NAMESPACE
36
37 /// A vector of form (x,y).
38 class float2
39 {
40 public:
41         enum
42         {
43                 /// Specifies the number of elements in this vector.
44                 Size = 2
45         };
46         /// The x component.
47         /** A float2 is 8 bytes in size. This element lies in the memory offsets 0-3 of this class. */
48         float x;
49         /// The y component. [similarOverload: x]
50         /** This element is packed to the memory offsets 4-7 of this class. */
51         float y;
52
53         /// The default constructor does not initialize any members of this class.
54         /** This means that the values of the members x and y are both undefined after creating a new float2 using 
55                 this default constructor. Remember to assign to them before use.
56                 @see x, y. */
57         float2() {}
58
59         /// The float2 copy constructor.
60         /** The copy constructor is a standard default copy-ctor, but it is explicitly written to be able to automatically pick up 
61                 this function for script bindings. */
62         float2(const float2 &rhs) { x = rhs.xy = rhs.y; }
63
64         /// Constructs a new float2 with the value (x, y).
65         /** @see x, y. */
66         float2(float xfloat y);
67
68         /// Constructs a new float2 with the value (scalar, scalar).
69         /** @see x, y. */
70         explicit float2(float scalar);
71
72         /// Constructs this float2 from a C array, to the value (data[0], data[1]).
73         /** @param data An array containing two elements for x and y. This pointer may not be null. */
74         explicit float2(const float *data);
75
76         /// Casts this float2 to a C array. 
77         /** This function does not allocate new memory or make a copy of this float2. This function simply
78                 returns a C pointer view to this data structure. Use ptr()[0] to access the x component of this float2
79                 and ptr()[1] to access the y component.
80                 @note Since the returned pointer points to this class, do not dereference the pointer after this
81                         float2 has been deleted. You should never store a copy of the returned pointer.
82                 @note This function is provided for compatibility with other APIs which require raw C pointer access
83                         to vectors. Avoid using this function in general, and instead always use the operator []
84                         or the At() function to access the elements of this vector by index.
85                 @return A pointer to the first float element of this class. The data is contiguous in memory.
86                 @see operator [](), At(). */
87         float *ptr();
88         const float *ptr() const;
89
90         /// Accesses an element of this vector using array notation.
91         /** @param index The element to get. Pass in 0 for x and 1 for y. 
92                 @note If you have a non-const instance of this class, you can use this notation to set the elements of 
93                         this vector as well, e.g. vec[1] = 10.f; would set the y-component of this vector.
94                 @see ptr(), At(). */
95         float &operator [](int index) { return At(index); }
96         CONST_WIN32 float operator [](int index) const return At(index); }
97
98         /// Accesses an element of this vector.
99         /** @param index The element to get. Pass in 0 for x and 1 for y.
100                 @note If you have a non-const instance of this class, you can use this notation to set the elements of 
101                         this vector as well, e.g. vec.At(1) = 10.f; would set the y-component of this vector.
102                 @see ptr(), operator [](). */
103         float &At(int index);
104         CONST_WIN32 float At(int index) const;
105
106         /// Adds two vectors. [indexTitle: operators +,-,*,/]
107         /** This function is identical to the member function Add().
108                 @return float2(x + v.x, y + v.y); */
109         float2 operator +(const float2 &v) const;
110         /// Performs an unary negation of this vector. [similarOverload: operator+] [hideIndex]
111         /** This function is identical to the member function Neg().
112                 @return float2(-x, -y). */
113         float2 operator -() const;
114         /// Subtracts the given vector from this vector. [similarOverload: operator+] [hideIndex]
115         /** This function is identical to the member function Sub().
116                 @return float2(x - v.x, y - v.y); */
117         float2 operator -(const float2 &v) const;
118         /// Multiplies this vector by a scalar. [similarOverload: operator+] [hideIndex]
119         /** This function is identical to the member function Mul().
120                 @return float2(x * scalar, y * scalar); */
121         float2 operator *(float scalar) const;
122         /// Divides this vector by a scalar. [similarOverload: operator+] [hideIndex]
123         /** This function is identical to the member function Div().
124                 @return float2(x / scalar, y / scalar); */
125         float2 operator /(float scalar) const;
126
127         /// Adds a vector to this vector, in-place. [indexTitle: operators +=,-=,*=,/=]
128         /** @return A reference to this. */
129         float2 &operator +=(const float2 &v);
130         /// Subtracts a vector from this vector, in-place. [similarOverload: operator+=] [hideIndex]
131         /** @return A reference to this. */
132         float2 &operator -=(const float2 &v);
133         /// Multiplies this vector by a scalar, in-place. [similarOverload: operator+=] [hideIndex]
134         /** @return A reference to this. */
135         float2 &operator *=(float scalar);
136         /// Divides this vector by a scalar, in-place. [similarOverload: operator+=] [hideIndex]
137         /** @return A reference to this. */
138         float2 &operator /=(float scalar);
139
140 #ifdef MATH_ENABLE_UNCOMMON_OPERATIONS
141         float2 operator *(const float2 &vector) const return this->Mul(vector); }
142         float2 operator /(const float2 &vector) const return this->Div(vector); }
143         float2 &operator *=(const float2 &vector) { *this = this->Mul(vector); return *this; }
144         float2 &operator /=(const float2 &vector) { *this = this->Div(vector); return *this; }
145 #endif
146
147         /// Adds a vector to this vector. [IndexTitle: Add/Sub/Mul/Div]
148         /// @return (x+v.x, y+v.y).
149         float2 Add(const float2 &v) const return *this + v; }
150
151         /// Adds the vector (s,s) to this vector.
152         /// @note Mathematically, the addition of a vector and scalar is not defined in linear space structures, 
153         ///      but this function is provided here for syntactical convenience.
154         /// @return (x+s, y+s).
155         float2 Add(float s) const;
156
157         /// Subtracts a vector from this vector. [similarOverload: Add] [hideIndex]
158         /// @return (x-v.x, y-v.y).
159         float2 Sub(const float2 &v) const return *this - v; }
160
161         /// Subtracts the vector (s,s) from this vector. [similarOverload: Add] [hideIndex]
162         /// @note Mathematically, the subtraction of a vector by a scalar is not defined in linear space structures, 
163         ///      but this function is provided here for syntactical convenience.
164         /// @return (x-s, y-s).
165         float2 Sub(float s) const;
166
167         /// Subtracts this vector from the vector (s,s). [similarOverload: Add] [hideIndex]
168         /// @note Mathematically, the subtraction of a scalar by a vector is not defined in linear space structures, 
169         ///      but this function is provided here for syntactical convenience.
170         /// @return (s-x, s-y).
171         float2 SubLeft(float s) const;
172
173         /// Multiplies this vector by a vector, element-wise. [similarOverload: Add] [hideIndex]
174         /// @note Mathematically, the multiplication of two vectors is not defined in linear space structures, 
175         ///      but this function is provided here for syntactical convenience.
176         /// @return (x*v.x, y*v.y).
177         float2 Mul(const float2 &v) const;
178
179         /// Multiplies this vector by a scalar. [similarOverload: Add] [hideIndex]
180         /// @return (x*s, y*s).
181         float2 Mul(float s) const return *this * s; }
182
183         /// Divides this vector by a vector, element-wise. [similarOverload: Add] [hideIndex]
184         /// @note Mathematically, the division of two vectors is not defined in linear space structures, 
185         ///      but this function is provided here for syntactical convenience.
186         /// @return (x/v.x, y/v.y).
187         float2 Div(const float2 &v) const;
188
189         /// Divides this vector by a scalar. [similarOverload: Add] [hideIndex]
190         /// @return (x/s, y/s).
191         float2 Div(float s) const return *this / s; }
192         
193         /// Divides the vector (s,s) by this vector, element-wise. [similarOverload: Add] [hideIndex]
194         /// @note Mathematically, the division of a scalar by a vector is not defined in linear space structures, 
195         ///      but this function is provided here for syntactical convenience.
196         /// @return (s/x, s/y).
197         float2 DivLeft(float s) const;
198
199         /// Performs a 2D swizzled access to this vector. [indexTitle: xx/xy/yx/yy]
200         float2 xx() const return float2(x,x); }
201         float2 xy() const return float2(x,y); } ///< [similarOverload: xx] [hideIndex]
202         float2 yx() const return float2(y,x); } ///< [similarOverload: xx] [hideIndex]
203         float2 yy() const return float2(y,y); } ///< [similarOverload: xx] [hideIndex]
204
205         /// Performs a swizzled access to this vector.
206         /** For example, Swizzled(2,1,0) return float3(z,y,x). Swizzled(2,2,2,2) returns float4(z,z,z,z).
207                 @param i Chooses the element of this vector to pick for the x value of the returned vector, in the range [0, 2].
208                 @param j Chooses the element of this vector to pick for the y value of the returned vector, in the range [0, 2].
209                 @param k Chooses the element of this vector to pick for the z value of the returned vector, in the range [0, 2].
210                 @param l Chooses the element of this vector to pick for the w value of the returned vector, in the range [0, 2]. */             
211         float2 Swizzled(int i, int j) const;
212         float3 Swizzled(int i, int j, int k) const;
213         float4 Swizzled(int i, int j, int k, int l) const;
214
215         /// Generates a new float2 by filling its entries by the given scalar.
216         /** @see float2::float2(float scalar), SetFromScalar(). */
217         static float2 FromScalar(float scalar);
218
219         /// Fills each entry of this float2 by the given scalar.
220         /** @see float2::float2(float scalar), FromScalar(). */
221         void SetFromScalar(float scalar);
222
223         /// Sets all elements of this vector.
224         /** @see x, y, At().. */
225         void Set(float xfloat y);
226
227         /// Computes the length of this vector.
228         /** @return Sqrt(x*x + y*y).
229                 @see LengthSq(), Distance(), DistanceSq(). */
230         float Length() const;
231
232         /// Computes the squared length of this vector. 
233         /** Calling this function is faster than calling Length(), since this function avoids computing a square root.
234                 If you only need to compare lengths to each other, but are not interested in the actual length values, 
235                 you can compare by using LengthSq(), instead of Length(), since Sqrt() is an order-preserving
236                 (monotonous and non-decreasing) function.
237                 @return x*x + y*y.
238                 @see LengthSq(), Distance(), DistanceSq(). */
239         float LengthSq() const;
240
241         /// Normalizes this float2.
242         /** In the case of failure, this vector is set to (1, 0), so calling this function will never result in an 
243                 unnormalized vector.
244                 @note If this function fails to normalize the vector, no error message is printed, the vector is set to (1,0) and 
245                         an error code 0 is returned. This is different than the behavior of the Normalized() function, which prints an 
246                         error if normalization fails. 
247                 @note This function operates in-place.
248                 @return The old length of this vector, or 0 if normalization failed. 
249                 @see Normalized(). */
250         float Normalize();
251
252         /// Returns a normalized copy of this vector.
253         /** @note If the vector is zero and cannot be normalized, the vector (1, 0) is returned, and an error message is printed.
254                         If you do not want to generate an error message on failure, but want to handle the failure yourself, use the
255                         Normalize() function instead.
256                 @see Normalize(). */
257         float2 Normalized() const;
258
259         /// Scales this vector so that its new length is as given.
260         /** Calling this function is effectively the same as normalizing the vector first and then multiplying by newLength.
261                 In the case of failure, this vector is set to (newLength, 0), so calling this function will never result in an
262                 unnormalized vector.
263                 @note This function operates in-place.
264                 @return The old length of this vector. If this function returns 0, the scaling failed, and this vector is arbitrarily
265                         reset to (newLength, 0). In case of failure, no error message is generated. You are expected to handle the failure 
266                         yourself.
267                 @see ScaledToLength(). */
268         float ScaleToLength(float newLength);
269
270         /// Returns a scaled copy of this vector which has its new length as given.
271         /** This function assumes the length of this vector is not zero. In the case of failure, an error message is printed,
272                 and the vector (newLength, 0) is returned.
273                 @see ScaleToLength(). */
274         float2 ScaledToLength(float newLength) const;
275
276         /// Tests if the length of this vector is one, up to the given epsilon.
277         /** @see IsZero(), IsFinite(), IsPerpendicular(). */
278         bool IsNormalized(float epsilonSq = 1e-6f) const;
279
280         /// Tests if this is the null vector, up to the given epsilon.
281         /** @see IsNormalized(), IsFinite(), IsPerpendicular(). */
282         bool IsZero(float epsilonSq = 1e-6f) const;
283
284         /// Tests if this vector contains valid finite elements.
285         /** @see IsNormalized(), IsZero(), IsPerpendicular(). */
286         bool IsFinite() const;
287
288         /// Tests if two vectors are perpendicular to each other.
289         /** @see IsNormalized(), IsZero(), IsPerpendicular(), Equals(). */
290         bool IsPerpendicular(const float2 &other, float epsilon = 1e-3f) const;
291
292         /// Tests if two vectors are equal, up to the given epsilon.
293         /** @see IsPerpendicular(). */
294         bool Equals(const float2 &other, float epsilon = 1e-3f) const;
295         bool Equals(float xfloat yfloat epsilon = 1e-3f) const;
296
297 #ifdef MATH_ENABLE_STL_SUPPORT
298         /// Returns "(x, y)".
299         std::string ToString() const;
300
301         /// Returns "x y". This is the preferred format for the float2 if it has to be serialized to a string for machine transfer.
302         std::string SerializeToString() const;
303 #endif
304
305         /// Parses a string that is of form "x,y" or "(x,y)" or "(x;y)" or "x y" to a new float2.
306         static float2 FromString(const char *str);
307 #ifdef MATH_ENABLE_STL_SUPPORT
308         static float2 FromString(const std::string &str) { return FromString(str.c_str()); }
309 #endif
310
311         /// @return x + y.
312         float SumOfElements() const;
313         /// @return x * y.
314         float ProductOfElements() const;
315         /// @return (x+y)/2.
316         float AverageOfElements() const;
317         /// @return Min(x, y).
318         /** @see MinElementIndex(). */
319         float MinElement() const;
320         /// Returns the index that has the smallest value in this vector.
321         /** @see MinElement(). */
322         int MinElementIndex() const;
323         /// @return Max(x, y).
324         /** @see MaxElementIndex(). */
325         float MaxElement() const;
326         /// Returns the index that has the smallest value in this vector.
327         /** @see MaxElement(). */
328         int MaxElementIndex() const;
329         /// Takes the element-wise absolute value of this vector.
330         /** @return float2(|x|, |y|).
331                 @see Neg(). */
332         float2 Abs() const;
333         /// Returns a copy of this vector with each element negated.
334         /** This function returns a new vector where each element x of the original vector is replaced by the value -x.
335                 @return float2(-x, -y).
336                 @see Abs(). */
337         float2 Neg() const;
338         /// Computes the element-wise reciprocal of this vector.
339         /** This function returns a new vector where each element x of the original vector is replaced by the value 1/x.
340                 @return float2(1/x, 1/y). */
341         float2 Recip() const;
342         /// Returns an element-wise minimum of this and the vector (ceil, ceil, ceil).
343         /** Each element that is larger than ceil is replaced by ceil. */
344         float2 Min(float ceil) const;
345         /// Returns an element-wise minimum of this and the given vector.
346         /** Each element that is larger than ceil is replaced by ceil.
347                 @see Max(), Clamp(). */
348         float2 Min(const float2 &ceil) const;
349         /// Returns an element-wise maximum of this and the vector (floor, floor, floor).
350         /** Each element that is smaller than floor is replaced by floor. */
351         float2 Max(float floor) const;
352         /// Returns an element-wise maximum of this and the given vector.
353         /** Each element that is smaller than floor is replaced by floor.
354                 @see Min(), Clamp(). */
355         float2 Max(const float2 &floor) const;
356         /// Returns a vector that has floor <= this[i] <= ceil for each element.
357         float2 Clamp(float floor, float ceil) const;
358         /// Limits each element of this vector between the corresponding elements in floor and ceil.
359         /** @see Min(), Max(), Clamp01(). */
360         float2 Clamp(const float2 &floor, const float2 &ceil) const;
361         /// Limits each element of this vector in the range [0, 1].
362         /** @see Min(), Max(), Clamp(). */
363         float2 Clamp01() const;
364
365         /// Computes the distance between this and the given float2.
366         /** @see DistanceSq(), Length(), LengthSq(). */
367         float Distance(const float2 &point) const;
368
369         /// Computes the squared distance between this and the given point.
370         /** Calling this function is faster than calling Distance(), since this function avoids computing a square root.
371                 If you only need to compare distances to each other, but are not interested in the actual distance values, 
372                 you can compare by using DistanceSq(), instead of Distance(), since Sqrt() is an order-preserving
373                 (monotonous and non-decreasing) function.
374                 @see Distance(), Length(), LengthSq(). */
375         float DistanceSq(const float2 &point) const;
376
377         /// Computes the dot product of this and the given vector.
378         /** The dot product has a geometric interpretation of measuring how close two direction vectors are to pointing
379                 in the same direction, computing angles between vectors, or the length of a projection of one vector to another.
380                 @return x*v.x + y*v.y.
381                 @see AngleBetween(), ProjectTo(), ProjectToNorm(), Perp(), PerpDot(). */
382         float Dot(const float2 &v) const;
383
384         /// Returns this vector with the "perp" operator applied to it.
385         /** The perp operator rotates a vector 90 degrees ccw (around the "z axis"), i.e.
386                 for a 2D vector (x,y), this function returns the vector (-y, x).
387                 @note This function is identical to Rotated90CCW().
388                 @return (-y, x). The returned vector is perpendicular to this vector.
389                 @see PerpDot(), Rotated90CCW(). */
390         float2 Perp() const;
391
392         /// Computes the perp-dot product of this and the given float2 in the order this^perp <dot> rhs.
393         /** @see Dot(), Perp(). */
394         float PerpDot(const float2 &rhs) const;
395
396         /// Rotates this vector 90 degrees clock-wise.
397         /** This rotation is interpreted in a coordinate system on a plane where +x extends to the right, and +y extends upwards.
398                 @see Perp(), Rotated90CW(), Rotate90CCW(), Rotated90CCW(). */
399         void Rotate90CW();
400
401         /// Returns a vector that is perpendicular to this vector (rotated 90 degrees clock-wise).
402         /** @note This function is identical to Perp().
403                 @see Perp(), Rotate90CW(), Rotate90CCW(), Rotated90CCW(). */
404         float2 Rotated90CW() const;
405
406         /// Rotates this vector 90 degrees counterclock-wise .
407         /// This is in a coordinate system on a plane where +x extends to the right, and +y extends upwards.
408         /** @see Perp(), Rotate90CW(), Rotated90CW(), Rotated90CCW(). */
409         void Rotate90CCW();
410
411         /// Returns a vector that is perpendicular to this vector (rotated 90 degrees counter-clock-wise).
412         /** @see Perp(), Rotate90CW(), Rotated90CW(), Rotate90CCW(). */
413         float2 Rotated90CCW() const;
414
415         /// Returns this vector reflected about a plane with the given normal.
416         /** By convention, both this and the reflected vector point away from the plane with the given normal
417                 @see Refract(). */
418         float2 Reflect(const float2 &normal) const;
419
420         /// Refracts this vector about a plane with the given normal. 
421         /** By convention, the this vector points towards the plane, and the returned vector points away from the plane.
422                 When the ray is going from a denser material to a lighter one, total internal reflection can occur.
423                 In this case, this function will just return a reflected vector from a call to Reflect().
424                 @param normal Specifies the plane normal direction
425                 @param negativeSideRefractionIndex The refraction index of the material we are exiting.
426                 @param positiveSideRefractionIndex The refraction index of the material we are entering.
427                 @see Reflect(). */
428         float2 Refract(const float2 &normal, float negativeSideRefractionIndex, float positiveSideRefractionIndex) const;
429
430         /// Projects this vector onto the given unnormalized direction vector.
431         /** @param direction The direction vector to project this vector onto. This function will normalize this
432                         vector, so you can pass in an unnormalized vector.
433                 @see ProjectToNorm(). */
434         float2 ProjectTo(const float2 &direction) const;
435
436         /// Projects this vector onto the given normalized direction vector.
437         /** @param direction The vector to project onto. This vector must be normalized.
438                 @see ProjectTo(). */
439         float2 ProjectToNorm(const float2 &direction) const;
440
441         /// Returns the angle between this vector and the specified vector, in radians.
442         /** @note This function takes into account that this vector or the other vector can be unnormalized, and normalizes the computations.
443                         If you are computing the angle between two normalized vectors, it is better to use AngleBetweenNorm().
444                 @see AngleBetweenNorm(). */             
445         float AngleBetween(const float2 &other) const;
446
447         /// Returns the angle between this vector and the specified normalized vector, in radians.
448         /** @param normalizedVector The direction vector to compute the angle against. This vector must be normalized.
449                 @note This vector must be normalized to call this function.
450                 @see AngleBetween(). */
451         float AngleBetweenNorm(const float2 &normalizedVector) const;
452
453         /// Breaks this vector down into parallel and perpendicular components with respect to the given direction.
454         /** @param direction The direction the decomposition is to be computed. This vector must be normalized.
455                 @param outParallel [out] Receives the part of this vector that is parallel to the given direction vector.
456                 @param outPerpendicular [out] Receives the part of this vector that is perpendicular to the given direction vector. */
457         void Decompose(const float2 &direction, float2 &outParallel, float2 &outPerpendicular) const;
458
459         /// Linearly interpolates between this and the vector b.
460         /** @param t The interpolation weight, in the range [0, 1].
461                 @return Lerp(b, 0) returns this vector, Lerp(b, 1) returns the vector b.
462                         Lerp(b, 0.5) returns the vector half-way in between the two vectors, and so on.
463                         Lerp(b, t) returns (1-t)*this + t*b. */
464         float2 Lerp(const float2 &b, float t) const;
465         /// This function is the same as calling a.Lerp(b, t).
466         static float2 Lerp(const float2 &a, const float2 &b, float t);
467
468         /// Makes the given vectors linearly independent.
469         /** This function directly follows the Gram-Schmidt procedure on the input vectors.
470                 The vector a is kept unmodified, and vector b is modified to be perpendicular to a.
471                 @note If any of the input vectors is zero, then the resulting set of vectors cannot be made orthogonal.
472                 @see AreOrthogonal(), Orthonormalize(), AreOrthonormal(). */
473         static void Orthogonalize(const float2 &a, float2 &b);
474
475         /// Returns true if the given vectors are orthogonal to each other.
476         /** @see Orthogonalize(), Orthonormalize(), AreOrthonormal(). */
477         static bool AreOrthogonal(const float2 &a, const float2 &b, float epsilon = 1e-3f);
478
479         /// Makes the given vectors linearly independent and normalized in length.
480         /** This function directly follows the Gram-Schmidt procedure on the input vectors.
481                 The vector a is first normalized, and vector b is modified to be perpendicular to a, and also normalized.
482                 @note If either of the input vectors is zero, then the resulting set of vectors cannot be made orthonormal.
483                 @see Orthogonalize(), AreOrthogonal(), AreOrthonormal(). */
484         static void Orthonormalize(float2 &a, float2 &b);
485
486         /// Tests if the triangle a->b->c is oriented counter-clockwise.
487         /** Returns true if the triangle a->b->c is oriented counter-clockwise, when viewed in the XY-plane
488                 where x spans to the right and y spans up.
489                 Another way to think of this is that this function returns true, if the point C lies to the left
490                 of the directed line AB. */
491         static bool OrientedCCW(const float2 &a, const float2 &b, const float2 &c);
492
493 #ifdef MATH_ENABLE_STL_SUPPORT
494         /// Computes the 2D convex hull of the given point set.
495         /* @see ConvexHullInPlace */
496         static void ConvexHull(const float2 *pointArray, int numPoints, std::vector<float2> &outConvexHull);
497
498         /// Computes the 2D convex hull of the given point set, in-place.
499         /** This version of the algorithm works in-place, meaning that when the algorithm finishes,
500                 pointArray will contain the list of the points on the convex hull.
501                 @return The number of points on the convex hull, i.e. the number of elements used in pointArray after the operation.
502                 @see ConvexHull(). */
503         static int ConvexHullInPlace(float2 *pointArray, int numPoints);
504 #endif
505
506         /// Computes the minimum-area rectangle that bounds the given point set.
507         /** @param center [out] This variable will receive the center point of the rectangle.
508                 @param uDir [out] This variable will receive a normalized direction vector pointing one of the sides of the rectangle.
509                 @param VDir [out] This variable will receive a normalized direction vector pointing the other side of the rectangle. */
510         static float MinAreaRect(const float2 *pointArray, int numPoints, float2 &center, float2 &uDir, float2 &vDir);
511
512         /// Generates a direction vector of the given length pointing at a uniformly random direction.
513         static float2 RandomDir(LCG &lcg, float length = 1.f);
514
515 #ifdef MATH_ENABLE_UNCOMMON_OPERATIONS
516         float2 operator *(const float2 &rhs) const return this->Mul(rhs); }
517         float2 operator /(const float2 &rhs) const return this->Div(rhs); }
518         float2 &operator *=(const float2 &rhs) { *this = this->Mul(rhs); return *this; }
519         float2 &operator /=(const float2 &rhs) { *this = this->Div(rhs); return *this; }
520 #endif
521
522         /// Specifies a compile-time constant float2 with value (0, 0).
523         /** @note Due to static data initialization order being undefined in C++, do NOT use this
524                         member to initialize other static data in other compilation units! */
525         static const float2 zero;
526         /// Specifies a compile-time constant float2 with value (1, 1). [similarOverload: zero]
527         /** @note Due to static data initialization order being undefined in C++, do NOT use this
528                         member to initialize other static data in other compilation units! */
529         static const float2 one;
530         /// Specifies a compile-time constant float2 with value (1, 0).
531         /** @note Due to static data initialization order being undefined in C++, do NOT use this
532                         member to initialize other static data in other compilation units! */
533         static const float2 unitX;
534         /// Specifies a compile-time constant float2 with value (0, 1). [similarOverload: unitX]
535         /** @note Due to static data initialization order being undefined in C++, do NOT use this
536                         member to initialize other static data in other compilation units! */
537         static const float2 unitY;
538         /// A compile-time constant float2 with value (NaN, NaN).
539         /** For this constant, each element has the value of quiet NaN, or Not-A-Number.
540                 @note Never compare a float2 to this value! Due to how IEEE floats work, for each float x, both expressions "x == nan" and "x != nan" return false!
541                           That is, nothing is equal to NaN, not even NaN itself!
542                 @note Due to static data initialization order being undefined in C++, do NOT use this
543                         member to initialize other static data in other compilation units! */
544         static const float2 nan;
545         /// A compile-time constant float2 with value (+infinity, +infinity). [similarOverload: nan]
546         /** @note Due to static data initialization order being undefined in C++, do NOT use this
547                         member to initialize other static data in other compilation units! */
548         static const float2 inf;
549
550 #ifdef MATH_OGRE_INTEROP
551         float2(const Ogre::Vector2 &other) { x = other.x; y = other.y; }
552         operator Ogre::Vector2() const return Ogre::Vector2(xy); }
553 #endif
554 #ifdef MATH_QT_INTEROP
555         float2(const QVector2D &other) { x = other.x(); y = other.y(); }
556         operator QVector2D() const return QVector2D(xy); }
557         operator QString() const return "float2(" + QString::number(x) + "," + QString::number(y) + ")"; }
558         QString toString() const return (QString)*this; }
559         QVector2D ToQVector2D() const return QVector2D(xy); }
560         static float2 FromQVector2D(const QVector2D &v) { return (float2)v; }
561         static float2 FromString(const QString &str) { return FromString(str.toStdString()); }
562 #endif
563 };
564
565 #ifdef MATH_ENABLE_STL_SUPPORT
566 /// Prints this float2 to the given stream.
567 std::ostream &operator <<(std::ostream &out, const float2 &rhs);
568 #endif
569
570 float2 operator *(float scalar, const float2 &rhs);
571
572 #ifdef MATH_ENABLE_UNCOMMON_OPERATIONS
573 inline float2 operator /(float scalar, const float2 &rhs) { return float2::FromScalar(scalar) / rhs; }
574 #endif
575
576 inline float Dot(const float2 &a, const float2 &b) { return a.Dot(b); }
577 inline float2 Abs(const float2 &a) { return a.Abs(); }
578 inline float2 Min(const float2 &a, const float2 &b) { return a.Min(b); }
579 inline float2 Max(const float2 &a, const float2 &b) { return a.Max(b); }
580 inline float2 Clamp(const float2 &a, float floor, float ceil) { return a.Clamp(floor, ceil); }
581 inline float2 Clamp(const float2 &a, const float2 &floor, const float2 &ceil) { return a.Clamp(floor, ceil); }
582 inline float2 Clamp01(const float2 &a) { return a.Clamp01(); }
583 inline float2 Lerp(const float2 &a, const float2 &b, float t) { return a.Lerp(b, t); }
584
585 MATH_END_NAMESPACE
586
587 #ifdef MATH_QT_INTEROP
588 Q_DECLARE_METATYPE(float2)
589 Q_DECLARE_METATYPE(float2*)
590 #endif

Go back to previous page