source: OGRE/trunk/ogrenew/OgreMain/include/OgreVector2.h @ 692

Revision 692, 15.3 KB checked in by mattausch, 18 years ago (diff)

adding ogre 1.2 and dependencies

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            Vector2 kSum;
137
138            kSum.x = x + rkVector.x;
139            kSum.y = y + rkVector.y;
140
141            return kSum;
142        }
143
144        inline Vector2 operator - ( const Vector2& rkVector ) const
145        {
146            Vector2 kDiff;
147
148            kDiff.x = x - rkVector.x;
149            kDiff.y = y - rkVector.y;
150
151            return kDiff;
152        }
153
154        inline Vector2 operator * ( const Real fScalar ) const
155        {
156            Vector2 kProd;
157
158            kProd.x = fScalar*x;
159            kProd.y = fScalar*y;
160
161            return kProd;
162        }
163
164        inline Vector2 operator * ( const Vector2& rhs) const
165        {
166            Vector2 kProd;
167
168            kProd.x = rhs.x * x;
169            kProd.y = rhs.y * y;
170
171            return kProd;
172        }
173
174        inline Vector2 operator / ( const Real fScalar ) const
175        {
176            assert( fScalar != 0.0 );
177
178            Vector2 kDiv;
179
180            Real fInv = 1.0 / fScalar;
181            kDiv.x = x * fInv;
182            kDiv.y = y * fInv;
183
184            return kDiv;
185        }
186
187        inline Vector2 operator - () const
188        {
189            Vector2 kNeg;
190
191            kNeg.x = -x;
192            kNeg.y = -y;
193
194            return kNeg;
195        }
196
197        // overloaded operators to help Vector2
198        inline friend Vector2 operator * ( const Real fScalar, const Vector2& rkVector )
199        {
200            Vector2 kProd;
201
202            kProd.x = fScalar * rkVector.x;
203            kProd.y = fScalar * rkVector.y;
204
205            return kProd;
206        }
207
208        inline friend Vector2 operator + (const Vector2& lhs, const Real rhs)
209        {
210            Vector2 ret(rhs);
211            return ret += lhs;
212        }
213
214        inline friend Vector2 operator + (const Real lhs, const Vector2& rhs)
215        {
216            Vector2 ret(lhs);
217            return ret += rhs;
218        }
219
220        inline friend Vector2 operator - (const Vector2& lhs, const Real rhs)
221        {
222            return lhs - Vector2(rhs);
223        }
224
225        inline friend Vector2 operator - (const Real lhs, const Vector2& rhs)
226        {
227            Vector2 ret(lhs);
228            return ret -= rhs;
229        }
230        // arithmetic updates
231        inline Vector2& operator += ( const Vector2& rkVector )
232        {
233            x += rkVector.x;
234            y += rkVector.y;
235
236            return *this;
237        }
238
239        inline Vector2& operator += ( const Real fScaler )
240        {
241            x += fScaler;
242            y += fScaler;
243
244            return *this;
245        }
246
247        inline Vector2& operator -= ( const Vector2& rkVector )
248        {
249            x -= rkVector.x;
250            y -= rkVector.y;
251
252            return *this;
253        }
254
255        inline Vector2& operator -= ( const Real fScaler )
256        {
257            x -= fScaler;
258            y -= fScaler;
259
260            return *this;
261        }
262
263        inline Vector2& operator *= ( const Real fScalar )
264        {
265            x *= fScalar;
266            y *= fScalar;
267
268            return *this;
269        }
270
271        inline Vector2& operator /= ( const Real fScalar )
272        {
273            assert( fScalar != 0.0 );
274
275            Real fInv = 1.0 / fScalar;
276
277            x *= fInv;
278            y *= fInv;
279
280            return *this;
281        }
282
283        /** Returns the length (magnitude) of the vector.
284            @warning
285                This operation requires a square root and is expensive in
286                terms of CPU operations. If you don't need to know the exact
287                length (e.g. for just comparing lengths) use squaredLength()
288                instead.
289        */
290        inline Real length () const
291        {
292            return Math::Sqrt( x * x + y * y );
293        }
294
295        /** Returns the square of the length(magnitude) of the vector.
296            @remarks
297                This  method is for efficiency - calculating the actual
298                length of a vector requires a square root, which is expensive
299                in terms of the operations required. This method returns the
300                square of the length of the vector, i.e. the same as the
301                length but before the square root is taken. Use this if you
302                want to find the longest / shortest vector without incurring
303                the square root.
304        */
305        inline Real squaredLength () const
306        {
307            return x * x + y * y;
308        }
309
310        /** Calculates the dot (scalar) product of this vector with another.
311            @remarks
312                The dot product can be used to calculate the angle between 2
313                vectors. If both are unit vectors, the dot product is the
314                cosine of the angle; otherwise the dot product must be
315                divided by the product of the lengths of both vectors to get
316                the cosine of the angle. This result can further be used to
317                calculate the distance of a point from a plane.
318            @param
319                vec Vector with which to calculate the dot product (together
320                with this one).
321            @returns
322                A float representing the dot product value.
323        */
324        inline Real dotProduct(const Vector2& vec) const
325        {
326            return x * vec.x + y * vec.y;
327        }
328
329        /** Normalises the vector.
330            @remarks
331                This method normalises the vector such that it's
332                length / magnitude is 1. The result is called a unit vector.
333            @note
334                This function will not crash for zero-sized vectors, but there
335                will be no changes made to their components.
336            @returns The previous length of the vector.
337        */
338        inline Real normalise()
339        {
340            Real fLength = Math::Sqrt( x * x + y * y);
341
342            // Will also work for zero-sized vectors, but will change nothing
343            if ( fLength > 1e-08 )
344            {
345                Real fInvLength = 1.0 / fLength;
346                x *= fInvLength;
347                y *= fInvLength;
348            }
349
350            return fLength;
351        }
352
353
354
355        /** Returns a vector at a point half way between this and the passed
356            in vector.
357        */
358        inline Vector2 midPoint( const Vector2& vec ) const
359        {
360            return Vector2(
361                ( x + vec.x ) * 0.5,
362                ( y + vec.y ) * 0.5 );
363        }
364
365        /** Returns true if the vector's scalar components are all greater
366            that the ones of the vector it is compared against.
367        */
368        inline bool operator < ( const Vector2& rhs ) const
369        {
370            if( x < rhs.x && y < rhs.y )
371                return true;
372            return false;
373        }
374
375        /** Returns true if the vector's scalar components are all smaller
376            that the ones of the vector it is compared against.
377        */
378        inline bool operator > ( const Vector2& rhs ) const
379        {
380            if( x > rhs.x && y > rhs.y )
381                return true;
382            return false;
383        }
384
385        /** Sets this vector's components to the minimum of its own and the
386            ones of the passed in vector.
387            @remarks
388                'Minimum' in this case means the combination of the lowest
389                value of x, y and z from both vectors. Lowest is taken just
390                numerically, not magnitude, so -1 < 0.
391        */
392        inline void makeFloor( const Vector2& cmp )
393        {
394            if( cmp.x < x ) x = cmp.x;
395            if( cmp.y < y ) y = cmp.y;
396        }
397
398        /** Sets this vector's components to the maximum of its own and the
399            ones of the passed in vector.
400            @remarks
401                'Maximum' in this case means the combination of the highest
402                value of x, y and z from both vectors. Highest is taken just
403                numerically, not magnitude, so 1 > -3.
404        */
405        inline void makeCeil( const Vector2& cmp )
406        {
407            if( cmp.x > x ) x = cmp.x;
408            if( cmp.y > y ) y = cmp.y;
409        }
410
411        /** Generates a vector perpendicular to this vector (eg an 'up' vector).
412            @remarks
413                This method will return a vector which is perpendicular to this
414                vector. There are an infinite number of possibilities but this
415                method will guarantee to generate one of them. If you need more
416                control you should use the Quaternion class.
417        */
418        inline Vector2 perpendicular(void) const
419        {
420            return Vector2 (-y, x);
421        }
422        /** Calculates the 2 dimensional cross-product of 2 vectors, which results
423                        in a single floating point value which is 2 times the area of the triangle.
424        */
425        inline Real crossProduct( const Vector2& rkVector ) const
426        {
427            return x * rkVector.y - y * rkVector.x;
428        }
429        /** Generates a new random vector which deviates from this vector by a
430            given angle in a random direction.
431            @remarks
432                This method assumes that the random number generator has already
433                been seeded appropriately.
434            @param
435                angle The angle at which to deviate in radians
436            @param
437                up Any vector perpendicular to this one (which could generated
438                by cross-product of this vector and any other non-colinear
439                vector). If you choose not to provide this the function will
440                derive one on it's own, however if you provide one yourself the
441                function will be faster (this allows you to reuse up vectors if
442                you call this method more than once)
443            @returns
444                A random vector which deviates from this vector by angle. This
445                vector will not be normalised, normalise it if you wish
446                afterwards.
447        */
448        inline Vector2 randomDeviant(
449            Real angle) const
450        {
451
452            angle *=  Math::UnitRandom() * Math::TWO_PI;
453            Real cosa = cos(angle);
454            Real sina = sin(angle);
455            return  Vector2(cosa * x - sina * y,
456                            sina * x + cosa * y);
457        }
458
459        /** Returns true if this vector is zero length. */
460        inline bool isZeroLength(void) const
461        {
462            Real sqlen = (x * x) + (y * y);
463            return (sqlen < (1e-06 * 1e-06));
464
465        }
466
467        /** As normalise, except that this vector is unaffected and the
468            normalised vector is returned as a copy. */
469        inline Vector2 normalisedCopy(void) const
470        {
471            Vector2 ret = *this;
472            ret.normalise();
473            return ret;
474        }
475
476        /** Calculates a reflection vector to the plane with the given normal .
477        @remarks NB assumes 'this' is pointing AWAY FROM the plane, invert if it is not.
478        */
479        inline Vector2 reflect(const Vector2& normal) const
480        {
481            return Vector2( *this - ( 2 * this->dotProduct(normal) * normal ) );
482        }
483
484        // special points
485        static const Vector2 ZERO;
486        static const Vector2 UNIT_X;
487        static const Vector2 UNIT_Y;
488        static const Vector2 NEGATIVE_UNIT_X;
489        static const Vector2 NEGATIVE_UNIT_Y;
490        static const Vector2 UNIT_SCALE;
491
492        /** Function for writing to a stream.
493        */
494        inline _OgreExport friend std::ostream& operator <<
495            ( std::ostream& o, const Vector2& v )
496        {
497            o << "Vector2(" << v.x << ", " << v.y <<  ")";
498            return o;
499        }
500
501    };
502
503}
504#endif
Note: See TracBrowser for help on using the repository browser.