source: GTP/trunk/Lib/Geom/OgreStuff/include/OgreVector2.h @ 1809

Revision 1809, 16.0 KB checked in by gumbau, 18 years ago (diff)
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25#ifndef __Vector2_H__
26#define __Vector2_H__
27
28
29#include "OgrePrerequisites.h"
30#include "OgreMath.h"
31
32namespace Ogre
33{
34
35    /** Standard 2-dimensional vector.
36        @remarks
37            A direction in 2D space represented as distances along the 2
38            orthoganal axes (x, y). Note that positions, directions and
39            scaling factors can be represented by a vector, depending on how
40            you interpret the values.
41    */
42    class _OgreExport Vector2
43    {
44    public:
45        union {
46            struct {
47                Real x, y;
48            };
49            Real val[2];
50        };
51
52    public:
53        inline Vector2()
54        {
55        }
56
57        inline Vector2(const Real fX, const Real fY )
58            : x( fX ), y( fY )
59        {
60        }
61
62        inline explicit Vector2( const Real scaler )
63            : x( scaler), y( scaler )
64        {
65        }
66
67        inline explicit Vector2( const Real afCoordinate[2] )
68            : x( afCoordinate[0] ),
69              y( afCoordinate[1] )
70        {
71        }
72
73        inline explicit Vector2( const int afCoordinate[2] )
74        {
75            x = (Real)afCoordinate[0];
76            y = (Real)afCoordinate[1];
77        }
78
79        inline explicit Vector2( Real* const r )
80            : x( r[0] ), y( r[1] )
81        {
82        }
83
84        inline Vector2( const Vector2& rkVector )
85            : x( rkVector.x ), y( rkVector.y )
86        {
87        }
88
89                inline Real operator [] ( const size_t i ) const
90        {
91            assert( i < 2 );
92
93            return *(&x+i);
94        }
95
96                inline Real& operator [] ( const size_t i )
97        {
98            assert( i < 2 );
99
100            return *(&x+i);
101        }
102
103        /** Assigns the value of the other vector.
104            @param
105                rkVector The other vector
106        */
107        inline Vector2& operator = ( const Vector2& rkVector )
108        {
109            x = rkVector.x;
110            y = rkVector.y;
111
112            return *this;
113        }
114
115                inline Vector2& operator = ( const Real fScalar)
116                {
117                        x = fScalar;
118                        y = fScalar;
119
120                        return *this;
121                }
122
123        inline bool operator == ( const Vector2& rkVector ) const
124        {
125            return ( x == rkVector.x && y == rkVector.y );
126        }
127
128        inline bool operator != ( const Vector2& rkVector ) const
129        {
130            return ( x != rkVector.x || y != rkVector.y  );
131        }
132
133        // arithmetic operations
134        inline Vector2 operator + ( const Vector2& rkVector ) const
135        {
136            return Vector2(
137                x + rkVector.x,
138                y + rkVector.y);
139        }
140
141        inline Vector2 operator - ( const Vector2& rkVector ) const
142        {
143            return Vector2(
144                x - rkVector.x,
145                y - rkVector.y);
146        }
147
148        inline Vector2 operator * ( const Real fScalar ) const
149        {
150            return Vector2(
151                x * fScalar,
152                y * fScalar);
153        }
154
155        inline Vector2 operator * ( const Vector2& rhs) const
156        {
157            return Vector2(
158                x * rhs.x,
159                y * rhs.y);
160        }
161
162        inline Vector2 operator / ( const Real fScalar ) const
163        {
164            assert( fScalar != 0.0 );
165
166            Real fInv = 1.0 / fScalar;
167
168            return Vector2(
169                x * fInv,
170                y * fInv);
171        }
172
173        inline Vector2 operator / ( const Vector2& rhs) const
174        {
175            return Vector2(
176                x / rhs.x,
177                y / rhs.y);
178        }
179
180        inline const Vector2& operator + () const
181        {
182            return *this;
183        }
184
185        inline Vector2 operator - () const
186        {
187            return Vector2(-x, -y);
188        }
189
190        // overloaded operators to help Vector2
191        inline friend Vector2 operator * ( const Real fScalar, const Vector2& rkVector )
192        {
193            return Vector2(
194                fScalar * rkVector.x,
195                fScalar * rkVector.y);
196        }
197
198        inline friend Vector2 operator / ( const Real fScalar, const Vector2& rkVector )
199        {
200            return Vector2(
201                fScalar / rkVector.x,
202                fScalar / rkVector.y);
203        }
204
205        inline friend Vector2 operator + (const Vector2& lhs, const Real rhs)
206        {
207            return Vector2(
208                lhs.x + rhs,
209                lhs.y + rhs);
210        }
211
212        inline friend Vector2 operator + (const Real lhs, const Vector2& rhs)
213        {
214            return Vector2(
215                lhs + rhs.x,
216                lhs + rhs.y);
217        }
218
219        inline friend Vector2 operator - (const Vector2& lhs, const Real rhs)
220        {
221            return Vector2(
222                lhs.x - rhs,
223                lhs.y - rhs);
224        }
225
226        inline friend Vector2 operator - (const Real lhs, const Vector2& rhs)
227        {
228            return Vector2(
229                lhs - rhs.x,
230                lhs - rhs.y);
231        }
232        // arithmetic updates
233        inline Vector2& operator += ( const Vector2& rkVector )
234        {
235            x += rkVector.x;
236            y += rkVector.y;
237
238            return *this;
239        }
240
241        inline Vector2& operator += ( const Real fScaler )
242        {
243            x += fScaler;
244            y += fScaler;
245
246            return *this;
247        }
248
249        inline Vector2& operator -= ( const Vector2& rkVector )
250        {
251            x -= rkVector.x;
252            y -= rkVector.y;
253
254            return *this;
255        }
256
257        inline Vector2& operator -= ( const Real fScaler )
258        {
259            x -= fScaler;
260            y -= fScaler;
261
262            return *this;
263        }
264
265        inline Vector2& operator *= ( const Real fScalar )
266        {
267            x *= fScalar;
268            y *= fScalar;
269
270            return *this;
271        }
272
273        inline Vector2& operator *= ( const Vector2& rkVector )
274        {
275            x *= rkVector.x;
276            y *= rkVector.y;
277
278            return *this;
279        }
280
281        inline Vector2& operator /= ( const Real fScalar )
282        {
283            assert( fScalar != 0.0 );
284
285            Real fInv = 1.0 / fScalar;
286
287            x *= fInv;
288            y *= fInv;
289
290            return *this;
291        }
292
293        inline Vector2& operator /= ( const Vector2& rkVector )
294        {
295            x /= rkVector.x;
296            y /= rkVector.y;
297
298            return *this;
299        }
300
301        /** Returns the length (magnitude) of the vector.
302            @warning
303                This operation requires a square root and is expensive in
304                terms of CPU operations. If you don't need to know the exact
305                length (e.g. for just comparing lengths) use squaredLength()
306                instead.
307        */
308        inline Real length () const
309        {
310            return Math::Sqrt( x * x + y * y );
311        }
312
313        /** Returns the square of the length(magnitude) of the vector.
314            @remarks
315                This  method is for efficiency - calculating the actual
316                length of a vector requires a square root, which is expensive
317                in terms of the operations required. This method returns the
318                square of the length of the vector, i.e. the same as the
319                length but before the square root is taken. Use this if you
320                want to find the longest / shortest vector without incurring
321                the square root.
322        */
323        inline Real squaredLength () const
324        {
325            return x * x + y * y;
326        }
327
328        /** Calculates the dot (scalar) product of this vector with another.
329            @remarks
330                The dot product can be used to calculate the angle between 2
331                vectors. If both are unit vectors, the dot product is the
332                cosine of the angle; otherwise the dot product must be
333                divided by the product of the lengths of both vectors to get
334                the cosine of the angle. This result can further be used to
335                calculate the distance of a point from a plane.
336            @param
337                vec Vector with which to calculate the dot product (together
338                with this one).
339            @returns
340                A float representing the dot product value.
341        */
342        inline Real dotProduct(const Vector2& vec) const
343        {
344            return x * vec.x + y * vec.y;
345        }
346
347        /** Normalises the vector.
348            @remarks
349                This method normalises the vector such that it's
350                length / magnitude is 1. The result is called a unit vector.
351            @note
352                This function will not crash for zero-sized vectors, but there
353                will be no changes made to their components.
354            @returns The previous length of the vector.
355        */
356        inline Real normalise()
357        {
358            Real fLength = Math::Sqrt( x * x + y * y);
359
360            // Will also work for zero-sized vectors, but will change nothing
361            if ( fLength > 1e-08 )
362            {
363                Real fInvLength = 1.0 / fLength;
364                x *= fInvLength;
365                y *= fInvLength;
366            }
367
368            return fLength;
369        }
370
371
372
373        /** Returns a vector at a point half way between this and the passed
374            in vector.
375        */
376        inline Vector2 midPoint( const Vector2& vec ) const
377        {
378            return Vector2(
379                ( x + vec.x ) * 0.5,
380                ( y + vec.y ) * 0.5 );
381        }
382
383        /** Returns true if the vector's scalar components are all greater
384            that the ones of the vector it is compared against.
385        */
386        inline bool operator < ( const Vector2& rhs ) const
387        {
388            if( x < rhs.x && y < rhs.y )
389                return true;
390            return false;
391        }
392
393        /** Returns true if the vector's scalar components are all smaller
394            that the ones of the vector it is compared against.
395        */
396        inline bool operator > ( const Vector2& rhs ) const
397        {
398            if( x > rhs.x && y > rhs.y )
399                return true;
400            return false;
401        }
402
403        /** Sets this vector's components to the minimum of its own and the
404            ones of the passed in vector.
405            @remarks
406                'Minimum' in this case means the combination of the lowest
407                value of x, y and z from both vectors. Lowest is taken just
408                numerically, not magnitude, so -1 < 0.
409        */
410        inline void makeFloor( const Vector2& cmp )
411        {
412            if( cmp.x < x ) x = cmp.x;
413            if( cmp.y < y ) y = cmp.y;
414        }
415
416        /** Sets this vector's components to the maximum of its own and the
417            ones of the passed in vector.
418            @remarks
419                'Maximum' in this case means the combination of the highest
420                value of x, y and z from both vectors. Highest is taken just
421                numerically, not magnitude, so 1 > -3.
422        */
423        inline void makeCeil( const Vector2& cmp )
424        {
425            if( cmp.x > x ) x = cmp.x;
426            if( cmp.y > y ) y = cmp.y;
427        }
428
429        /** Generates a vector perpendicular to this vector (eg an 'up' vector).
430            @remarks
431                This method will return a vector which is perpendicular to this
432                vector. There are an infinite number of possibilities but this
433                method will guarantee to generate one of them. If you need more
434                control you should use the Quaternion class.
435        */
436        inline Vector2 perpendicular(void) const
437        {
438            return Vector2 (-y, x);
439        }
440        /** Calculates the 2 dimensional cross-product of 2 vectors, which results
441                        in a single floating point value which is 2 times the area of the triangle.
442        */
443        inline Real crossProduct( const Vector2& rkVector ) const
444        {
445            return x * rkVector.y - y * rkVector.x;
446        }
447        /** Generates a new random vector which deviates from this vector by a
448            given angle in a random direction.
449            @remarks
450                This method assumes that the random number generator has already
451                been seeded appropriately.
452            @param
453                angle The angle at which to deviate in radians
454            @param
455                up Any vector perpendicular to this one (which could generated
456                by cross-product of this vector and any other non-colinear
457                vector). If you choose not to provide this the function will
458                derive one on it's own, however if you provide one yourself the
459                function will be faster (this allows you to reuse up vectors if
460                you call this method more than once)
461            @returns
462                A random vector which deviates from this vector by angle. This
463                vector will not be normalised, normalise it if you wish
464                afterwards.
465        */
466        inline Vector2 randomDeviant(
467            Real angle) const
468        {
469
470            angle *=  Math::UnitRandom() * Math::TWO_PI;
471            Real cosa = cos(angle);
472            Real sina = sin(angle);
473            return  Vector2(cosa * x - sina * y,
474                            sina * x + cosa * y);
475        }
476
477        /** Returns true if this vector is zero length. */
478        inline bool isZeroLength(void) const
479        {
480            Real sqlen = (x * x) + (y * y);
481            return (sqlen < (1e-06 * 1e-06));
482
483        }
484
485        /** As normalise, except that this vector is unaffected and the
486            normalised vector is returned as a copy. */
487        inline Vector2 normalisedCopy(void) const
488        {
489            Vector2 ret = *this;
490            ret.normalise();
491            return ret;
492        }
493
494        /** Calculates a reflection vector to the plane with the given normal .
495        @remarks NB assumes 'this' is pointing AWAY FROM the plane, invert if it is not.
496        */
497        inline Vector2 reflect(const Vector2& normal) const
498        {
499            return Vector2( *this - ( 2 * this->dotProduct(normal) * normal ) );
500        }
501
502        // special points
503        static const Vector2 ZERO;
504        static const Vector2 UNIT_X;
505        static const Vector2 UNIT_Y;
506        static const Vector2 NEGATIVE_UNIT_X;
507        static const Vector2 NEGATIVE_UNIT_Y;
508        static const Vector2 UNIT_SCALE;
509
510        /** Function for writing to a stream.
511        */
512        inline _OgreExport friend std::ostream& operator <<
513            ( std::ostream& o, const Vector2& v )
514        {
515            o << "Vector2(" << v.x << ", " << v.y <<  ")";
516            return o;
517        }
518
519    };
520
521}
522#endif
Note: See TracBrowser for help on using the repository browser.