source: GTP/trunk/App/Demos/Geom/OgreStuff/include/OgreVector2.h @ 1030

Revision 1030, 15.5 KB checked in by gumbau, 18 years ago (diff)

Ogre Stuff initial import

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( Real fX, Real fY )
58            : x( fX ), y( fY )
59        {
60        }
61
62        inline Vector2( Real afCoordinate[2] )
63            : x( afCoordinate[0] ),
64              y( afCoordinate[1] )
65        {
66        }
67
68        inline Vector2( int afCoordinate[2] )
69        {
70            x = (Real)afCoordinate[0];
71            y = (Real)afCoordinate[1];
72        }
73
74        inline Vector2( const Real* const r )
75            : x( r[0] ), y( r[1] )
76        {
77        }
78
79        inline Vector2( const Vector2& rkVector )
80            : x( rkVector.x ), y( rkVector.y )
81        {
82        }
83
84                inline Real operator [] ( size_t i ) const
85        {
86            assert( i < 2 );
87
88            return *(&x+i);
89        }
90
91                inline Real& operator [] ( size_t i )
92        {
93            assert( i < 2 );
94
95            return *(&x+i);
96        }
97
98        /** Assigns the value of the other vector.
99            @param
100                rkVector The other vector
101        */
102        inline Vector2& operator = ( const Vector2& rkVector )
103        {
104            x = rkVector.x;
105            y = rkVector.y;       
106
107            return *this;
108        }
109
110        inline bool operator == ( const Vector2& rkVector ) const
111        {
112            return ( x == rkVector.x && y == rkVector.y );
113        }
114
115        inline bool operator != ( const Vector2& rkVector ) const
116        {
117            return ( x != rkVector.x || y != rkVector.y  );
118        }
119
120        // arithmetic operations
121        inline Vector2 operator + ( const Vector2& rkVector ) const
122        {
123            Vector2 kSum;
124
125            kSum.x = x + rkVector.x;
126            kSum.y = y + rkVector.y;
127
128            return kSum;
129        }
130
131        inline Vector2 operator - ( const Vector2& rkVector ) const
132        {
133            Vector2 kDiff;
134
135            kDiff.x = x - rkVector.x;
136            kDiff.y = y - rkVector.y;
137
138            return kDiff;
139        }
140
141        inline Vector2 operator * ( Real fScalar ) const
142        {
143            Vector2 kProd;
144
145            kProd.x = fScalar*x;
146            kProd.y = fScalar*y;
147
148            return kProd;
149        }
150
151        inline Vector2 operator * ( const Vector2& rhs) const
152        {
153            Vector2 kProd;
154
155            kProd.x = rhs.x * x;
156            kProd.y = rhs.y * y;
157
158            return kProd;
159        }
160
161        inline Vector2 operator / ( Real fScalar ) const
162        {
163            assert( fScalar != 0.0 );
164
165            Vector2 kDiv;
166
167            Real fInv = 1.0 / fScalar;
168            kDiv.x = x * fInv;
169            kDiv.y = y * fInv;
170
171            return kDiv;
172        }
173
174        inline Vector2 operator - () const
175        {
176            Vector2 kNeg;
177
178            kNeg.x = -x;
179            kNeg.y = -y;
180
181            return kNeg;
182        }
183
184        inline friend Vector2 operator * ( Real fScalar, const Vector2& rkVector )
185        {
186            Vector2 kProd;
187
188            kProd.x = fScalar * rkVector.x;
189            kProd.y = fScalar * rkVector.y;
190
191            return kProd;
192        }
193
194        // arithmetic updates
195        inline Vector2& operator += ( const Vector2& rkVector )
196        {
197            x += rkVector.x;
198            y += rkVector.y;
199
200            return *this;
201        }
202
203        inline Vector2& operator -= ( const Vector2& rkVector )
204        {
205            x -= rkVector.x;
206            y -= rkVector.y;
207
208            return *this;
209        }
210
211        inline Vector2& operator *= ( Real fScalar )
212        {
213            x *= fScalar;
214            y *= fScalar;
215
216            return *this;
217        }
218
219        inline Vector2& operator /= ( Real fScalar )
220        {
221            assert( fScalar != 0.0 );
222
223            Real fInv = 1.0 / fScalar;
224
225            x *= fInv;
226            y *= fInv;
227
228            return *this;
229        }
230
231        /** Returns the length (magnitude) of the vector.
232            @warning
233                This operation requires a square root and is expensive in
234                terms of CPU operations. If you don't need to know the exact
235                length (e.g. for just comparing lengths) use squaredLength()
236                instead.
237        */
238        inline Real length () const
239        {
240            return Math::Sqrt( x * x + y * y );
241        }
242
243        /** Returns the square of the length(magnitude) of the vector.
244            @remarks
245                This  method is for efficiency - calculating the actual
246                length of a vector requires a square root, which is expensive
247                in terms of the operations required. This method returns the
248                square of the length of the vector, i.e. the same as the
249                length but before the square root is taken. Use this if you
250                want to find the longest / shortest vector without incurring
251                the square root.
252        */
253        inline Real squaredLength () const
254        {
255            return x * x + y * y;
256        }
257
258        /** Calculates the dot (scalar) product of this vector with another.
259            @remarks
260                The dot product can be used to calculate the angle between 2
261                vectors. If both are unit vectors, the dot product is the
262                cosine of the angle; otherwise the dot product must be
263                divided by the product of the lengths of both vectors to get
264                the cosine of the angle. This result can further be used to
265                calculate the distance of a point from a plane.
266            @param
267                vec Vector with which to calculate the dot product (together
268                with this one).
269            @returns
270                A float representing the dot product value.
271        */
272        inline Real dotProduct(const Vector2& vec) const
273        {
274            return x * vec.x + y * vec.y;
275        }
276
277        /** Normalises the vector.
278            @remarks
279                This method normalises the vector such that it's
280                length / magnitude is 1. The result is called a unit vector.
281            @note
282                This function will not crash for zero-sized vectors, but there
283                will be no changes made to their components.
284            @returns The previous length of the vector.
285        */
286        inline Real normalise()
287        {
288            Real fLength = Math::Sqrt( x * x + y * y);
289
290            // Will also work for zero-sized vectors, but will change nothing
291            if ( fLength > 1e-08 )
292            {
293                Real fInvLength = 1.0 / fLength;
294                x *= fInvLength;
295                y *= fInvLength;
296            }
297
298            return fLength;
299        }
300
301   
302   
303        /** Returns a vector at a point half way between this and the passed
304            in vector.
305        */
306        inline Vector2 midPoint( const Vector2& vec ) const
307        {
308            return Vector2(
309                ( x + vec.x ) * 0.5,
310                ( y + vec.y ) * 0.5 );
311        }
312
313        /** Returns true if the vector's scalar components are all greater
314            that the ones of the vector it is compared against.
315        */
316        inline bool operator < ( const Vector2& rhs ) const
317        {
318            if( x < rhs.x && y < rhs.y )
319                return true;
320            return false;
321        }
322
323        /** Returns true if the vector's scalar components are all smaller
324            that the ones of the vector it is compared against.
325        */
326        inline bool operator > ( const Vector2& rhs ) const
327        {
328            if( x > rhs.x && y > rhs.y )
329                return true;
330            return false;
331        }
332
333        /** Sets this vector's components to the minimum of its own and the
334            ones of the passed in vector.
335            @remarks
336                'Minimum' in this case means the combination of the lowest
337                value of x, y and z from both vectors. Lowest is taken just
338                numerically, not magnitude, so -1 < 0.
339        */
340        inline void makeFloor( const Vector2& cmp )
341        {
342            if( cmp.x < x ) x = cmp.x;
343            if( cmp.y < y ) y = cmp.y;
344        }
345
346        /** Sets this vector's components to the maximum of its own and the
347            ones of the passed in vector.
348            @remarks
349                'Maximum' in this case means the combination of the highest
350                value of x, y and z from both vectors. Highest is taken just
351                numerically, not magnitude, so 1 > -3.
352        */
353        inline void makeCeil( const Vector2& cmp )
354        {
355            if( cmp.x > x ) x = cmp.x;
356            if( cmp.y > y ) y = cmp.y;
357        }
358
359        /** Generates a vector perpendicular to this vector (eg an 'up' vector).
360            @remarks
361                This method will return a vector which is perpendicular to this
362                vector. There are an infinite number of possibilities but this
363                method will guarantee to generate one of them. If you need more
364                control you should use the Quaternion class.
365        */
366        inline Vector2 perpendicular(void) const
367        {         
368            return Vector2 (-y, x);
369        }
370        /** Calculates the cross-product of 2 vectors, i.e. the vector that
371            lies perpendicular to them both.
372            @remarks
373                The cross-product is normally used to calculate the normal
374                vector of a plane, by calculating the cross-product of 2
375                non-equivalent vectors which lie on the plane (e.g. 2 edges
376                of a triangle).
377            @param
378                vec Vector which, together with this one, will be used to
379                calculate the cross-product.
380            @returns
381                A vector which is the result of the cross-product. This
382                vector will <b>NOT</b> be normalised, to maximise efficiency
383                - call Vector3::normalise on the result if you wish this to
384                be done. As for which side the resultant vector will be on, the
385                returned vector will be on the side from which the arc from 'this'
386                to rkVector is anticlockwise, e.g. UNIT_Y.crossProduct(UNIT_Z)
387                = UNIT_X, whilst UNIT_Z.crossProduct(UNIT_Y) = -UNIT_X.
388            @par
389                For a clearer explanation, look a the left and the bottom edges
390                of your monitor's screen. Assume that the first vector is the
391                left edge and the second vector is the bottom edge, both of
392                them starting from the lower-left corner of the screen. The
393                resulting vector is going to be perpendicular to both of them
394                and will go <i>inside</i> the screen, towards the cathode tube
395                (assuming you're using a CRT monitor, of course).
396        */
397        inline Vector2 crossProduct( const Vector2& rkVector ) const
398        {
399            return Vector2(-rkVector.y, rkVector.x);
400        }
401        /** Generates a new random vector which deviates from this vector by a
402            given angle in a random direction.
403            @remarks
404                This method assumes that the random number generator has already
405                been seeded appropriately.
406            @param
407                angle The angle at which to deviate in radians
408            @param
409                up Any vector perpendicular to this one (which could generated
410                by cross-product of this vector and any other non-colinear
411                vector). If you choose not to provide this the function will
412                derive one on it's own, however if you provide one yourself the
413                function will be faster (this allows you to reuse up vectors if
414                you call this method more than once)
415            @returns
416                A random vector which deviates from this vector by angle. This
417                vector will not be normalised, normalise it if you wish
418                afterwards.
419        */
420        inline Vector2 randomDeviant(
421            Real angle) const
422        {
423           
424            angle *=  Math::UnitRandom() * Math::TWO_PI;
425            Real cosa = cos(angle);
426            Real sina = sin(angle);
427            return  Vector2(cosa * x - sina * y,
428                            sina * x + cosa * y);
429        }
430       
431        /** Returns true if this vector is zero length. */
432        inline bool isZeroLength(void) const
433        {
434            Real sqlen = (x * x) + (y * y);
435            return (sqlen < (1e-06 * 1e-06));
436
437        }
438
439        /** As normalise, except that this vector is unaffected and the
440            normalised vector is returned as a copy. */
441        inline Vector2 normalisedCopy(void) const
442        {
443            Vector2 ret = *this;
444            ret.normalise();
445            return ret;
446        }
447
448        /** Calculates a reflection vector to the plane with the given normal .
449        @remarks NB assumes 'this' is pointing AWAY FROM the plane, invert if it is not.
450        */
451        inline Vector2 reflect(const Vector2& normal) const
452        {
453            return Vector2( *this - ( 2 * this->dotProduct(normal) * normal ) );
454        }
455
456        // special points
457        static const Vector2 ZERO;
458        static const Vector2 UNIT_X;
459        static const Vector2 UNIT_Y;
460        static const Vector2 NEGATIVE_UNIT_X;
461        static const Vector2 NEGATIVE_UNIT_Y;
462        static const Vector2 UNIT_SCALE;
463
464        /** Function for writing to a stream.
465        */
466        inline _OgreExport friend std::ostream& operator <<
467            ( std::ostream& o, const Vector2& v )
468        {
469            o << "Vector2(" << v.x << ", " << v.y <<  ")";
470            return o;
471        }
472    };
473
474}
475#endif
Note: See TracBrowser for help on using the repository browser.