Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/OgreMain/include/OgreVector2.h @ 1

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