vector2.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. "use strict";
  2. /**
  3. * 2 Dimensional Vector
  4. * @module vector2
  5. */
  6. module.exports = {
  7. /**
  8. * Creates a new, empty vector2
  9. *
  10. * @return {vector2} a new 2D vector
  11. */
  12. create: function create() {
  13. return [0, 0];
  14. },
  15. /**
  16. * Calculates the length of a vector2
  17. *
  18. * @param {vector2} v vector to calculate length of
  19. * @return {Number} length of v
  20. */
  21. length: function length(v) {
  22. var x = v[0];
  23. var y = v[1];
  24. return Math.sqrt(x * x + y * y);
  25. },
  26. /**
  27. * Normalize a vector2
  28. *
  29. * @param {vector2} out the receiving vector
  30. * @param {vector2} v vector to normalize
  31. * @return {vector2} out
  32. */
  33. normalize: function normalize(out, v) {
  34. var len = this.length(v);
  35. if (len === 0) {
  36. out[0] = 0;
  37. out[1] = 0;
  38. } else {
  39. out[0] = v[0] / len;
  40. out[1] = v[1] / len;
  41. }
  42. return out;
  43. },
  44. /**
  45. * Adds two vector2's
  46. *
  47. * @param {vector2} out the receiving vector
  48. * @param {vector2} v1 the first operand
  49. * @param {vector2} v2 the second operand
  50. * @return {vector2} out
  51. */
  52. add: function add(out, v1, v2) {
  53. out[0] = v1[0] + v2[0];
  54. out[1] = v1[1] + v2[1];
  55. return out;
  56. },
  57. /**
  58. * Subtracts vector v2 from vector v1
  59. *
  60. * @param {vector2} out the receiving vector
  61. * @param {vector2} v1 the first operand
  62. * @param {vector2} v2 the second operand
  63. * @return {vector2} out
  64. */
  65. sub: function sub(out, v1, v2) {
  66. out[0] = v1[0] - v2[0];
  67. out[1] = v1[1] - v2[1];
  68. return out;
  69. },
  70. /**
  71. * Scales a vector2 by a scalar number
  72. *
  73. * @param {vector2} out the receiving vector
  74. * @param {vector2} v the vector to scale
  75. * @param {Number} s amount to scale the vector by
  76. * @return {vector2} out
  77. */
  78. scale: function scale(out, v, s) {
  79. out[0] = v[0] * s;
  80. out[1] = v[1] * s;
  81. return out;
  82. },
  83. /**
  84. * Calculates the dot product of two vector2's
  85. *
  86. * @param {vector2} v1 the first operand
  87. * @param {vector2} v2 the second operand
  88. * @return {Number} dot product of v1 and v2
  89. */
  90. dot: function dot(v1, v2) {
  91. return v1[0] * v2[0] + v1[1] * v2[1];
  92. },
  93. /**
  94. * Calculates the direction of two vector2's
  95. *
  96. * @param {vector2} v1 the first operand
  97. * @param {vector2} v2 the second operand
  98. * @return {Boolean} the direction of v1 and v2
  99. */
  100. direction: function direction(v1, v2) {
  101. return v1[0] * v2[1] - v2[0] * v1[1];
  102. },
  103. /**
  104. * Calculates the angle of two vector2's
  105. *
  106. * @param {vector2} v1 the first operand
  107. * @param {vector2} v2 the second operand
  108. * @return {Number} angle of v1 and v2
  109. */
  110. angle: function angle(v1, v2) {
  111. var theta = this.dot(v1, v2) / (this.length(v1) * this.length(v2));
  112. return Math.acos(theta);
  113. },
  114. /**
  115. * Calculates the angle of two vector2's with direction
  116. *
  117. * @param {vector2} v1 the first operand
  118. * @param {vector2} v2 the second operand
  119. * @param {Boolean} direction the direction of two vector2's
  120. * @return {Number} angle of v1 and v2
  121. */
  122. angleTo: function angleTo(v1, v2, direction) {
  123. var angle = this.angle(v1, v2);
  124. var angleLargeThanPI = this.direction(v1, v2) >= 0;
  125. if (direction) {
  126. if (angleLargeThanPI) {
  127. return Math.PI * 2 - angle;
  128. }
  129. return angle;
  130. }
  131. if (angleLargeThanPI) {
  132. return angle;
  133. }
  134. return Math.PI * 2 - angle;
  135. },
  136. /**
  137. * whether a vector2 is zero vector
  138. *
  139. * @param {vector2} v vector to calculate
  140. * @return {Boolean} is or not a zero vector
  141. */
  142. zero: function zero(v) {
  143. return v[0] === 0 && v[1] === 0;
  144. },
  145. /**
  146. * Calculates the euclidian distance between two vector2's
  147. *
  148. * @param {vector2} v1 the first operand
  149. * @param {vector2} v2 the second operand
  150. * @return {Number} distance between a and b
  151. */
  152. distance: function distance(v1, v2) {
  153. var x = v2[0] - v1[0];
  154. var y = v2[1] - v1[1];
  155. return Math.sqrt(x * x + y * y);
  156. },
  157. /**
  158. * Creates a new vector2 initialized with values from an existing vector
  159. *
  160. * @param {vector2} v vector to clone
  161. * @return {Array} a new 2D vector
  162. */
  163. clone: function clone(v) {
  164. return [v[0], v[1]];
  165. },
  166. /**
  167. * Return the minimum of two vector2's
  168. *
  169. * @param {vector2} out the receiving vector
  170. * @param {vector2} v1 the first operand
  171. * @param {vector2} v2 the second operand
  172. * @return {vector2} out
  173. */
  174. min: function min(out, v1, v2) {
  175. out[0] = Math.min(v1[0], v2[0]);
  176. out[1] = Math.min(v1[1], v2[1]);
  177. return out;
  178. },
  179. /**
  180. * Return the maximum of two vector2's
  181. *
  182. * @param {vector2} out the receiving vector
  183. * @param {vector2} v1 the first operand
  184. * @param {vector2} v2 the second operand
  185. * @return {vector2} out
  186. */
  187. max: function max(out, v1, v2) {
  188. out[0] = Math.max(v1[0], v2[0]);
  189. out[1] = Math.max(v1[1], v2[1]);
  190. return out;
  191. },
  192. /**
  193. * Transforms the vector2 with a mat2d
  194. *
  195. * @param {vector2} out the receiving vector
  196. * @param {vector2} v the vector to transform
  197. * @param {mat2d} m matrix to transform with
  198. * @return {vector2} out
  199. */
  200. transformMat2d: function transformMat2d(out, v, m) {
  201. var x = v[0];
  202. var y = v[1];
  203. out[0] = m[0] * x + m[2] * y + m[4];
  204. out[1] = m[1] * x + m[3] * y + m[5];
  205. return out;
  206. }
  207. };