Vector2Float.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951
  1. #region --- License ---
  2. /*
  3. Copyright (c) 2006 - 2008 The Open Toolkit library.
  4. Permission is hereby granted, free of charge, to any person obtaining a copy of
  5. this software and associated documentation files (the "Software"), to deal in
  6. the Software without restriction, including without limitation the rights to
  7. use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  8. of the Software, and to permit persons to whom the Software is furnished to do
  9. so, subject to the following conditions:
  10. The above copyright notice and this permission notice shall be included in all
  11. copies or substantial portions of the Software.
  12. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  15. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  16. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  17. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  18. SOFTWARE.
  19. */
  20. #endregion --- License ---
  21. using System;
  22. using System.Runtime.InteropServices;
  23. namespace MatterHackers.VectorMath
  24. {
  25. /// <summary>Represents a 2D vector using two double-precision floating-point numbers.</summary>
  26. [Serializable]
  27. [StructLayout(LayoutKind.Sequential)]
  28. public struct Vector2Float : IEquatable<Vector2Float>
  29. {
  30. #region Fields
  31. /// <summary>The X coordinate of this instance.</summary>
  32. public float X;
  33. /// <summary>The Y coordinate of this instance.</summary>
  34. public float Y;
  35. /// <summary>
  36. /// Defines a unit-length Vector2d that points towards the X-axis.
  37. /// </summary>
  38. public static Vector2Float UnitX = new Vector2Float(1, 0);
  39. /// <summary>
  40. /// Defines a unit-length Vector2d that points towards the Y-axis.
  41. /// </summary>
  42. public static Vector2Float UnitY = new Vector2Float(0, 1);
  43. /// <summary>
  44. /// Defines a zero-length Vector2d.
  45. /// </summary>
  46. public static Vector2Float Zero = new Vector2Float(0, 0);
  47. /// <summary>
  48. /// Defines an instance with all components set to 1.
  49. /// </summary>
  50. public static readonly Vector2Float One = new Vector2Float(1, 1);
  51. /// <summary>
  52. /// Defines the size of the Vector2d struct in bytes.
  53. /// </summary>
  54. public static readonly int SizeInBytes = Marshal.SizeOf(new Vector2Float());
  55. #endregion Fields
  56. #region Constructors
  57. /// <summary>Constructs left vector with the given coordinates.</summary>
  58. /// <param name="x">The X coordinate.</param>
  59. /// <param name="y">The Y coordinate.</param>
  60. public Vector2Float(double x, double y)
  61. {
  62. this.X = (float)x;
  63. this.Y = (float)y;
  64. }
  65. public Vector2Float(Vector3 vector)
  66. {
  67. this.X = (float)vector.X;
  68. this.Y = (float)vector.Y;
  69. }
  70. public Vector2Float(Vector2 vector)
  71. {
  72. this.X = (float)vector.X;
  73. this.Y = (float)vector.Y;
  74. }
  75. public Vector2Float(Vector3Float vector)
  76. {
  77. this.X = vector.X;
  78. this.Y = vector.Y;
  79. }
  80. #endregion Constructors
  81. #region Properties
  82. public float this[int index]
  83. {
  84. get
  85. {
  86. switch (index)
  87. {
  88. case 0:
  89. return X;
  90. case 1:
  91. return Y;
  92. default:
  93. return 0;
  94. }
  95. }
  96. set
  97. {
  98. switch (index)
  99. {
  100. case 0:
  101. X = value;
  102. break;
  103. case 1:
  104. Y = value;
  105. break;
  106. default:
  107. throw new Exception();
  108. }
  109. }
  110. }
  111. /// <summary>
  112. /// Get the delta angle from start to end relative to this
  113. /// </summary>
  114. /// <param name="startPosition"></param>
  115. /// <param name="endPosition"></param>
  116. public double GetDeltaAngle(Vector2Float startPosition, Vector2Float endPosition)
  117. {
  118. startPosition -= this;
  119. var startAngle = Math.Atan2(startPosition.Y, startPosition.X);
  120. startAngle = startAngle < 0 ? startAngle + MathHelper.Tau : startAngle;
  121. endPosition -= this;
  122. var endAngle = Math.Atan2(endPosition.Y, endPosition.X);
  123. endAngle = endAngle < 0 ? endAngle + MathHelper.Tau : endAngle;
  124. return endAngle - startAngle;
  125. }
  126. #endregion Properties
  127. #region Public Members
  128. #region Instance
  129. /// <summary>
  130. /// Gets the length (magnitude) of the vector.
  131. /// </summary>
  132. /// <seealso cref="LengthSquared"/>
  133. public float Length
  134. {
  135. get => (float)System.Math.Sqrt(X * X + Y * Y);
  136. }
  137. /// <summary>
  138. /// Gets the square of the vector length (magnitude).
  139. /// </summary>
  140. /// <remarks>
  141. /// This property avoids the costly square root operation required by the Length property. This makes it more suitable
  142. /// for comparisons.
  143. /// </remarks>
  144. /// <see cref="Length"/>
  145. public double LengthSquared
  146. {
  147. get => X * X + Y * Y;
  148. }
  149. public void Rotate(double radians)
  150. {
  151. this = Vector2Float.Rotate(this, radians);
  152. }
  153. public double GetAngle()
  154. {
  155. return System.Math.Atan2(Y, X);
  156. }
  157. public double GetAngle0To2PI()
  158. {
  159. return MathHelper.Range0ToTau(GetAngle());
  160. }
  161. #region public Vector2d PerpendicularRight
  162. /// <summary>
  163. /// Gets the perpendicular vector on the right side of this vector.
  164. /// </summary>
  165. public Vector2Float GetPerpendicularRight()
  166. {
  167. return new Vector2Float(Y, -X);
  168. }
  169. #endregion public Vector2d PerpendicularRight
  170. #region public Vector2d PerpendicularLeft
  171. /// <summary>
  172. /// Gets the perpendicular vector on the left side of this vector.
  173. /// </summary>
  174. public Vector2Float GetPerpendicularLeft()
  175. {
  176. return new Vector2Float(-Y, X);
  177. }
  178. #endregion public Vector2d PerpendicularLeft
  179. #region public void Normalize()
  180. /// <summary>
  181. /// Returns a normalized Vector of this.
  182. /// </summary>
  183. /// <returns></returns>
  184. public Vector2Float GetNormal()
  185. {
  186. Vector2Float temp = this;
  187. temp.Normalize();
  188. return temp;
  189. }
  190. /// <summary>
  191. /// Scales the Vector2 to unit length.
  192. /// </summary>
  193. public void Normalize()
  194. {
  195. float scale = 1.0f / Length;
  196. X *= scale;
  197. Y *= scale;
  198. }
  199. #endregion public void Normalize()
  200. #endregion Instance
  201. #region Static
  202. #region Add
  203. /// <summary>
  204. /// Adds two vectors.
  205. /// </summary>
  206. /// <param name="a">Left operand.</param>
  207. /// <param name="b">Right operand.</param>
  208. /// <returns>Result of operation.</returns>
  209. public static Vector2Float Add(Vector2Float a, Vector2Float b)
  210. {
  211. Add(ref a, ref b, out a);
  212. return a;
  213. }
  214. /// <summary>
  215. /// Adds two vectors.
  216. /// </summary>
  217. /// <param name="a">Left operand.</param>
  218. /// <param name="b">Right operand.</param>
  219. /// <param name="result">Result of operation.</param>
  220. public static void Add(ref Vector2Float a, ref Vector2Float b, out Vector2Float result)
  221. {
  222. result = new Vector2Float(a.X + b.X, a.Y + b.Y);
  223. }
  224. #endregion Add
  225. #region Subtract
  226. /// <summary>
  227. /// Subtract one Vector from another
  228. /// </summary>
  229. /// <param name="a">First operand</param>
  230. /// <param name="b">Second operand</param>
  231. /// <returns>Result of subtraction</returns>
  232. public static Vector2Float Subtract(Vector2Float a, Vector2Float b)
  233. {
  234. Subtract(ref a, ref b, out a);
  235. return a;
  236. }
  237. /// <summary>
  238. /// Subtract one Vector from another
  239. /// </summary>
  240. /// <param name="a">First operand</param>
  241. /// <param name="b">Second operand</param>
  242. /// <param name="result">Result of subtraction</param>
  243. public static void Subtract(ref Vector2Float a, ref Vector2Float b, out Vector2Float result)
  244. {
  245. result = new Vector2Float(a.X - b.X, a.Y - b.Y);
  246. }
  247. #endregion Subtract
  248. #region Multiply
  249. /// <summary>
  250. /// Multiplies a vector by a scalar.
  251. /// </summary>
  252. /// <param name="vector">Left operand.</param>
  253. /// <param name="scale">Right operand.</param>
  254. /// <returns>Result of the operation.</returns>
  255. public static Vector2Float Multiply(Vector2Float vector, double scale)
  256. {
  257. Multiply(ref vector, scale, out vector);
  258. return vector;
  259. }
  260. /// <summary>
  261. /// Multiplies a vector by a scalar.
  262. /// </summary>
  263. /// <param name="vector">Left operand.</param>
  264. /// <param name="scale">Right operand.</param>
  265. /// <param name="result">Result of the operation.</param>
  266. public static void Multiply(ref Vector2Float vector, double scale, out Vector2Float result)
  267. {
  268. result = new Vector2Float(vector.X * scale, vector.Y * scale);
  269. }
  270. /// <summary>
  271. /// Multiplies a vector by the components a vector (scale).
  272. /// </summary>
  273. /// <param name="vector">Left operand.</param>
  274. /// <param name="scale">Right operand.</param>
  275. /// <returns>Result of the operation.</returns>
  276. public static Vector2Float Multiply(Vector2Float vector, Vector2Float scale)
  277. {
  278. Multiply(ref vector, ref scale, out vector);
  279. return vector;
  280. }
  281. /// <summary>
  282. /// Multiplies a vector by the components of a vector (scale).
  283. /// </summary>
  284. /// <param name="vector">Left operand.</param>
  285. /// <param name="scale">Right operand.</param>
  286. /// <param name="result">Result of the operation.</param>
  287. public static void Multiply(ref Vector2Float vector, ref Vector2Float scale, out Vector2Float result)
  288. {
  289. result = new Vector2Float(vector.X * scale.X, vector.Y * scale.Y);
  290. }
  291. #endregion Multiply
  292. #region Divide
  293. /// <summary>
  294. /// Divides a vector by a scalar.
  295. /// </summary>
  296. /// <param name="vector">Left operand.</param>
  297. /// <param name="scale">Right operand.</param>
  298. /// <returns>Result of the operation.</returns>
  299. public static Vector2Float Divide(Vector2Float vector, double scale)
  300. {
  301. Divide(ref vector, scale, out vector);
  302. return vector;
  303. }
  304. /// <summary>
  305. /// Divides a vector by a scalar.
  306. /// </summary>
  307. /// <param name="vector">Left operand.</param>
  308. /// <param name="scale">Right operand.</param>
  309. /// <param name="result">Result of the operation.</param>
  310. public static void Divide(ref Vector2Float vector, double scale, out Vector2Float result)
  311. {
  312. Multiply(ref vector, 1 / scale, out result);
  313. }
  314. /// <summary>
  315. /// Divides a vector by the components of a vector (scale).
  316. /// </summary>
  317. /// <param name="vector">Left operand.</param>
  318. /// <param name="scale">Right operand.</param>
  319. /// <returns>Result of the operation.</returns>
  320. public static Vector2Float Divide(Vector2Float vector, Vector2Float scale)
  321. {
  322. Divide(ref vector, ref scale, out vector);
  323. return vector;
  324. }
  325. /// <summary>
  326. /// Divide a vector by the components of a vector (scale).
  327. /// </summary>
  328. /// <param name="vector">Left operand.</param>
  329. /// <param name="scale">Right operand.</param>
  330. /// <param name="result">Result of the operation.</param>
  331. public static void Divide(ref Vector2Float vector, ref Vector2Float scale, out Vector2Float result)
  332. {
  333. result = new Vector2Float(vector.X / scale.X, vector.Y / scale.Y);
  334. }
  335. #endregion Divide
  336. #region Min
  337. /// <summary>
  338. /// Calculate the component-wise minimum of two vectors
  339. /// </summary>
  340. /// <param name="a">First operand</param>
  341. /// <param name="b">Second operand</param>
  342. /// <returns>The component-wise minimum</returns>
  343. public static Vector2Float Min(Vector2Float a, Vector2Float b)
  344. {
  345. a.X = a.X < b.X ? a.X : b.X;
  346. a.Y = a.Y < b.Y ? a.Y : b.Y;
  347. return a;
  348. }
  349. /// <summary>
  350. /// Calculate the component-wise minimum of two vectors
  351. /// </summary>
  352. /// <param name="a">First operand</param>
  353. /// <param name="b">Second operand</param>
  354. /// <param name="result">The component-wise minimum</param>
  355. public static void Min(ref Vector2Float a, ref Vector2Float b, out Vector2Float result)
  356. {
  357. result.X = a.X < b.X ? a.X : b.X;
  358. result.Y = a.Y < b.Y ? a.Y : b.Y;
  359. }
  360. #endregion Min
  361. #region Max
  362. /// <summary>
  363. /// Calculate the component-wise maximum of two vectors
  364. /// </summary>
  365. /// <param name="a">First operand</param>
  366. /// <param name="b">Second operand</param>
  367. /// <returns>The component-wise maximum</returns>
  368. public static Vector2Float Max(Vector2Float a, Vector2Float b)
  369. {
  370. a.X = a.X > b.X ? a.X : b.X;
  371. a.Y = a.Y > b.Y ? a.Y : b.Y;
  372. return a;
  373. }
  374. /// <summary>
  375. /// Calculate the component-wise maximum of two vectors
  376. /// </summary>
  377. /// <param name="a">First operand</param>
  378. /// <param name="b">Second operand</param>
  379. /// <param name="result">The component-wise maximum</param>
  380. public static void Max(ref Vector2Float a, ref Vector2Float b, out Vector2Float result)
  381. {
  382. result.X = a.X > b.X ? a.X : b.X;
  383. result.Y = a.Y > b.Y ? a.Y : b.Y;
  384. }
  385. #endregion Max
  386. #region Clamp
  387. /// <summary>
  388. /// Clamp a vector to the given minimum and maximum vectors
  389. /// </summary>
  390. /// <param name="vec">Input vector</param>
  391. /// <param name="min">Minimum vector</param>
  392. /// <param name="max">Maximum vector</param>
  393. /// <returns>The clamped vector</returns>
  394. public static Vector2Float Clamp(Vector2Float vec, Vector2Float min, Vector2Float max)
  395. {
  396. vec.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
  397. vec.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
  398. return vec;
  399. }
  400. /// <summary>
  401. /// Clamp a vector to the given minimum and maximum vectors
  402. /// </summary>
  403. /// <param name="vec">Input vector</param>
  404. /// <param name="min">Minimum vector</param>
  405. /// <param name="max">Maximum vector</param>
  406. /// <param name="result">The clamped vector</param>
  407. public static void Clamp(ref Vector2Float vec, ref Vector2Float min, ref Vector2Float max, out Vector2Float result)
  408. {
  409. result.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X;
  410. result.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y;
  411. }
  412. #endregion Clamp
  413. #region Normalize
  414. /// <summary>
  415. /// Scale a vector to unit length
  416. /// </summary>
  417. /// <param name="vec">The input vector</param>
  418. /// <returns>The normalized vector</returns>
  419. public static Vector2Float Normalize(Vector2Float vec)
  420. {
  421. float scale = 1.0f / vec.Length;
  422. vec.X *= scale;
  423. vec.Y *= scale;
  424. return vec;
  425. }
  426. /// <summary>
  427. /// Scale a vector to unit length
  428. /// </summary>
  429. /// <param name="vec">The input vector</param>
  430. /// <param name="result">The normalized vector</param>
  431. public static void Normalize(ref Vector2Float vec, out Vector2Float result)
  432. {
  433. float scale = 1.0f / vec.Length;
  434. result.X = vec.X * scale;
  435. result.Y = vec.Y * scale;
  436. }
  437. #endregion Normalize
  438. #region Dot
  439. /// <summary>
  440. /// Calculate the dot (scalar) product of two vectors
  441. /// </summary>
  442. /// <param name="left">First operand</param>
  443. /// <param name="right">Second operand</param>
  444. /// <returns>The dot product of the two inputs</returns>
  445. public static double Dot(Vector2Float left, Vector2Float right)
  446. {
  447. return left.X * right.X + left.Y * right.Y;
  448. }
  449. /// <summary>
  450. /// Calculate the dot (scalar) product of two vectors
  451. /// </summary>
  452. /// <param name="left">First operand</param>
  453. /// <param name="right">Second operand</param>
  454. /// <param name="result">The dot product of the two inputs</param>
  455. public static void Dot(ref Vector2Float left, ref Vector2Float right, out double result)
  456. {
  457. result = left.X * right.X + left.Y * right.Y;
  458. }
  459. #endregion Dot
  460. #region Cross
  461. /// <summary>
  462. /// Calculate the cross product of two vectors
  463. /// </summary>
  464. /// <param name="left">First operand</param>
  465. /// <param name="right">Second operand</param>
  466. /// <returns>The cross product of the two inputs</returns>
  467. public static double Cross(Vector2Float left, Vector2Float right)
  468. {
  469. return left.X * right.Y - left.Y * right.X;
  470. }
  471. #endregion Cross
  472. #region Rotate
  473. public static Vector2Float Rotate(Vector2Float toRotate, double radians)
  474. {
  475. Vector2Float temp;
  476. Rotate(ref toRotate, radians, out temp);
  477. return temp;
  478. }
  479. public static void Rotate(ref Vector2Float input, double radians, out Vector2Float output)
  480. {
  481. float Cos, Sin;
  482. Cos = (float)System.Math.Cos(radians);
  483. Sin = (float)System.Math.Sin(radians);
  484. output.X = input.X * Cos - input.Y * Sin;
  485. output.Y = input.Y * Cos + input.X * Sin;
  486. }
  487. #endregion Rotate
  488. #region Lerp
  489. /// <summary>
  490. /// Returns a new Vector that is the linear blend of the 2 given Vectors
  491. /// </summary>
  492. /// <param name="a">First input vector</param>
  493. /// <param name="b">Second input vector</param>
  494. /// <param name="blend">The blend factor. a when blend=0, b when blend=1.</param>
  495. /// <returns>a when blend=0, b when blend=1, and a linear combination otherwise</returns>
  496. public static Vector2Float Lerp(Vector2Float a, Vector2Float b, float blend)
  497. {
  498. a.X = blend * (b.X - a.X) + a.X;
  499. a.Y = blend * (b.Y - a.Y) + a.Y;
  500. return a;
  501. }
  502. /// <summary>
  503. /// Returns a new Vector that is the linear blend of the 2 given Vectors
  504. /// </summary>
  505. /// <param name="a">First input vector</param>
  506. /// <param name="b">Second input vector</param>
  507. /// <param name="blend">The blend factor. a when blend=0, b when blend=1.</param>
  508. /// <param name="result">a when blend=0, b when blend=1, and a linear combination otherwise</param>
  509. public static void Lerp(ref Vector2Float a, ref Vector2Float b, float blend, out Vector2Float result)
  510. {
  511. result.X = blend * (b.X - a.X) + a.X;
  512. result.Y = blend * (b.Y - a.Y) + a.Y;
  513. }
  514. #endregion Lerp
  515. #region Barycentric
  516. /// <summary>
  517. /// Interpolate 3 Vectors using Barycentric coordinates
  518. /// </summary>
  519. /// <param name="a">First input Vector</param>
  520. /// <param name="b">Second input Vector</param>
  521. /// <param name="c">Third input Vector</param>
  522. /// <param name="u">First Barycentric Coordinate</param>
  523. /// <param name="v">Second Barycentric Coordinate</param>
  524. /// <returns>a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise</returns>
  525. public static Vector2Float BaryCentric(Vector2Float a, Vector2Float b, Vector2Float c, float u, float v)
  526. {
  527. return a + u * (b - a) + v * (c - a);
  528. }
  529. /// <summary>Interpolate 3 Vectors using Barycentric coordinates</summary>
  530. /// <param name="a">First input Vector.</param>
  531. /// <param name="b">Second input Vector.</param>
  532. /// <param name="c">Third input Vector.</param>
  533. /// <param name="u">First Barycentric Coordinate.</param>
  534. /// <param name="v">Second Barycentric Coordinate.</param>
  535. /// <param name="result">Output Vector. a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise</param>
  536. public static void BaryCentric(ref Vector2Float a, ref Vector2Float b, ref Vector2Float c, double u, double v, out Vector2Float result)
  537. {
  538. result = a; // copy
  539. Vector2Float temp = b; // copy
  540. Subtract(ref temp, ref a, out temp);
  541. Multiply(ref temp, u, out temp);
  542. Add(ref result, ref temp, out result);
  543. temp = c; // copy
  544. Subtract(ref temp, ref a, out temp);
  545. Multiply(ref temp, v, out temp);
  546. Add(ref result, ref temp, out result);
  547. }
  548. #endregion Barycentric
  549. #region Transform
  550. /// <summary>
  551. /// Transforms a vector by a quaternion rotation.
  552. /// </summary>
  553. /// <param name="vec">The vector to transform.</param>
  554. /// <param name="quat">The quaternion to rotate the vector by.</param>
  555. /// <returns>The result of the operation.</returns>
  556. public static Vector2Float Transform(Vector2Float vec, Quaternion quat)
  557. {
  558. Vector2Float result;
  559. Transform(ref vec, ref quat, out result);
  560. return result;
  561. }
  562. /// <summary>
  563. /// Transforms a vector by a quaternion rotation.
  564. /// </summary>
  565. /// <param name="vec">The vector to transform.</param>
  566. /// <param name="quat">The quaternion to rotate the vector by.</param>
  567. /// <param name="result">The result of the operation.</param>
  568. public static void Transform(ref Vector2Float vec, ref Quaternion quat, out Vector2Float result)
  569. {
  570. Quaternion v = new Quaternion(vec.X, vec.Y, 0, 0), i, t;
  571. Quaternion.Invert(ref quat, out i);
  572. Quaternion.Multiply(ref quat, ref v, out t);
  573. Quaternion.Multiply(ref t, ref i, out v);
  574. result = new Vector2Float(v.X, v.Y);
  575. }
  576. #endregion Transform
  577. #region ComponentMin
  578. /// <summary>
  579. /// Calculate the component-wise minimum of two vectors
  580. /// </summary>
  581. /// <param name="a">First operand</param>
  582. /// <param name="b">Second operand</param>
  583. /// <returns>The component-wise minimum</returns>
  584. public static Vector2Float ComponentMin(Vector2Float a, Vector2Float b)
  585. {
  586. a.X = a.X < b.X ? a.X : b.X;
  587. a.Y = a.Y < b.Y ? a.Y : b.Y;
  588. return a;
  589. }
  590. /// <summary>
  591. /// Calculate the component-wise minimum of two vectors
  592. /// </summary>
  593. /// <param name="a">First operand</param>
  594. /// <param name="b">Second operand</param>
  595. /// <param name="result">The component-wise minimum</param>
  596. public static void ComponentMin(ref Vector2Float a, ref Vector2Float b, out Vector2Float result)
  597. {
  598. result.X = a.X < b.X ? a.X : b.X;
  599. result.Y = a.Y < b.Y ? a.Y : b.Y;
  600. }
  601. #endregion ComponentMin
  602. #region ComponentMax
  603. /// <summary>
  604. /// Calculate the component-wise maximum of two vectors
  605. /// </summary>
  606. /// <param name="a">First operand</param>
  607. /// <param name="b">Second operand</param>
  608. /// <returns>The component-wise maximum</returns>
  609. public static Vector2Float ComponentMax(Vector2Float a, Vector2Float b)
  610. {
  611. a.X = a.X > b.X ? a.X : b.X;
  612. a.Y = a.Y > b.Y ? a.Y : b.Y;
  613. return a;
  614. }
  615. /// <summary>
  616. /// Calculate the component-wise maximum of two vectors
  617. /// </summary>
  618. /// <param name="a">First operand</param>
  619. /// <param name="b">Second operand</param>
  620. /// <param name="result">The component-wise maximum</param>
  621. public static void ComponentMax(ref Vector2Float a, ref Vector2Float b, out Vector2Float result)
  622. {
  623. result.X = a.X > b.X ? a.X : b.X;
  624. result.Y = a.Y > b.Y ? a.Y : b.Y;
  625. }
  626. #endregion ComponentMax
  627. #endregion Static
  628. #region Operators
  629. /// <summary>
  630. /// Adds two instances.
  631. /// </summary>
  632. /// <param name="left">The left instance.</param>
  633. /// <param name="right">The right instance.</param>
  634. /// <returns>The result of the operation.</returns>
  635. public static Vector2Float operator +(Vector2Float left, Vector2Float right)
  636. {
  637. left.X += right.X;
  638. left.Y += right.Y;
  639. return left;
  640. }
  641. /// <summary>
  642. /// Subtracts two instances.
  643. /// </summary>
  644. /// <param name="left">The left instance.</param>
  645. /// <param name="right">The right instance.</param>
  646. /// <returns>The result of the operation.</returns>
  647. public static Vector2Float operator -(Vector2Float left, Vector2Float right)
  648. {
  649. left.X -= right.X;
  650. left.Y -= right.Y;
  651. return left;
  652. }
  653. /// <summary>
  654. /// Negates an instance.
  655. /// </summary>
  656. /// <param name="vec">The instance.</param>
  657. /// <returns>The result of the operation.</returns>
  658. public static Vector2Float operator -(Vector2Float vec)
  659. {
  660. vec.X = -vec.X;
  661. vec.Y = -vec.Y;
  662. return vec;
  663. }
  664. /// <summary>
  665. /// Multiplies an instance by a scalar.
  666. /// </summary>
  667. /// <param name="vec">The instance.</param>
  668. /// <param name="f">The scalar.</param>
  669. /// <returns>The result of the operation.</returns>
  670. public static Vector2Float operator *(Vector2Float vec, float f)
  671. {
  672. vec.X *= f;
  673. vec.Y *= f;
  674. return vec;
  675. }
  676. /// <summary>
  677. /// Multiply an instance by a scalar.
  678. /// </summary>
  679. /// <param name="f">The scalar.</param>
  680. /// <param name="vec">The instance.</param>
  681. /// <returns>The result of the operation.</returns>
  682. public static Vector2Float operator *(float f, Vector2Float vec)
  683. {
  684. vec.X *= f;
  685. vec.Y *= f;
  686. return vec;
  687. }
  688. /// <summary>
  689. /// Divides an instance by a scalar.
  690. /// </summary>
  691. /// <param name="vec">The instance.</param>
  692. /// <param name="f">The scalar.</param>
  693. /// <returns>The result of the operation.</returns>
  694. public static Vector2Float operator /(Vector2Float vec, float f)
  695. {
  696. float mult = 1.0f / f;
  697. vec.X *= mult;
  698. vec.Y *= mult;
  699. return vec;
  700. }
  701. /// <summary>
  702. /// Divides a scaler by an instance components wise.
  703. /// </summary>
  704. /// <param name="vec">The scalar.</param>
  705. /// <param name="f">The instance.</param>
  706. /// <returns>The result of the operation.</returns>
  707. public static Vector2Float operator /(float f, Vector2Float vec)
  708. {
  709. vec.X = f / vec.X;
  710. vec.Y = f / vec.Y;
  711. return vec;
  712. }
  713. /// <summary>
  714. /// Compares two instances for equality.
  715. /// </summary>
  716. /// <param name="left">The left instance.</param>
  717. /// <param name="right">The right instance.</param>
  718. /// <returns>True, if both instances are equal; false otherwise.</returns>
  719. public static bool operator ==(Vector2Float left, Vector2Float right)
  720. {
  721. return left.Equals(right);
  722. }
  723. /// <summary>
  724. /// Compares two instances for ienquality.
  725. /// </summary>
  726. /// <param name="left">The left instance.</param>
  727. /// <param name="right">The right instance.</param>
  728. /// <returns>True, if the instances are not equal; false otherwise.</returns>
  729. public static bool operator !=(Vector2Float left, Vector2Float right)
  730. {
  731. return !left.Equals(right);
  732. }
  733. #endregion Operators
  734. #region Overrides
  735. #region public override string ToString()
  736. /// <summary>
  737. /// Returns a System.String that represents the current instance.
  738. /// </summary>
  739. /// <returns></returns>
  740. public override string ToString()
  741. {
  742. return String.Format("({0}, {1})", X, Y);
  743. }
  744. #endregion public override string ToString()
  745. #region public override int GetHashCode()
  746. /// <summary>
  747. /// Returns the hashcode for this instance.
  748. /// </summary>
  749. /// <returns>A System.Int32 containing the unique hashcode for this instance.</returns>
  750. public override int GetHashCode()
  751. {
  752. return new { X, Y }.GetHashCode();
  753. }
  754. #endregion public override int GetHashCode()
  755. #region public override bool Equals(object obj)
  756. /// <summary>
  757. /// Indicates whether this instance and a specified object are equal.
  758. /// </summary>
  759. /// <param name="obj">The object to compare to.</param>
  760. /// <returns>True if the instances are equal; false otherwise.</returns>
  761. public override bool Equals(object obj)
  762. {
  763. if (!(obj is Vector2Float))
  764. return false;
  765. return this.Equals((Vector2Float)obj);
  766. }
  767. #endregion public override bool Equals(object obj)
  768. #endregion Overrides
  769. #endregion Public Members
  770. #region IEquatable<Vector2Floatd> Members
  771. /// <summary>Indicates whether the current vector is equal to another vector.</summary>
  772. /// <param name="other">A vector to compare with this vector.</param>
  773. /// <returns>true if the current vector is equal to the vector parameter; otherwise, false.</returns>
  774. public bool Equals(Vector2Float other)
  775. {
  776. return
  777. X == other.X &&
  778. Y == other.Y;
  779. }
  780. /// <summary>Indicates whether the current vector is equal to another vector.</summary>
  781. /// <param name="other">A vector to compare with this vector.</param>
  782. /// <returns>true if the current vector is equal to the vector parameter; otherwise, false.</returns>
  783. public bool Equals(Vector2Float other, double errorRange)
  784. {
  785. if ((X < other.X + errorRange && X > other.X - errorRange) &&
  786. (Y < other.Y + errorRange && Y > other.Y - errorRange))
  787. {
  788. return true;
  789. }
  790. return false;
  791. }
  792. #endregion IEquatable<Vector2Floatd> Members
  793. }
  794. }