Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/forks/sandbox_light/src/external/ogremath/OgreVector2.h @ 10255

Last change on this file since 10255 was 7908, checked in by rgrieder, 14 years ago

Stripped down trunk to form a new light sandbox.

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