PixelLightAPI  .
Vector4.h
Go to the documentation of this file.
00001 /*********************************************************\
00002  *  File: Vector4.h                                      *
00003  *
00004  *  Copyright (C) 2002-2012 The PixelLight Team (http://www.pixellight.org/)
00005  *
00006  *  This file is part of PixelLight.
00007  *
00008  *  PixelLight is free software: you can redistribute it and/or modify
00009  *  it under the terms of the GNU Lesser General Public License as published by
00010  *  the Free Software Foundation, either version 3 of the License, or
00011  *  (at your option) any later version.
00012  *
00013  *  PixelLight is distributed in the hope that it will be useful,
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016  *  GNU Lesser General Public License for more details.
00017  *
00018  *  You should have received a copy of the GNU Lesser General Public License
00019  *  along with PixelLight. If not, see <http://www.gnu.org/licenses/>.
00020 \*********************************************************/
00021 
00022 
00023 #ifndef __PLMATH_VECTOR4_H__
00024 #define __PLMATH_VECTOR4_H__
00025 #pragma once
00026 
00027 
00028 //[-------------------------------------------------------]
00029 //[ Includes                                              ]
00030 //[-------------------------------------------------------]
00031 #include "PLMath/Vector3.h"
00032 
00033 
00034 //[-------------------------------------------------------]
00035 //[ Namespace                                             ]
00036 //[-------------------------------------------------------]
00037 namespace PLMath {
00038 
00039 
00040 //[-------------------------------------------------------]
00041 //[ Classes                                               ]
00042 //[-------------------------------------------------------]
00043 /**
00044 *  @brief
00045 *    4D vector
00046 */
00047 class Vector4 {
00048 
00049 
00050     //[-------------------------------------------------------]
00051     //[ Public definitions                                    ]
00052     //[-------------------------------------------------------]
00053     public:
00054         /**
00055         *  @brief
00056         *    Vector component
00057         */
00058         enum Component {
00059             X = 0,  /**< X component */
00060             Y = 1,  /**< Y component */
00061             Z = 2,  /**< Z component */
00062             W = 3   /**< Z component */
00063         };
00064 
00065 
00066     //[-------------------------------------------------------]
00067     //[ Public static data                                    ]
00068     //[-------------------------------------------------------]
00069     public:
00070         static PLMATH_API const Vector4 Zero;           /**<  0.0,  0.0,  0.0,  0.0 */
00071         static PLMATH_API const Vector4 One;            /**<  1.0,  1.0,  1.0,  1.0 */
00072         static PLMATH_API const Vector4 NegativeOne;    /**< -1.0, -1.0, -1.0, -1.0 */
00073         static PLMATH_API const Vector4 UnitX;          /**<  1.0,  0.0,  0.0,  1.0 */
00074         static PLMATH_API const Vector4 UnitY;          /**<  0.0,  1.0,  0.0,  1.0 */
00075         static PLMATH_API const Vector4 UnitZ;          /**<  0.0,  0.0,  1.0,  1.0 */
00076         static PLMATH_API const Vector4 UnitW;          /**<  0.0,  0.0,  0.0,  1.0 */
00077         static PLMATH_API const Vector4 NegativeUnitX;  /**< -1.0,  0.0,  0.0,  1.0 */
00078         static PLMATH_API const Vector4 NegativeUnitY;  /**<  0.0, -1.0,  0.0,  1.0 */
00079         static PLMATH_API const Vector4 NegativeUnitZ;  /**<  0.0,  0.0, -1.0,  1.0 */
00080         static PLMATH_API const Vector4 NegativeUnitW;  /**<  0.0,  0.0,  0.0, -1.0 */
00081 
00082 
00083     //[-------------------------------------------------------]
00084     //[ Public data                                           ]
00085     //[-------------------------------------------------------]
00086     public:
00087         /**
00088         *  @brief
00089         *    Some direct vertex element accesses
00090         */
00091         union {
00092             /**
00093             *  @brief
00094             *    Vertex element array access
00095             */
00096             float fV[4];
00097 
00098             /**
00099             *  @brief
00100             *    Known vertex element names when dealing with positions or directions
00101             */
00102             struct {
00103                 float x, y, z, w;
00104             };
00105         };
00106 
00107 
00108     //[-------------------------------------------------------]
00109     //[ Public functions                                      ]
00110     //[-------------------------------------------------------]
00111     public:
00112         //[-------------------------------------------------------]
00113         //[ Constructors                                          ]
00114         //[-------------------------------------------------------]
00115         /**
00116         *  @brief
00117         *    Default constructor setting the components to (0, 0, 0, 1)
00118         */
00119         inline Vector4();
00120 
00121         inline Vector4(float fX, float fY, float fZ = 0.0f, float fW = 1.0f);
00122         inline Vector4(const float fV[]);
00123         PLMATH_API Vector4(const Vector2 &vV, float fZ = 0.0f, float fW = 1.0f);
00124         PLMATH_API Vector4(const Vector3 &vV, float fW = 1.0f);
00125         inline Vector4(const Vector4 &vV);
00126         inline Vector4(const PLCore::String &sString);
00127 
00128         //[-------------------------------------------------------]
00129         //[ Destructor                                            ]
00130         //[-------------------------------------------------------]
00131         inline ~Vector4();
00132 
00133         //[-------------------------------------------------------]
00134         //[ Assignment operators                                  ]
00135         //[-------------------------------------------------------]
00136         inline     Vector4 &operator =(const float fV[]);
00137         PLMATH_API Vector4 &operator =(const Vector2 &vV);
00138         PLMATH_API Vector4 &operator =(const Vector3 &vV);
00139         inline     Vector4 &operator =(const Vector4 &vV);
00140 
00141         //[-------------------------------------------------------]
00142         //[ Comparison                                            ]
00143         //[-------------------------------------------------------]
00144         /**
00145         *  @brief
00146         *    Compares two vectors
00147         *
00148         *  @param[in] vV
00149         *    Vector to compare with
00150         *
00151         *  @return
00152         *    'true' if all components are equal, else 'false'
00153         */
00154         inline bool operator ==(const Vector4 &vV) const;
00155 
00156         /**
00157         *  @brief
00158         *    Compares two vectors
00159         *
00160         *  @param[in] vV
00161         *    Vector to compare with
00162         *
00163         *  @return
00164         *    'false' if all components are equal, else 'true'
00165         */
00166         inline bool operator !=(const Vector4 &vV) const;
00167 
00168         /**
00169         *  @brief
00170         *    Compares two vectors lexicographically
00171         *
00172         *  @param[in] vV
00173         *    Vector to compare with
00174         *
00175         *  @return
00176         *    'true' if ALL components of this vector are less, else 'false'
00177         *
00178         *  @note
00179         *    - A lexicographical order for 4-dimensional vectors is used (see http://en.wikipedia.org/wiki/Ordered_vector_space)
00180         */
00181         inline bool operator <(const Vector4 &vV) const;
00182 
00183         /**
00184         *  @brief
00185         *    Compares two vectors lexicographically
00186         *
00187         *  @param[in] vV
00188         *    Vector to compare with
00189         *
00190         *  @return
00191         *    'true' if ALL components of this vector are greater, else 'false'
00192         *
00193         *  @see
00194         *    - "operator <"
00195         */
00196         inline bool operator >(const Vector4 &vV) const;
00197 
00198         /**
00199         *  @brief
00200         *    Compares two vectors lexicographically
00201         *
00202         *  @param[in] vV
00203         *    Vector to compare with
00204         *
00205         *  @return
00206         *    'true' if ALL components of this vector are less or equal, else 'false'
00207         *
00208         *  @see
00209         *    - "operator <"
00210         */
00211         inline bool operator <=(const Vector4 &vV) const;
00212 
00213         /**
00214         *  @brief
00215         *    Compares two vectors lexicographically
00216         *
00217         *  @param[in] vV
00218         *    Vector to compare with
00219         *
00220         *  @return
00221         *    'true' if ALL components of this vector are greater or equal, else 'false'
00222         *
00223         *  @see
00224         *    - "operator <"
00225         */
00226         inline bool operator >=(const Vector4 &vV) const;
00227 
00228         //[-------------------------------------------------------]
00229         //[ Vector                                                ]
00230         //[-------------------------------------------------------]
00231         inline Vector4  operator +(const Vector4 &vV) const;
00232         inline Vector4  operator +(float fN) const;
00233         inline Vector4 &operator +=(const Vector4 &vV);
00234         inline Vector4 &operator +=(float fN);
00235         inline Vector4  operator -() const;
00236         inline Vector4  operator -(const Vector4 &vV) const;
00237         inline Vector4  operator -(float fN) const;
00238         inline Vector4 &operator -=(const Vector4 &vV);
00239         inline Vector4 &operator -=(float fN);
00240 
00241         /**
00242         *  @brief
00243         *    Per component multiplication
00244         *
00245         *  @param[in] vV
00246         *    Vector to multiplicate with
00247         *
00248         *  @return
00249         *    The resulting vector
00250         */
00251         inline Vector4 operator *(const Vector4 &vV) const;
00252         inline Vector4 operator *(float fS) const;
00253 
00254         /**
00255         *  @brief
00256         *    Per component multiplication
00257         *
00258         *  @param[in] vV
00259         *    Vector to multiplicate with
00260         *
00261         *  @return
00262         *    This vector which is now the resulting vector
00263         */
00264         inline Vector4 &operator *=(const Vector4 &vV);
00265         inline Vector4 &operator *=(float fS);
00266 
00267         /**
00268         *  @brief
00269         *    Transforms the vector
00270         *
00271         *  @param[in] mTrans
00272         *    Matrix which transforms the vector
00273         *
00274         *  @return
00275         *    This vector which is now the resulting vector
00276         */
00277         PLMATH_API Vector4 &operator *=(const Matrix4x4 &mTrans);
00278 
00279         /**
00280         *  @brief
00281         *    Per component division
00282         *
00283         *  @param[in] vV
00284         *    Vector to divide through
00285         *
00286         *  @return
00287         *    The resulting vector
00288         */
00289         inline Vector4 operator /(const Vector4 &vV) const;
00290         inline Vector4 operator /(float fS) const;
00291 
00292         /**
00293         *  @brief
00294         *    Per component division
00295         *
00296         *  @param[in] vV
00297         *    Vector to divide through
00298         *
00299         *  @return
00300         *    This vector which is now the resulting vector
00301         */
00302         inline Vector4 &operator /=(const Vector4 &vV);
00303         inline Vector4 &operator /=(float fS);
00304 
00305         //[-------------------------------------------------------]
00306         //[ Get and set                                           ]
00307         //[-------------------------------------------------------]
00308         PLMATH_API operator Vector3();
00309         inline operator float *();
00310         inline operator const float *() const;
00311         inline float &operator [](int nIndex);
00312         inline const float &operator [](int nIndex) const;
00313         inline void     GetXYZW(float &fX, float &fY, float &fZ, float &fW) const;
00314         inline float    GetX() const;
00315         inline float    GetY() const;
00316         inline float    GetZ() const;
00317         inline float    GetW() const;
00318         inline void     SetXYZ(float fX = 0.0f, float fY = 0.0f, float fZ = 0.0f);
00319         inline void     SetXYZ(const float fV[]);
00320         PLMATH_API void SetXYZ(const Vector3 &vV);
00321         inline void     SetXYZW(float fX = 0.0f, float fY = 0.0f, float fZ = 0.0f, float fW = 1.0f);
00322         inline void     SetXYZW(const float fV[]);
00323         PLMATH_API void SetXYZW(const Vector3 &vV, float fW = 1.0f);
00324         inline void     SetX(float fX = 0.0f);
00325         inline void     SetY(float fY = 0.0f);
00326         inline void     SetZ(float fZ = 0.0f);
00327         inline void     SetW(float fW = 1.0f);
00328         inline void     IncXYZW(float fX = 0.0f, float fY = 0.0f, float fZ = 0.0f, float fW = 0.0f);
00329         inline void     IncXYZW(const float fV[]);
00330         inline void     IncX(float fX);
00331         inline void     IncY(float fY);
00332         inline void     IncZ(float fZ);
00333         inline void     IncW(float fW);
00334 
00335         //[-------------------------------------------------------]
00336         //[ Misc                                                  ]
00337         //[-------------------------------------------------------]
00338         /**
00339         *  @brief
00340         *    Returns whether the vector is null or not
00341         *
00342         *  @return
00343         *    'true' if the vector is null, else 'false'
00344         */
00345         inline bool IsNull() const;
00346 
00347         /**
00348         *  @brief
00349         *    Returns whether the vector is packed (within range of 0-1) or not
00350         *
00351         *  @return
00352         *    'true' if the vector is packed, else 'false'
00353         */
00354         inline bool IsPacked() const;
00355 
00356         /**
00357         *  @brief
00358         *    Packs/clamps the vector into a range of 0-1
00359         *
00360         *  @remarks
00361         *    First, the vector is normalized - now each component is between -1 and 1.
00362         *    This normalized vector is scaled by 0.5 and 0.5 is added.
00363         */
00364         inline void PackTo01();
00365 
00366         /**
00367         *  @brief
00368         *    Returns a vector which is packed/clamped into the range of 0-1
00369         *
00370         *  @return
00371         *    The packed vector
00372         *
00373         *  @see
00374         *    - PackTo01()
00375         */
00376         inline Vector4 GetPackedTo01() const;
00377 
00378         /**
00379         *  @brief
00380         *    Unpacks the packed vector into a range of -1 to 1
00381         *
00382         *  @remarks
00383         *    The vector is scaled by 2 and 1 is subtracted.
00384         *
00385         *  @note
00386         *    - There's no internal check whether the vector is packed or not, you can do this
00387         *      by yourself using the IsPacked() function
00388         */
00389         inline void UnpackFrom01();
00390 
00391         /**
00392         *  @brief
00393         *    Returns a unpacked vector of the range of -1 to 1
00394         *
00395         *  @return
00396         *    The unpacked vector
00397         *
00398         *  @see
00399         *    - UnpackFrom01()
00400         */
00401         inline Vector4 GetUnpackedFrom01() const;
00402 
00403         /**
00404         *  @brief
00405         *    Returns the smallest component
00406         *
00407         *  @return
00408         *    The smallest component
00409         *
00410         *  @remarks
00411         *    If x is 1, y is 2, z is 3 and w is 4, this function will return the x component.
00412         */
00413         inline Component GetSmallestComponent() const;
00414 
00415         /**
00416         *  @brief
00417         *    Returns the value of the smallest component
00418         *
00419         *  @return
00420         *    The value of the smallest component
00421         *
00422         *  @see
00423         *    - GetSmallestComponent() above
00424         */
00425         inline float GetSmallestValue() const;
00426 
00427         /**
00428         *  @brief
00429         *    Returns the greatest component
00430         *
00431         *  @return
00432         *    The greatest component
00433         *
00434         *  @remarks
00435         *    If x is 1, y is 2, z is 3 and w is 4, this function will return the w component.
00436         */
00437         inline Component GetGreatestComponent() const;
00438 
00439         /**
00440         *  @brief
00441         *    Returns the value of the greatest component
00442         *
00443         *  @return
00444         *    The value of the greatest component
00445         *
00446         *  @see
00447         *    - GetGreatestComponent() above
00448         */
00449         inline float GetGreatestValue() const;
00450 
00451         /**
00452         *  @brief
00453         *    Inverts the vector
00454         *
00455         *  @remarks
00456         *    v'.x = -v.x\n
00457         *    v'.y = -v.y\n
00458         *    v'.z = -v.z\n
00459         *    v'.w = -v.w
00460         */
00461         inline void Invert();
00462 
00463         /**
00464         *  @brief
00465         *    Returns the inverted vector
00466         *
00467         *  @return
00468         *    Inverted vector
00469         *
00470         *  @see
00471         *    - Invert()
00472         */
00473         inline Vector4 GetInverted() const;
00474 
00475         /**
00476         *  @brief
00477         *    Returns the length of the vector (also called magnitude)
00478         *
00479         *  @return
00480         *    Vector length
00481         *
00482         *  @remarks
00483         *    l = sqrt(x*x + y*y + z*z + w*w)
00484         */
00485         inline float GetLength() const;
00486 
00487         /**
00488         *  @brief
00489         *    Returns the squared length of the vector (also called norm)
00490         *
00491         *  @return
00492         *    Squared vector length
00493         *
00494         *  @remarks
00495         *    l = x*x + y*y + z*z + w*w
00496         *
00497         *  @note
00498         *    - For better performance, use this function instead of GetLength() whenever
00499         *      possible. You can often work with squared lengths instead of the 'real' ones.
00500         */
00501         inline float GetSquaredLength() const;
00502 
00503         /**
00504         *  @brief
00505         *    Sets the vector to the given length
00506         *
00507         *  @param[in] fLength
00508         *    Length to set
00509         *
00510         *  @remarks
00511         *    v' = v*l/sqrt(x*x + y*y + z*z + w*w)
00512         */
00513         inline void SetLength(float fLength = 1.0f);
00514 
00515         /**
00516         *  @brief
00517         *    Normalizes the vector
00518         *
00519         *  @return
00520         *    This instance
00521         *
00522         *  @remarks
00523         *    v' = v*1/sqrt(x*x + y*y + z*z + w*w)
00524         *
00525         *  @note
00526         *    - This will set the vector to a length of 1 (same as SetLength(1.0f) :)
00527         *    - A normalized vector is called 'unit vector'
00528         */
00529         inline Vector4 &Normalize();
00530 
00531         /**
00532         *  @brief
00533         *    Returns the normalized vector
00534         *
00535         *  @return
00536         *    Normalized vector
00537         *
00538         *  @see
00539         *    - Normalize()
00540         */
00541         inline Vector4 GetNormalized() const;
00542 
00543         /**
00544         *  @brief
00545         *    Returns the distance to another vector
00546         *
00547         *  @param[in] vV
00548         *    The other vector
00549         *
00550         *  @return
00551         *    Distance to the other vector
00552         *
00553         *  @remarks
00554         *    dx = v2.x-v1.x\n
00555         *    dy = v2.y-v1.y\n
00556         *    dz = v2.z-v1.z\n
00557         *    dw = v2.w-v1.w\n
00558         *    d  = sqrt(dx*dx + dy*dy + dz*dz + dw*dw)
00559         */
00560         inline float GetDistance(const Vector4 &vV) const;
00561 
00562         /**
00563         *  @brief
00564         *    Returns the squared distance to another vector
00565         *
00566         *  @param[in] vV
00567         *    The other vector
00568         *
00569         *  @return
00570         *    Squared distance to the other vector
00571         *
00572         *  @remarks
00573         *    dx = v2.x-v1.x\n
00574         *    dy = v2.y-v1.y\n
00575         *    dz = v2.z-v1.z\n
00576         *    dw = v2.w-v1.w\n
00577         *    d  = dx*dx + dy*dy + dz*dz + dw*dw
00578         *
00579         *  @note
00580         *    - For better performance, use this function instead of GetDistance() whenever
00581         *      possible. You can often work with squared distances instead of the 'real' ones.
00582         */
00583         inline float GetSquaredDistance(const Vector4 &vV) const;
00584 
00585         /**
00586         *  @brief
00587         *    Returns the dot product of two vectors
00588         *
00589         *  @param[in] vV
00590         *    Second vector
00591         *
00592         *  @return
00593         *    Dot product of the vectors
00594         *
00595         *  @remarks
00596         *    d = this->x*vV.x + this->y*vV.y + this->z*vV.z + this->w*vV.w
00597         *
00598         *  @note
00599         *    - The dot product is also known as 'scalar product' or 'inner product'
00600         *    - The dot product of a vector with itself is equal to it's squared length, so it's possible to
00601         *      use GetSquaredLength() instead of v.DotProduct(v)
00602         *    - The dot product is commutative
00603         *    - If the two vectors are perpendicular, their dot product equals zero
00604         *    - If the angle between the two vectors is acute (< 90 degrees) the dot product will be positive,
00605         *      if the angle is obtuse (> 90 degrees) the dot product will be negative
00606         *    - Geometric definition: a.DotProduct(b) = a.GetLength() * b.GetLength() * cos(r)
00607         *
00608         *  @see
00609         *    - GetAngle()
00610         */
00611         inline float DotProduct(const Vector4 &vV) const;
00612 
00613         /**
00614         *  @brief
00615         *    Project vector a onto another vector b
00616         *
00617         *  @param[in] vA
00618         *    Vector to project
00619         *  @param[in] vB
00620         *    Vector to project onto
00621         *
00622         *  @remarks
00623         *    @code
00624         *            ^.
00625         *           / .
00626         *          /  .
00627         *       a /   .
00628         *        /    .                                  a.DotProduct(b)
00629         *       /     .                  projb(a) = b * -----------------
00630         *      /      .                                  b.DotProduct(b)
00631         *     /       .
00632         *     --->____.
00633         *      b      ^= projb(a)
00634         *    @endcode
00635         *
00636         *  @return
00637         *    The resulting projection vector
00638         */
00639         inline Vector4 ProjectVector(const Vector4 &vA, const Vector4 &vB) const;
00640 
00641         /**
00642         *  @brief
00643         *    Calculates the angle between two vectors
00644         *
00645         *  @param[in] vV
00646         *    Second vector
00647         *
00648         *  @return
00649         *    The angle between the two vectors (in radians)
00650         *
00651         *  @remarks
00652         *    @code
00653         *                    v1.DotProduct(v2)
00654         *     cos A = --------------------------------
00655         *              v1.GetLength() * v2.GetLength()
00656         *    @endcode
00657         *
00658         *  @note
00659         *    - If the two vectors are normalized, you can also use acos(DotProduct()) which is
00660         *      in this case more performant
00661         */
00662         inline float GetAngle(const Vector4 &vV) const;
00663 
00664         /**
00665         *  @brief
00666         *    Calculates a normalized projection vector
00667         *
00668         *  @param[in] vX
00669         *    The first vector to calculate the projection from
00670         *  @param[in] vN
00671         *    The second vector to calculate the projection from
00672         *
00673         *  @return
00674         *    Reference to the vector itself which is now the resulting projection
00675         */
00676         PLMATH_API Vector4 &GetProjection(const Vector4 &vX, const Vector4 &vN);
00677 
00678         /**
00679         *  @brief
00680         *    Project the vector on to the plane created by two direction vectors
00681         *
00682         *  @param[in] vV1
00683         *    First of the two direction vectors creating the plane
00684         *  @param[in] vV2
00685         *    Second of the two direction vectors creating the plane
00686         *
00687         *  @return
00688         *    Reference to the vector itself which is now the resulting projection vector
00689         *
00690         *  @note
00691         *    - vV1 and vV2 MUST be perpendicular to each other
00692         */
00693         PLMATH_API Vector4 &ProjectPlane(const Vector4 &vV1, const Vector4 &vV2);
00694 
00695         /**
00696         *  @brief
00697         *    To string
00698         *
00699         *  @return
00700         *    String with the data
00701         */
00702         PLMATH_API PLCore::String ToString() const;
00703 
00704         /**
00705         *  @brief
00706         *    From string
00707         *
00708         *  @param[in] sString
00709         *    String with the data
00710         */
00711         PLMATH_API bool FromString(const PLCore::String &sString);
00712 
00713 
00714 };
00715 
00716 
00717 //[-------------------------------------------------------]
00718 //[ Namespace                                             ]
00719 //[-------------------------------------------------------]
00720 } // PLMath
00721 
00722 
00723 //[-------------------------------------------------------]
00724 //[ Implementation                                        ]
00725 //[-------------------------------------------------------]
00726 #include "PLMath/Vector4.inl"
00727 #include "PLMath/TypeVector4.inl"
00728 
00729 
00730 #endif // __PLMATH_VECTOR4_H__


PixelLight PixelLight 0.9.11-R1
Copyright (C) 2002-2012 by The PixelLight Team
Last modified Thu Feb 23 2012 14:09:01
The content of this PixelLight document is published under the
Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported