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