Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ogre_src_v1-9-0/OgreMain/include/OgreVector2.h @ 148

Last change on this file since 148 was 148, checked in by patricwi, 6 years ago

Added new dependencies for ogre1.9 and cegui0.8

File size: 17.9 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-2013 Torus Knot Software Ltd
8
9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal
11in the Software without restriction, including without limitation the rights
12to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13copies of the Software, and to permit persons to whom the Software is
14furnished to do so, subject to the following conditions:
15
16The above copyright notice and this permission notice shall be included in
17all copies or substantial portions of the Software.
18
19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25THE SOFTWARE.
26-----------------------------------------------------------------------------
27*/
28#ifndef __Vector2_H__
29#define __Vector2_H__
30
31
32#include "OgrePrerequisites.h"
33#include "OgreMath.h"
34
35namespace Ogre
36{
37
38        /** \addtogroup Core
39        *  @{
40        */
41        /** \addtogroup Math
42        *  @{
43        */
44        /** Standard 2-dimensional vector.
45        @remarks
46            A direction in 2D space represented as distances along the 2
47            orthogonal axes (x, y). Note that positions, directions and
48            scaling factors can be represented by a vector, depending on how
49            you interpret the values.
50    */
51    class _OgreExport Vector2
52    {
53    public:
54        Real x, y;
55
56    public:
57        /** Default constructor.
58            @note
59                It does <b>NOT</b> initialize the vector for efficiency.
60        */
61        inline Vector2()
62        {
63        }
64
65        inline Vector2(const Real fX, const Real fY )
66            : x( fX ), y( fY )
67        {
68        }
69
70        inline explicit Vector2( const Real scaler )
71            : x( scaler), y( scaler )
72        {
73        }
74
75        inline explicit Vector2( const Real afCoordinate[2] )
76            : x( afCoordinate[0] ),
77              y( afCoordinate[1] )
78        {
79        }
80
81        inline explicit Vector2( const int afCoordinate[2] )
82        {
83            x = (Real)afCoordinate[0];
84            y = (Real)afCoordinate[1];
85        }
86
87        inline explicit Vector2( Real* const r )
88            : x( r[0] ), y( r[1] )
89        {
90        }
91
92                /** Exchange the contents of this vector with another.
93                */
94                inline void swap(Vector2& other)
95                {
96                        std::swap(x, other.x);
97                        std::swap(y, other.y);
98                }
99
100                inline Real operator [] ( const size_t i ) const
101        {
102            assert( i < 2 );
103
104            return *(&x+i);
105        }
106
107                inline Real& operator [] ( const size_t i )
108        {
109            assert( i < 2 );
110
111            return *(&x+i);
112        }
113
114                /// Pointer accessor for direct copying
115                inline Real* ptr()
116                {
117                        return &x;
118                }
119                /// Pointer accessor for direct copying
120                inline const Real* ptr() const
121                {
122                        return &x;
123                }
124
125        /** Assigns the value of the other vector.
126            @param
127                rkVector The other vector
128        */
129        inline Vector2& operator = ( const Vector2& rkVector )
130        {
131            x = rkVector.x;
132            y = rkVector.y;
133
134            return *this;
135        }
136
137                inline Vector2& operator = ( const Real fScalar)
138                {
139                        x = fScalar;
140                        y = fScalar;
141
142                        return *this;
143                }
144
145        inline bool operator == ( const Vector2& rkVector ) const
146        {
147            return ( x == rkVector.x && y == rkVector.y );
148        }
149
150        inline bool operator != ( const Vector2& rkVector ) const
151        {
152            return ( x != rkVector.x || y != rkVector.);
153        }
154
155        // arithmetic operations
156        inline Vector2 operator + ( const Vector2& rkVector ) const
157        {
158            return Vector2(
159                x + rkVector.x,
160                y + rkVector.y);
161        }
162
163        inline Vector2 operator - ( const Vector2& rkVector ) const
164        {
165            return Vector2(
166                x - rkVector.x,
167                y - rkVector.y);
168        }
169
170        inline Vector2 operator * ( const Real fScalar ) const
171        {
172            return Vector2(
173                x * fScalar,
174                y * fScalar);
175        }
176
177        inline Vector2 operator * ( const Vector2& rhs) const
178        {
179            return Vector2(
180                x * rhs.x,
181                y * rhs.y);
182        }
183
184        inline Vector2 operator / ( const Real fScalar ) const
185        {
186            assert( fScalar != 0.0 );
187
188            Real fInv = 1.0f / fScalar;
189
190            return Vector2(
191                x * fInv,
192                y * fInv);
193        }
194
195        inline Vector2 operator / ( const Vector2& rhs) const
196        {
197            return Vector2(
198                x / rhs.x,
199                y / rhs.y);
200        }
201
202        inline const Vector2& operator + () const
203        {
204            return *this;
205        }
206
207        inline Vector2 operator - () const
208        {
209            return Vector2(-x, -y);
210        }
211
212        // overloaded operators to help Vector2
213        inline friend Vector2 operator * ( const Real fScalar, const Vector2& rkVector )
214        {
215            return Vector2(
216                fScalar * rkVector.x,
217                fScalar * rkVector.y);
218        }
219
220        inline friend Vector2 operator / ( const Real fScalar, const Vector2& rkVector )
221        {
222            return Vector2(
223                fScalar / rkVector.x,
224                fScalar / rkVector.y);
225        }
226
227        inline friend Vector2 operator + (const Vector2& lhs, const Real rhs)
228        {
229            return Vector2(
230                lhs.x + rhs,
231                lhs.y + rhs);
232        }
233
234        inline friend Vector2 operator + (const Real lhs, const Vector2& rhs)
235        {
236            return Vector2(
237                lhs + rhs.x,
238                lhs + rhs.y);
239        }
240
241        inline friend Vector2 operator - (const Vector2& lhs, const Real rhs)
242        {
243            return Vector2(
244                lhs.x - rhs,
245                lhs.y - rhs);
246        }
247
248        inline friend Vector2 operator - (const Real lhs, const Vector2& rhs)
249        {
250            return Vector2(
251                lhs - rhs.x,
252                lhs - rhs.y);
253        }
254
255        // arithmetic updates
256        inline Vector2& operator += ( const Vector2& rkVector )
257        {
258            x += rkVector.x;
259            y += rkVector.y;
260
261            return *this;
262        }
263
264        inline Vector2& operator += ( const Real fScaler )
265        {
266            x += fScaler;
267            y += fScaler;
268
269            return *this;
270        }
271
272        inline Vector2& operator -= ( const Vector2& rkVector )
273        {
274            x -= rkVector.x;
275            y -= rkVector.y;
276
277            return *this;
278        }
279
280        inline Vector2& operator -= ( const Real fScaler )
281        {
282            x -= fScaler;
283            y -= fScaler;
284
285            return *this;
286        }
287
288        inline Vector2& operator *= ( const Real fScalar )
289        {
290            x *= fScalar;
291            y *= fScalar;
292
293            return *this;
294        }
295
296        inline Vector2& operator *= ( const Vector2& rkVector )
297        {
298            x *= rkVector.x;
299            y *= rkVector.y;
300
301            return *this;
302        }
303
304        inline Vector2& operator /= ( const Real fScalar )
305        {
306            assert( fScalar != 0.0 );
307
308            Real fInv = 1.0f / fScalar;
309
310            x *= fInv;
311            y *= fInv;
312
313            return *this;
314        }
315
316        inline Vector2& operator /= ( const Vector2& rkVector )
317        {
318            x /= rkVector.x;
319            y /= rkVector.y;
320
321            return *this;
322        }
323
324        /** Returns the length (magnitude) of the vector.
325            @warning
326                This operation requires a square root and is expensive in
327                terms of CPU operations. If you don't need to know the exact
328                length (e.g. for just comparing lengths) use squaredLength()
329                instead.
330        */
331        inline Real length () const
332        {
333            return Math::Sqrt( x * x + y * y );
334        }
335
336        /** Returns the square of the length(magnitude) of the vector.
337            @remarks
338                This  method is for efficiency - calculating the actual
339                length of a vector requires a square root, which is expensive
340                in terms of the operations required. This method returns the
341                square of the length of the vector, i.e. the same as the
342                length but before the square root is taken. Use this if you
343                want to find the longest / shortest vector without incurring
344                the square root.
345        */
346        inline Real squaredLength () const
347        {
348            return x * x + y * y;
349        }
350
351        /** Returns the distance to another vector.
352            @warning
353                This operation requires a square root and is expensive in
354                terms of CPU operations. If you don't need to know the exact
355                distance (e.g. for just comparing distances) use squaredDistance()
356                instead.
357        */
358        inline Real distance(const Vector2& rhs) const
359        {
360            return (*this - rhs).length();
361        }
362
363        /** Returns the square of the distance to another vector.
364            @remarks
365                This method is for efficiency - calculating the actual
366                distance to another vector requires a square root, which is
367                expensive in terms of the operations required. This method
368                returns the square of the distance to another vector, i.e.
369                the same as the distance but before the square root is taken.
370                Use this if you want to find the longest / shortest distance
371                without incurring the square root.
372        */
373        inline Real squaredDistance(const Vector2& rhs) const
374        {
375            return (*this - rhs).squaredLength();
376        }
377
378        /** Calculates the dot (scalar) product of this vector with another.
379            @remarks
380                The dot product can be used to calculate the angle between 2
381                vectors. If both are unit vectors, the dot product is the
382                cosine of the angle; otherwise the dot product must be
383                divided by the product of the lengths of both vectors to get
384                the cosine of the angle. This result can further be used to
385                calculate the distance of a point from a plane.
386            @param
387                vec Vector with which to calculate the dot product (together
388                with this one).
389            @return
390                A float representing the dot product value.
391        */
392        inline Real dotProduct(const Vector2& vec) const
393        {
394            return x * vec.x + y * vec.y;
395        }
396
397        /** Normalises the vector.
398            @remarks
399                This method normalises the vector such that it's
400                length / magnitude is 1. The result is called a unit vector.
401            @note
402                This function will not crash for zero-sized vectors, but there
403                will be no changes made to their components.
404            @return The previous length of the vector.
405        */
406
407        inline Real normalise()
408        {
409            Real fLength = Math::Sqrt( x * x + y * y);
410
411            // Will also work for zero-sized vectors, but will change nothing
412                        // We're not using epsilons because we don't need to.
413            // Read http://www.ogre3d.org/forums/viewtopic.php?f=4&t=61259
414            if ( fLength > Real(0.0f) )
415            {
416                Real fInvLength = 1.0f / fLength;
417                x *= fInvLength;
418                y *= fInvLength;
419            }
420
421            return fLength;
422        }
423
424        /** Returns a vector at a point half way between this and the passed
425            in vector.
426        */
427        inline Vector2 midPoint( const Vector2& vec ) const
428        {
429            return Vector2(
430                ( x + vec.x ) * 0.5f,
431                ( y + vec.y ) * 0.5f );
432        }
433
434        /** Returns true if the vector's scalar components are all greater
435            that the ones of the vector it is compared against.
436        */
437        inline bool operator < ( const Vector2& rhs ) const
438        {
439            if( x < rhs.x && y < rhs.y )
440                return true;
441            return false;
442        }
443
444        /** Returns true if the vector's scalar components are all smaller
445            that the ones of the vector it is compared against.
446        */
447        inline bool operator > ( const Vector2& rhs ) const
448        {
449            if( x > rhs.x && y > rhs.y )
450                return true;
451            return false;
452        }
453
454        /** Sets this vector's components to the minimum of its own and the
455            ones of the passed in vector.
456            @remarks
457                'Minimum' in this case means the combination of the lowest
458                value of x, y and z from both vectors. Lowest is taken just
459                numerically, not magnitude, so -1 < 0.
460        */
461        inline void makeFloor( const Vector2& cmp )
462        {
463            if( cmp.x < x ) x = cmp.x;
464            if( cmp.y < y ) y = cmp.y;
465        }
466
467        /** Sets this vector's components to the maximum of its own and the
468            ones of the passed in vector.
469            @remarks
470                'Maximum' in this case means the combination of the highest
471                value of x, y and z from both vectors. Highest is taken just
472                numerically, not magnitude, so 1 > -3.
473        */
474        inline void makeCeil( const Vector2& cmp )
475        {
476            if( cmp.x > x ) x = cmp.x;
477            if( cmp.y > y ) y = cmp.y;
478        }
479
480        /** Generates a vector perpendicular to this vector (eg an 'up' vector).
481            @remarks
482                This method will return a vector which is perpendicular to this
483                vector. There are an infinite number of possibilities but this
484                method will guarantee to generate one of them. If you need more
485                control you should use the Quaternion class.
486        */
487        inline Vector2 perpendicular(void) const
488        {
489            return Vector2 (-y, x);
490        }
491
492        /** Calculates the 2 dimensional cross-product of 2 vectors, which results
493                        in a single floating point value which is 2 times the area of the triangle.
494        */
495        inline Real crossProduct( const Vector2& rkVector ) const
496        {
497            return x * rkVector.y - y * rkVector.x;
498        }
499
500        /** Generates a new random vector which deviates from this vector by a
501            given angle in a random direction.
502            @remarks
503                This method assumes that the random number generator has already
504                been seeded appropriately.
505            @param angle
506                The angle at which to deviate in radians
507            @return
508                A random vector which deviates from this vector by angle. This
509                vector will not be normalised, normalise it if you wish
510                afterwards.
511        */
512        inline Vector2 randomDeviant(Radian angle) const
513        {
514            angle *= Math::RangeRandom(-1, 1);
515            Real cosa = Math::Cos(angle);
516            Real sina = Math::Sin(angle);
517            return Vector2(cosa * x - sina * y,
518                           sina * x + cosa * y);
519        }
520
521        /** Returns true if this vector is zero length. */
522        inline bool isZeroLength(void) const
523        {
524            Real sqlen = (x * x) + (y * y);
525            return (sqlen < (1e-06 * 1e-06));
526
527        }
528
529        /** As normalise, except that this vector is unaffected and the
530            normalised vector is returned as a copy. */
531        inline Vector2 normalisedCopy(void) const
532        {
533            Vector2 ret = *this;
534            ret.normalise();
535            return ret;
536        }
537
538        /** Calculates a reflection vector to the plane with the given normal .
539        @remarks NB assumes 'this' is pointing AWAY FROM the plane, invert if it is not.
540        */
541        inline Vector2 reflect(const Vector2& normal) const
542        {
543            return Vector2( *this - ( 2 * this->dotProduct(normal) * normal ) );
544        }
545
546                /// Check whether this vector contains valid values
547                inline bool isNaN() const
548                {
549                        return Math::isNaN(x) || Math::isNaN(y);
550                }
551
552                /**      Gets the angle between 2 vectors.
553                @remarks
554                        Vectors do not have to be unit-length but must represent directions.
555                */
556                inline Ogre::Radian angleBetween(const Ogre::Vector2& other) const
557                {               
558                        Ogre::Real lenProduct = length() * other.length();
559                        // Divide by zero check
560                        if(lenProduct < 1e-6f)
561                                lenProduct = 1e-6f;
562               
563                        Ogre::Real f = dotProduct(other) / lenProduct;
564       
565                        f = Ogre::Math::Clamp(f, (Ogre::Real)-1.0, (Ogre::Real)1.0);
566                        return Ogre::Math::ACos(f);
567                }
568
569                /**      Gets the oriented angle between 2 vectors.
570                @remarks
571                        Vectors do not have to be unit-length but must represent directions.
572                        The angle is comprised between 0 and 2 PI.
573                */
574                inline Ogre::Radian angleTo(const Ogre::Vector2& other) const
575                {
576                        Ogre::Radian angle = angleBetween(other);
577               
578                        if (crossProduct(other)<0)                     
579                                angle = (Ogre::Radian)Ogre::Math::TWO_PI - angle;               
580
581                        return angle;
582                }
583
584        // special points
585        static const Vector2 ZERO;
586        static const Vector2 UNIT_X;
587        static const Vector2 UNIT_Y;
588        static const Vector2 NEGATIVE_UNIT_X;
589        static const Vector2 NEGATIVE_UNIT_Y;
590        static const Vector2 UNIT_SCALE;
591
592        /** Function for writing to a stream.
593        */
594        inline _OgreExport friend std::ostream& operator <<
595            ( std::ostream& o, const Vector2& v )
596        {
597            o << "Vector2(" << v.x << ", " << v.y <<  ")";
598            return o;
599        }
600    };
601        /** @} */
602        /** @} */
603
604}
605#endif
Note: See TracBrowser for help on using the repository browser.