vector2.h 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /* $Header: /Commando/Code/wwmath/vector2.h 19 9/01/00 5:30p Ian_l $ */
  19. /***********************************************************************************************
  20. *** Confidential - Westwood Studios ***
  21. ***********************************************************************************************
  22. * *
  23. * Project Name : Westwood 3D *
  24. * *
  25. * File Name : VECTOR2.H *
  26. * *
  27. * Programmer : Greg Hjelstrom *
  28. * *
  29. * Start Date : 02/24/97 *
  30. * *
  31. * Last Update : February 24, 1997 [GH] *
  32. * *
  33. *---------------------------------------------------------------------------------------------*
  34. * Functions: *
  35. * Scalar Division Operator -- Divide a vector by a scalar *
  36. * Scalar Multiply Operator -- Multiply a vector by a scalar *
  37. * Vector Addition Operator -- Add two vectors *
  38. * Vector Subtraction Operator -- Subract two vectors *
  39. * Vector Inner Product Operator -- Compute the inner or dot product *
  40. * Vector Equality Operator -- Detemine if two vectors are identical *
  41. * Equal_Within_Epsilon -- Determine if two vectors are identical within *
  42. * Vector Inequality Operator -- Detemine if two vectors are identical *
  43. * Swap -- swap two Vector2's *
  44. * Vector2::Is_Valid -- Verifies that all components are valid floats *
  45. * Vector2::Update_Min -- sets each component of the vector to the min of this and a. *
  46. * Vector2::Update_Max -- sets each component of the vector to the max of this and a. *
  47. * Vector2::Scale -- multiply components of a vector by independant scaling factors. *
  48. * Vector2::Lerp -- linearly interpolates two Vector2's *
  49. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  50. #if defined(_MSC_VER)
  51. #pragma once
  52. #endif
  53. #ifndef VECTOR2_H
  54. #define VECTOR2_H
  55. #include "always.h"
  56. #include "wwmath.h"
  57. #include <math.h>
  58. /*
  59. ** 2-Dimensional Vectors
  60. */
  61. class Vector2
  62. {
  63. public:
  64. union {
  65. float X;
  66. float U;
  67. };
  68. union {
  69. float Y;
  70. float V;
  71. };
  72. // Constructors
  73. Vector2(void) {};
  74. Vector2(const Vector2 & v) { X = v.X; Y = v.Y; }
  75. Vector2(float x, float y) { X = x; Y = y; }
  76. Vector2(const float vector[2]) { X = vector[0]; Y = vector[1]; }
  77. // Assignment
  78. Vector2 & operator = (const Vector2 & v) { X = v[0]; Y = v[1]; return *this; }
  79. void Set(float x, float y) { X = x; Y = y; }
  80. void Set(const Vector2 & v) { X = v.X; Y = v.Y; }
  81. // Array access
  82. float & operator [](int i) { return (&X)[i]; }
  83. const float & operator [](int i) const { return (&X)[i]; }
  84. // normalize, compute length
  85. void Normalize(void);
  86. float Length(void) const;
  87. float Length2(void) const;
  88. // unary operators
  89. Vector2 operator-() const { return Vector2(-X,-Y); }
  90. Vector2 operator+() const { return *this; }
  91. Vector2 & operator += (const Vector2 & v) { X += v.X; Y += v.Y; return *this; }
  92. Vector2 & operator -= (const Vector2 & v) { X -= v.X; Y -= v.Y; return *this; }
  93. Vector2 & operator *= (float k) { X = (float)(X*k); Y=(float)(Y*k); return *this; }
  94. Vector2 & operator /= (float k) { k=1.0f/k; X*=k; Y*=k; return *this; }
  95. // scalar multiplication, division
  96. friend Vector2 operator * (const Vector2 &a,float k);
  97. friend Vector2 operator * (float k,const Vector2 &a);
  98. friend Vector2 operator / (const Vector2 &a,float k);
  99. // vector addition,subtraction
  100. friend Vector2 operator + (const Vector2 &a,const Vector2 &b);
  101. friend Vector2 operator - (const Vector2 &a,const Vector2 &b);
  102. // dot product / inner product
  103. friend float operator * (const Vector2 &a,const Vector2 &b);
  104. static float Dot_Product(const Vector2 &a,const Vector2 &b);
  105. // dot product between a and perpendicular vector to b
  106. static float Perp_Dot_Product(const Vector2 &a,const Vector2 &b);
  107. // Equality operators
  108. friend bool operator == (const Vector2 &a,const Vector2 &b);
  109. friend bool operator != (const Vector2 &a,const Vector2 &b);
  110. friend bool Equal_Within_Epsilon(const Vector2 &a,const Vector2 &b,float epsilon);
  111. // Rotation
  112. void Rotate(float theta);
  113. void Rotate(float s, float c);
  114. bool Rotate_Towards_Vector(Vector2 &target, float max_theta, bool & positive_turn);
  115. bool Rotate_Towards_Vector(Vector2 &target, float max_s, float max_c, bool & positive_turn);
  116. // verify that none of the members of this vector are invalid floats
  117. bool Is_Valid(void) const;
  118. // make this vector the min or max of itself and the passed vector
  119. void Update_Min (const Vector2 & a);
  120. void Update_Max (const Vector2 & a);
  121. void Scale (float a, float b);
  122. static float Distance(const Vector2 &p1, const Vector2 &p2);
  123. static float Quick_Distance(const Vector2 &p1, const Vector2 &p2);
  124. // interpolate between two Vector2's
  125. static void Lerp(const Vector2 & a,const Vector2 & b,float t,Vector2 * set_result);
  126. };
  127. /**************************************************************************
  128. * Scalar Multiply Operator -- Multiply a vector by a scalar *
  129. * *
  130. * INPUT: *
  131. * *
  132. * OUTPUT: *
  133. * *
  134. * WARNINGS: *
  135. * *
  136. * HISTORY: *
  137. * 02/24/1997 GH : Created. *
  138. *========================================================================*/
  139. inline Vector2 operator * (const Vector2 &a,float k)
  140. {
  141. return Vector2((a[0] * k),(a[1] * k));
  142. }
  143. inline Vector2 operator * (float k, const Vector2 &a)
  144. {
  145. return Vector2((a[0] * k),(a[1] * k));
  146. }
  147. /**************************************************************************
  148. * Scalar Division Operator -- Divide a vector by a scalar *
  149. * *
  150. * INPUT: *
  151. * *
  152. * OUTPUT: *
  153. * *
  154. * WARNINGS: *
  155. * *
  156. * HISTORY: *
  157. *========================================================================*/
  158. inline Vector2 operator / (const Vector2 &a,float k)
  159. {
  160. float ook=1.0f/k;
  161. return Vector2((a[0] * ook),(a[1] * ook));
  162. }
  163. /**************************************************************************
  164. * Vector Addition Operator -- Add two vectors *
  165. * *
  166. * INPUT: *
  167. * *
  168. * OUTPUT: *
  169. * *
  170. * WARNINGS: *
  171. * *
  172. * HISTORY: *
  173. * 02/24/1997 GH : Created. *
  174. *========================================================================*/
  175. inline Vector2 operator + (const Vector2 &a,const Vector2 &b)
  176. {
  177. return Vector2(
  178. a.X + b.X,
  179. a.Y + b.Y
  180. );
  181. }
  182. /**************************************************************************
  183. * Vector Subtraction Operator -- Subract two vectors *
  184. * *
  185. * INPUT: *
  186. * *
  187. * OUTPUT: *
  188. * *
  189. * WARNINGS: *
  190. * *
  191. * HISTORY: *
  192. * 02/24/1997 GH : Created. *
  193. *========================================================================*/
  194. inline Vector2 operator - (const Vector2 &a,const Vector2 &b)
  195. {
  196. return Vector2(
  197. a.X - b.X,
  198. a.Y - b.Y
  199. );
  200. }
  201. /**************************************************************************
  202. * Vector Inner Product -- Compute the inner or dot product of two vector *
  203. * *
  204. * INPUT: *
  205. * *
  206. * OUTPUT: *
  207. * *
  208. * WARNINGS: *
  209. * *
  210. * HISTORY: *
  211. *========================================================================*/
  212. inline float operator * (const Vector2 &a,const Vector2 &b)
  213. {
  214. return a.X*b.X + a.Y*b.Y;
  215. }
  216. inline float Vector2::Dot_Product(const Vector2 &a,const Vector2 &b)
  217. {
  218. return a*b;
  219. }
  220. inline float Vector2::Perp_Dot_Product(const Vector2 &a,const Vector2 &b)
  221. {
  222. return a.X * -b.Y + a.Y * b.X;
  223. }
  224. /**************************************************************************
  225. * Vector Equality Operator -- Detemine if two vectors are identical *
  226. * *
  227. * INPUT: *
  228. * *
  229. * OUTPUT: *
  230. * *
  231. * WARNINGS: *
  232. * *
  233. * HISTORY: *
  234. *========================================================================*/
  235. inline bool operator == (const Vector2 &a,const Vector2 &b)
  236. {
  237. return ( (a[0] == b[0]) && (a[1] == b[1]));
  238. }
  239. /**************************************************************************
  240. * Vector Inequality Operator -- Detemine if two vectors are identical *
  241. * *
  242. * INPUT: *
  243. * *
  244. * OUTPUT: *
  245. * *
  246. * WARNINGS: *
  247. * *
  248. * HISTORY: *
  249. *========================================================================*/
  250. inline bool operator != (const Vector2 &a,const Vector2 &b)
  251. {
  252. return ( (a[0] != b[0]) || (a[1] != b[1]));
  253. }
  254. /**************************************************************************
  255. * Equal_Within_Epsilon -- Determine if two vectors are identical within e*
  256. * *
  257. * INPUT: *
  258. * *
  259. * OUTPUT: *
  260. * *
  261. * WARNINGS: *
  262. * *
  263. * HISTORY: *
  264. *========================================================================*/
  265. inline bool Equal_Within_Epsilon(const Vector2 &a,const Vector2 &b,float epsilon)
  266. {
  267. return( (WWMath::Fabs(a.X - b.X) < epsilon) && (WWMath::Fabs(a.Y - b.Y) < epsilon) );
  268. }
  269. /**************************************************************************
  270. * Vector2::Normalize -- Normalizes the vector. *
  271. * *
  272. * INPUT: *
  273. * *
  274. * OUTPUT: *
  275. * *
  276. * WARNINGS: *
  277. * *
  278. * HISTORY: *
  279. *========================================================================*/
  280. inline void Vector2::Normalize()
  281. {
  282. float len2 = Length2();
  283. if (len2 != 0.0f) {
  284. float oolen = WWMath::Inv_Sqrt(len2);
  285. X *= oolen;
  286. Y *= oolen;
  287. }
  288. }
  289. inline Vector2 Normalize(const Vector2 & vec)
  290. {
  291. float len2 = vec.Length2();
  292. if (len2 != 0.0f) {
  293. float oolen = WWMath::Inv_Sqrt(len2);
  294. return vec / oolen;
  295. }
  296. }
  297. /**************************************************************************
  298. * Vector2::Length -- Returns the length of the vector *
  299. * *
  300. * INPUT: *
  301. * *
  302. * OUTPUT: *
  303. * *
  304. * WARNINGS: *
  305. * *
  306. * HISTORY: *
  307. *========================================================================*/
  308. inline float Vector2::Length() const
  309. {
  310. return (float)WWMath::Sqrt(Length2());
  311. }
  312. /**************************************************************************
  313. * Vector2::Length -- Returns the square of the length of the vector *
  314. * *
  315. * INPUT: *
  316. * *
  317. * OUTPUT: *
  318. * *
  319. * WARNINGS: *
  320. * *
  321. * HISTORY: *
  322. *========================================================================*/
  323. inline float Vector2::Length2() const
  324. {
  325. return (X*X + Y*Y);
  326. }
  327. /**************************************************************************
  328. * Vector2::Rotate -- Rotate vector *
  329. * *
  330. * INPUT: *
  331. * float theta - angle to rotate *
  332. * *
  333. * OUTPUT: *
  334. * *
  335. * WARNINGS: *
  336. * *
  337. * HISTORY: *
  338. *========================================================================*/
  339. inline void Vector2::Rotate(float theta)
  340. {
  341. Rotate(sin(theta), cos(theta));
  342. }
  343. /**************************************************************************
  344. * Vector2::Rotate -- Rotate vector *
  345. * *
  346. * INPUT: *
  347. * s - sine of the angle *
  348. * c - cosine of the angle *
  349. * *
  350. * OUTPUT: *
  351. * *
  352. * WARNINGS: *
  353. * *
  354. * HISTORY: *
  355. *========================================================================*/
  356. inline void Vector2::Rotate(float s, float c)
  357. {
  358. float new_x = X * c + Y * -s;
  359. float new_y = X * s + Y * c;
  360. X = new_x;
  361. Y = new_y;
  362. }
  363. /**************************************************************************
  364. * Vector2::Rotate -- Rotate towards given vector (stop on reaching it) *
  365. * *
  366. * INPUT: *
  367. * float theta - angle to rotate *
  368. * *
  369. * OUTPUT: *
  370. * bool - true if we have reached the desired vector *
  371. * *
  372. * WARNINGS: *
  373. * This function assumes both vectors are normalized! *
  374. * *
  375. * HISTORY: *
  376. *========================================================================*/
  377. inline bool Vector2::Rotate_Towards_Vector(Vector2 &target, float max_theta, bool & positive_turn)
  378. {
  379. return Rotate_Towards_Vector(target, sin(max_theta), cos(max_theta), positive_turn);
  380. }
  381. /**************************************************************************
  382. * Vector2::Rotate -- Rotate towards given vector (stop on reaching it) *
  383. * *
  384. * INPUT: *
  385. * s - sine of the angle *
  386. * c - cosine of the angle *
  387. * *
  388. * OUTPUT: *
  389. * bool - true if we have reached the desired vector *
  390. * *
  391. * WARNINGS: *
  392. * This function assumes both vectors are normalized! *
  393. * *
  394. * HISTORY: *
  395. *========================================================================*/
  396. inline bool Vector2::Rotate_Towards_Vector(Vector2 &target, float max_s, float max_c, bool & positive_turn)
  397. {
  398. bool return_value = false;
  399. positive_turn = Vector2::Perp_Dot_Product(target, *this) > 0.0f;
  400. if (Vector2::Dot_Product(*this, target) >= max_c) {
  401. Set(target);
  402. return_value = true;
  403. } else {
  404. // Determine turn direction and rotate accordingly.
  405. if (positive_turn) {
  406. Rotate(max_s, max_c);
  407. } else {
  408. Rotate(-max_s, max_c);
  409. }
  410. }
  411. return return_value;
  412. }
  413. /***********************************************************************************************
  414. * Swap -- swap two Vector2's *
  415. * *
  416. * INPUT: *
  417. * *
  418. * OUTPUT: *
  419. * *
  420. * WARNINGS: *
  421. * *
  422. * HISTORY: *
  423. * 08/11/1997 GH : Created. *
  424. *=============================================================================================*/
  425. inline void Swap(Vector2 & a,Vector2 & b)
  426. {
  427. Vector2 tmp(a);
  428. a = b;
  429. b = tmp;
  430. }
  431. /***********************************************************************************************
  432. * Vector2::Is_Valid -- Verifies that all components are valid floats *
  433. * *
  434. * INPUT: *
  435. * *
  436. * OUTPUT: *
  437. * *
  438. * WARNINGS: *
  439. * *
  440. * HISTORY: *
  441. * 10/18/99 gth : Created. *
  442. *=============================================================================================*/
  443. inline bool Vector2::Is_Valid(void) const
  444. {
  445. return (WWMath::Is_Valid_Float(X) && WWMath::Is_Valid_Float(Y));
  446. }
  447. /***********************************************************************************************
  448. * Vector2::Update_Min -- Set each component of the vector to the min of this and a. *
  449. * *
  450. * INPUT: *
  451. * *
  452. * OUTPUT: *
  453. * *
  454. * WARNINGS: *
  455. * *
  456. * HISTORY: *
  457. * 06/12/00 IML : Created. *
  458. *=============================================================================================*/
  459. inline void Vector2::Update_Min (const Vector2 & a)
  460. {
  461. if (a.X < X) X = a.X;
  462. if (a.Y < Y) Y = a.Y;
  463. }
  464. /***********************************************************************************************
  465. * Vector2::Update_Max -- Set each component of the vector to the max of this and a. *
  466. * *
  467. * INPUT: *
  468. * *
  469. * OUTPUT: *
  470. * *
  471. * WARNINGS: *
  472. * *
  473. * HISTORY: *
  474. * 06/12/00 IML : Created. *
  475. *=============================================================================================*/
  476. inline void Vector2::Update_Max (const Vector2 & a)
  477. {
  478. if (a.X > X) X = a.X;
  479. if (a.Y > Y) Y = a.Y;
  480. }
  481. /***********************************************************************************************
  482. * Vector2::Scale -- multiply components of a vector by independant scaling factors. *
  483. * *
  484. * INPUT: *
  485. * *
  486. * OUTPUT: *
  487. * *
  488. * WARNINGS: *
  489. * *
  490. * HISTORY: *
  491. * 06/19/2000 IML : Created. *
  492. *=============================================================================================*/
  493. inline void Vector2::Scale (float a, float b)
  494. {
  495. X *= a;
  496. Y *= b;
  497. }
  498. /***********************************************************************************************
  499. * Quick_Distance -- Fast but inaccurate 2D distance calculation. *
  500. * *
  501. * *
  502. * *
  503. * *
  504. * HISTORY: *
  505. * 11/29/1999MLL: Created. *
  506. *=============================================================================================*/
  507. inline float Quick_Distance(float x1, float y1, float x2, float y2)
  508. {
  509. // From Graphic Gems I.
  510. float x_diff = x1 - x2;
  511. float y_diff = y1 - y2;
  512. WWMath::Fabs(x_diff);
  513. WWMath::Fabs(y_diff);
  514. if (x_diff > y_diff)
  515. {
  516. return ((y_diff / 2) + x_diff);
  517. }
  518. else
  519. {
  520. return ((x_diff / 2) + y_diff);
  521. }
  522. }
  523. inline float Vector2::Quick_Distance(const Vector2 &a, const Vector2 &b)
  524. {
  525. return ::Quick_Distance(a.X, a.Y, b.X, b.Y);
  526. }
  527. /***********************************************************************************************
  528. * Distance -- Accurate distance 2D calculation. *
  529. * *
  530. * *
  531. * *
  532. * *
  533. * HISTORY: *
  534. * 11/29/1999MLL: Created. *
  535. *=============================================================================================*/
  536. inline float Vector2::Distance(const Vector2 &a, const Vector2 &b)
  537. {
  538. Vector2 temp;
  539. temp = a - b;
  540. return (temp.Length());
  541. }
  542. inline float Distance(float x1, float y1, float x2, float y2)
  543. {
  544. float x_diff = x1 - x2;
  545. float y_diff = y1 - y2;
  546. return (WWMath::Sqrt((x_diff * x_diff) + (y_diff * y_diff)));
  547. }
  548. /***********************************************************************************************
  549. * Vector2::Lerp -- linearly interpolates two Vector2's *
  550. * *
  551. * INPUT: *
  552. * *
  553. * OUTPUT: *
  554. * *
  555. * WARNINGS: *
  556. * *
  557. * HISTORY: *
  558. * 4/14/2000 gth : Created. *
  559. *=============================================================================================*/
  560. inline void Vector2::Lerp(const Vector2 & a,const Vector2 & b,float t,Vector2 * set_result)
  561. {
  562. assert(set_result != NULL);
  563. set_result->X = (a.X + (b.X - a.X)*t);
  564. set_result->Y = (a.Y + (b.Y - a.Y)*t);
  565. }
  566. #endif /* VECTOR2_H */