├── .editorconfig ├── .gitignore ├── .npmignore ├── .travis.yml ├── LICENSE ├── README.md ├── artwork ├── logo.png ├── logo.svg └── logo_workfiles.svg ├── bower.json ├── build ├── victor.js └── victor.min.js ├── documentation └── api.md ├── index.js ├── package.json ├── test.txt └── test └── victor.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | 10 | indent_style = tab 11 | indent_size = 4 12 | 13 | # We recommend you to keep these unchanged 14 | end_of_line = lf 15 | charset = utf-8 16 | trim_trailing_whitespace = true 17 | insert_final_newline = false 18 | 19 | [{package.json,bower.json,.travis.yml}] 20 | indent_style = space 21 | indent_size = 2 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .idea -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | *.md 2 | build/ 3 | artwork/ 4 | test/ 5 | documentation/ 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.11" 4 | - "0.10" 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2011 Max Kueng, George Crabtree 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Victor](./artwork/logo.png) 2 | ============================= 3 | 4 | [![Build Status](https://secure.travis-ci.org/maxkueng/victor.png?branch=master)](http://travis-ci.org/maxkueng/victor) 5 | 6 | A Javascript 2D Vector Maths Library, built using the UMD standards, so you can use it as a global object or with any module loader. It works in both Node.js and the browser. 7 | 8 | Check out the website for [documentation](http://victorjs.org/). 9 | 10 | ## Installation 11 | 12 | ### Node.js / Browserify 13 | 14 | ```bash 15 | npm install victor --save 16 | ``` 17 | 18 | ```javascript 19 | var Victor = require('victor'); 20 | var vec = new Victor(42, 1337); 21 | ``` 22 | 23 | ### Bower 24 | 25 | ```bash 26 | bower install victor --save 27 | ``` 28 | 29 | ### Global object 30 | 31 | Include the pre-built script. 32 | 33 | ```html 34 | 35 | 38 | ``` 39 | 40 | ## Build & test 41 | 42 | ```bash 43 | npm run build 44 | ``` 45 | 46 | ```bash 47 | npm test 48 | ``` 49 | 50 | ## Contributors 51 | 52 | Ordered by date of first contribution. [Auto-generated](https://github.com/dtrejo/node-authors) on Mon, 31 Aug 2015 13:08:12 GMT. 53 | 54 | - [Max Kueng](https://github.com/maxkueng) aka `maxkueng` 55 | - [George Crabtree](https://github.com/supercrabtree) aka `supercrabtree` 56 | - [Michel.Ypma](https://github.com/MichelYpma) aka `MichelYpma` 57 | - [Chris Pearce](https://github.com/Chrisui) aka `Chrisui` 58 | - [Beau Gunderson](https://github.com/beaugunderson) aka `beaugunderson` 59 | - [René Bischoff](https://github.com/Fjandin) aka `Fjandin` 60 | - [Chris Ertel](https://github.com/chrisrertel) aka `chrisrertel` 61 | - [Heikki Ylönen](https://github.com/heikki) aka `heikki` 62 | - [Joonas Salmela](https://github.com/undefined) aka `undefined` 63 | - [Moritz Rebbert](https://github.com/ztiromoritz) aka `ztiromoritz` 64 | 65 | ## License 66 | 67 | MIT 68 | -------------------------------------------------------------------------------- /artwork/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxkueng/victor/8383f436d63f6741e5529b09a39e7fb2b7f1dbfb/artwork/logo.png -------------------------------------------------------------------------------- /artwork/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 16 | 19 | 22 | 23 | 30 | 33 | 34 | 35 | 37 | 38 | 40 | image/svg+xml 41 | 43 | 44 | 45 | 46 | 47 | 50 | 54 | 57 | 62 | 66 | 70 | 74 | 78 | 82 | 86 | 90 | 94 | 97 | 100 | 103 | 106 | 109 | 112 | 113 | 117 | 120 | 123 | 126 | 127 | 130 | 133 | 136 | 139 | 142 | 145 | 148 | 149 | 152 | 155 | 158 | 161 | 162 | 163 | 164 | 165 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "victor", 3 | "main": "build/victor.js", 4 | "repository": { 5 | "type": "git", 6 | "url": "git://github.com/maxkueng/victor.git" 7 | }, 8 | "version": "1.1.0", 9 | "homepage": "https://github.com/maxkueng/victor", 10 | "authors": [ 11 | "Max Kueng (http://maxkueng.com/)", 12 | "George Crabtree (http://georgecrabtree.com/)" 13 | ], 14 | "description": "A JavaScript 2D vector class for common vector operations", 15 | "keywords": [ 16 | "vector", 17 | "2d" 18 | ], 19 | "license": "MIT", 20 | "ignore": [ 21 | "**/.*", 22 | "node_modules", 23 | "bower_components", 24 | "components", 25 | "test", 26 | "documentation", 27 | "artwork", 28 | "index.js", 29 | "**/*.json", 30 | "**/*.md" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /build/victor.js: -------------------------------------------------------------------------------- 1 | /*! 2 | MIT License 3 | 4 | Copyright (c) 2011 Max Kueng, George Crabtree 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | "Software"), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be 15 | included in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | !function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Victor=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 42 57 | * 58 | * @api public 59 | */ 60 | this.x = x || 0; 61 | 62 | /** 63 | * The Y axis 64 | * 65 | * ### Examples: 66 | * var vec = new Victor.fromArray(42, 21); 67 | * 68 | * vec.y; 69 | * // => 21 70 | * 71 | * @api public 72 | */ 73 | this.y = y || 0; 74 | }; 75 | 76 | /** 77 | * # Static 78 | */ 79 | 80 | /** 81 | * Creates a new instance from an array 82 | * 83 | * ### Examples: 84 | * var vec = Victor.fromArray([42, 21]); 85 | * 86 | * vec.toString(); 87 | * // => x:42, y:21 88 | * 89 | * @name Victor.fromArray 90 | * @param {Array} array Array with the x and y values at index 0 and 1 respectively 91 | * @return {Victor} The new instance 92 | * @api public 93 | */ 94 | Victor.fromArray = function (arr) { 95 | return new Victor(arr[0] || 0, arr[1] || 0); 96 | }; 97 | 98 | /** 99 | * Creates a new instance from an object 100 | * 101 | * ### Examples: 102 | * var vec = Victor.fromObject({ x: 42, y: 21 }); 103 | * 104 | * vec.toString(); 105 | * // => x:42, y:21 106 | * 107 | * @name Victor.fromObject 108 | * @param {Object} obj Object with the values for x and y 109 | * @return {Victor} The new instance 110 | * @api public 111 | */ 112 | Victor.fromObject = function (obj) { 113 | return new Victor(obj.x || 0, obj.y || 0); 114 | }; 115 | 116 | /** 117 | * # Manipulation 118 | * 119 | * These functions are chainable. 120 | */ 121 | 122 | /** 123 | * Adds another vector's X axis to this one 124 | * 125 | * ### Examples: 126 | * var vec1 = new Victor(10, 10); 127 | * var vec2 = new Victor(20, 30); 128 | * 129 | * vec1.addX(vec2); 130 | * vec1.toString(); 131 | * // => x:30, y:10 132 | * 133 | * @param {Victor} vector The other vector you want to add to this one 134 | * @return {Victor} `this` for chaining capabilities 135 | * @api public 136 | */ 137 | Victor.prototype.addX = function (vec) { 138 | this.x += vec.x; 139 | return this; 140 | }; 141 | 142 | /** 143 | * Adds another vector's Y axis to this one 144 | * 145 | * ### Examples: 146 | * var vec1 = new Victor(10, 10); 147 | * var vec2 = new Victor(20, 30); 148 | * 149 | * vec1.addY(vec2); 150 | * vec1.toString(); 151 | * // => x:10, y:40 152 | * 153 | * @param {Victor} vector The other vector you want to add to this one 154 | * @return {Victor} `this` for chaining capabilities 155 | * @api public 156 | */ 157 | Victor.prototype.addY = function (vec) { 158 | this.y += vec.y; 159 | return this; 160 | }; 161 | 162 | /** 163 | * Adds another vector to this one 164 | * 165 | * ### Examples: 166 | * var vec1 = new Victor(10, 10); 167 | * var vec2 = new Victor(20, 30); 168 | * 169 | * vec1.add(vec2); 170 | * vec1.toString(); 171 | * // => x:30, y:40 172 | * 173 | * @param {Victor} vector The other vector you want to add to this one 174 | * @return {Victor} `this` for chaining capabilities 175 | * @api public 176 | */ 177 | Victor.prototype.add = function (vec) { 178 | this.x += vec.x; 179 | this.y += vec.y; 180 | return this; 181 | }; 182 | 183 | /** 184 | * Adds the given scalar to both vector axis 185 | * 186 | * ### Examples: 187 | * var vec = new Victor(1, 2); 188 | * 189 | * vec.addScalar(2); 190 | * vec.toString(); 191 | * // => x: 3, y: 4 192 | * 193 | * @param {Number} scalar The scalar to add 194 | * @return {Victor} `this` for chaining capabilities 195 | * @api public 196 | */ 197 | Victor.prototype.addScalar = function (scalar) { 198 | this.x += scalar; 199 | this.y += scalar; 200 | return this; 201 | }; 202 | 203 | /** 204 | * Adds the given scalar to the X axis 205 | * 206 | * ### Examples: 207 | * var vec = new Victor(1, 2); 208 | * 209 | * vec.addScalarX(2); 210 | * vec.toString(); 211 | * // => x: 3, y: 2 212 | * 213 | * @param {Number} scalar The scalar to add 214 | * @return {Victor} `this` for chaining capabilities 215 | * @api public 216 | */ 217 | Victor.prototype.addScalarX = function (scalar) { 218 | this.x += scalar; 219 | return this; 220 | }; 221 | 222 | /** 223 | * Adds the given scalar to the Y axis 224 | * 225 | * ### Examples: 226 | * var vec = new Victor(1, 2); 227 | * 228 | * vec.addScalarY(2); 229 | * vec.toString(); 230 | * // => x: 1, y: 4 231 | * 232 | * @param {Number} scalar The scalar to add 233 | * @return {Victor} `this` for chaining capabilities 234 | * @api public 235 | */ 236 | Victor.prototype.addScalarY = function (scalar) { 237 | this.y += scalar; 238 | return this; 239 | }; 240 | 241 | /** 242 | * Subtracts the X axis of another vector from this one 243 | * 244 | * ### Examples: 245 | * var vec1 = new Victor(100, 50); 246 | * var vec2 = new Victor(20, 30); 247 | * 248 | * vec1.subtractX(vec2); 249 | * vec1.toString(); 250 | * // => x:80, y:50 251 | * 252 | * @param {Victor} vector The other vector you want subtract from this one 253 | * @return {Victor} `this` for chaining capabilities 254 | * @api public 255 | */ 256 | Victor.prototype.subtractX = function (vec) { 257 | this.x -= vec.x; 258 | return this; 259 | }; 260 | 261 | /** 262 | * Subtracts the Y axis of another vector from this one 263 | * 264 | * ### Examples: 265 | * var vec1 = new Victor(100, 50); 266 | * var vec2 = new Victor(20, 30); 267 | * 268 | * vec1.subtractY(vec2); 269 | * vec1.toString(); 270 | * // => x:100, y:20 271 | * 272 | * @param {Victor} vector The other vector you want subtract from this one 273 | * @return {Victor} `this` for chaining capabilities 274 | * @api public 275 | */ 276 | Victor.prototype.subtractY = function (vec) { 277 | this.y -= vec.y; 278 | return this; 279 | }; 280 | 281 | /** 282 | * Subtracts another vector from this one 283 | * 284 | * ### Examples: 285 | * var vec1 = new Victor(100, 50); 286 | * var vec2 = new Victor(20, 30); 287 | * 288 | * vec1.subtract(vec2); 289 | * vec1.toString(); 290 | * // => x:80, y:20 291 | * 292 | * @param {Victor} vector The other vector you want subtract from this one 293 | * @return {Victor} `this` for chaining capabilities 294 | * @api public 295 | */ 296 | Victor.prototype.subtract = function (vec) { 297 | this.x -= vec.x; 298 | this.y -= vec.y; 299 | return this; 300 | }; 301 | 302 | /** 303 | * Subtracts the given scalar from both axis 304 | * 305 | * ### Examples: 306 | * var vec = new Victor(100, 200); 307 | * 308 | * vec.subtractScalar(20); 309 | * vec.toString(); 310 | * // => x: 80, y: 180 311 | * 312 | * @param {Number} scalar The scalar to subtract 313 | * @return {Victor} `this` for chaining capabilities 314 | * @api public 315 | */ 316 | Victor.prototype.subtractScalar = function (scalar) { 317 | this.x -= scalar; 318 | this.y -= scalar; 319 | return this; 320 | }; 321 | 322 | /** 323 | * Subtracts the given scalar from the X axis 324 | * 325 | * ### Examples: 326 | * var vec = new Victor(100, 200); 327 | * 328 | * vec.subtractScalarX(20); 329 | * vec.toString(); 330 | * // => x: 80, y: 200 331 | * 332 | * @param {Number} scalar The scalar to subtract 333 | * @return {Victor} `this` for chaining capabilities 334 | * @api public 335 | */ 336 | Victor.prototype.subtractScalarX = function (scalar) { 337 | this.x -= scalar; 338 | return this; 339 | }; 340 | 341 | /** 342 | * Subtracts the given scalar from the Y axis 343 | * 344 | * ### Examples: 345 | * var vec = new Victor(100, 200); 346 | * 347 | * vec.subtractScalarY(20); 348 | * vec.toString(); 349 | * // => x: 100, y: 180 350 | * 351 | * @param {Number} scalar The scalar to subtract 352 | * @return {Victor} `this` for chaining capabilities 353 | * @api public 354 | */ 355 | Victor.prototype.subtractScalarY = function (scalar) { 356 | this.y -= scalar; 357 | return this; 358 | }; 359 | 360 | /** 361 | * Divides the X axis by the x component of given vector 362 | * 363 | * ### Examples: 364 | * var vec = new Victor(100, 50); 365 | * var vec2 = new Victor(2, 0); 366 | * 367 | * vec.divideX(vec2); 368 | * vec.toString(); 369 | * // => x:50, y:50 370 | * 371 | * @param {Victor} vector The other vector you want divide by 372 | * @return {Victor} `this` for chaining capabilities 373 | * @api public 374 | */ 375 | Victor.prototype.divideX = function (vector) { 376 | this.x /= vector.x; 377 | return this; 378 | }; 379 | 380 | /** 381 | * Divides the Y axis by the y component of given vector 382 | * 383 | * ### Examples: 384 | * var vec = new Victor(100, 50); 385 | * var vec2 = new Victor(0, 2); 386 | * 387 | * vec.divideY(vec2); 388 | * vec.toString(); 389 | * // => x:100, y:25 390 | * 391 | * @param {Victor} vector The other vector you want divide by 392 | * @return {Victor} `this` for chaining capabilities 393 | * @api public 394 | */ 395 | Victor.prototype.divideY = function (vector) { 396 | this.y /= vector.y; 397 | return this; 398 | }; 399 | 400 | /** 401 | * Divides both vector axis by a axis values of given vector 402 | * 403 | * ### Examples: 404 | * var vec = new Victor(100, 50); 405 | * var vec2 = new Victor(2, 2); 406 | * 407 | * vec.divide(vec2); 408 | * vec.toString(); 409 | * // => x:50, y:25 410 | * 411 | * @param {Victor} vector The vector to divide by 412 | * @return {Victor} `this` for chaining capabilities 413 | * @api public 414 | */ 415 | Victor.prototype.divide = function (vector) { 416 | this.x /= vector.x; 417 | this.y /= vector.y; 418 | return this; 419 | }; 420 | 421 | /** 422 | * Divides both vector axis by the given scalar value 423 | * 424 | * ### Examples: 425 | * var vec = new Victor(100, 50); 426 | * 427 | * vec.divideScalar(2); 428 | * vec.toString(); 429 | * // => x:50, y:25 430 | * 431 | * @param {Number} The scalar to divide by 432 | * @return {Victor} `this` for chaining capabilities 433 | * @api public 434 | */ 435 | Victor.prototype.divideScalar = function (scalar) { 436 | if (scalar !== 0) { 437 | this.x /= scalar; 438 | this.y /= scalar; 439 | } else { 440 | this.x = 0; 441 | this.y = 0; 442 | } 443 | 444 | return this; 445 | }; 446 | 447 | /** 448 | * Divides the X axis by the given scalar value 449 | * 450 | * ### Examples: 451 | * var vec = new Victor(100, 50); 452 | * 453 | * vec.divideScalarX(2); 454 | * vec.toString(); 455 | * // => x:50, y:50 456 | * 457 | * @param {Number} The scalar to divide by 458 | * @return {Victor} `this` for chaining capabilities 459 | * @api public 460 | */ 461 | Victor.prototype.divideScalarX = function (scalar) { 462 | if (scalar !== 0) { 463 | this.x /= scalar; 464 | } else { 465 | this.x = 0; 466 | } 467 | return this; 468 | }; 469 | 470 | /** 471 | * Divides the Y axis by the given scalar value 472 | * 473 | * ### Examples: 474 | * var vec = new Victor(100, 50); 475 | * 476 | * vec.divideScalarY(2); 477 | * vec.toString(); 478 | * // => x:100, y:25 479 | * 480 | * @param {Number} The scalar to divide by 481 | * @return {Victor} `this` for chaining capabilities 482 | * @api public 483 | */ 484 | Victor.prototype.divideScalarY = function (scalar) { 485 | if (scalar !== 0) { 486 | this.y /= scalar; 487 | } else { 488 | this.y = 0; 489 | } 490 | return this; 491 | }; 492 | 493 | /** 494 | * Inverts the X axis 495 | * 496 | * ### Examples: 497 | * var vec = new Victor(100, 50); 498 | * 499 | * vec.invertX(); 500 | * vec.toString(); 501 | * // => x:-100, y:50 502 | * 503 | * @return {Victor} `this` for chaining capabilities 504 | * @api public 505 | */ 506 | Victor.prototype.invertX = function () { 507 | this.x *= -1; 508 | return this; 509 | }; 510 | 511 | /** 512 | * Inverts the Y axis 513 | * 514 | * ### Examples: 515 | * var vec = new Victor(100, 50); 516 | * 517 | * vec.invertY(); 518 | * vec.toString(); 519 | * // => x:100, y:-50 520 | * 521 | * @return {Victor} `this` for chaining capabilities 522 | * @api public 523 | */ 524 | Victor.prototype.invertY = function () { 525 | this.y *= -1; 526 | return this; 527 | }; 528 | 529 | /** 530 | * Inverts both axis 531 | * 532 | * ### Examples: 533 | * var vec = new Victor(100, 50); 534 | * 535 | * vec.invert(); 536 | * vec.toString(); 537 | * // => x:-100, y:-50 538 | * 539 | * @return {Victor} `this` for chaining capabilities 540 | * @api public 541 | */ 542 | Victor.prototype.invert = function () { 543 | this.invertX(); 544 | this.invertY(); 545 | return this; 546 | }; 547 | 548 | /** 549 | * Multiplies the X axis by X component of given vector 550 | * 551 | * ### Examples: 552 | * var vec = new Victor(100, 50); 553 | * var vec2 = new Victor(2, 0); 554 | * 555 | * vec.multiplyX(vec2); 556 | * vec.toString(); 557 | * // => x:200, y:50 558 | * 559 | * @param {Victor} vector The vector to multiply the axis with 560 | * @return {Victor} `this` for chaining capabilities 561 | * @api public 562 | */ 563 | Victor.prototype.multiplyX = function (vector) { 564 | this.x *= vector.x; 565 | return this; 566 | }; 567 | 568 | /** 569 | * Multiplies the Y axis by Y component of given vector 570 | * 571 | * ### Examples: 572 | * var vec = new Victor(100, 50); 573 | * var vec2 = new Victor(0, 2); 574 | * 575 | * vec.multiplyX(vec2); 576 | * vec.toString(); 577 | * // => x:100, y:100 578 | * 579 | * @param {Victor} vector The vector to multiply the axis with 580 | * @return {Victor} `this` for chaining capabilities 581 | * @api public 582 | */ 583 | Victor.prototype.multiplyY = function (vector) { 584 | this.y *= vector.y; 585 | return this; 586 | }; 587 | 588 | /** 589 | * Multiplies both vector axis by values from a given vector 590 | * 591 | * ### Examples: 592 | * var vec = new Victor(100, 50); 593 | * var vec2 = new Victor(2, 2); 594 | * 595 | * vec.multiply(vec2); 596 | * vec.toString(); 597 | * // => x:200, y:100 598 | * 599 | * @param {Victor} vector The vector to multiply by 600 | * @return {Victor} `this` for chaining capabilities 601 | * @api public 602 | */ 603 | Victor.prototype.multiply = function (vector) { 604 | this.x *= vector.x; 605 | this.y *= vector.y; 606 | return this; 607 | }; 608 | 609 | /** 610 | * Multiplies both vector axis by the given scalar value 611 | * 612 | * ### Examples: 613 | * var vec = new Victor(100, 50); 614 | * 615 | * vec.multiplyScalar(2); 616 | * vec.toString(); 617 | * // => x:200, y:100 618 | * 619 | * @param {Number} The scalar to multiply by 620 | * @return {Victor} `this` for chaining capabilities 621 | * @api public 622 | */ 623 | Victor.prototype.multiplyScalar = function (scalar) { 624 | this.x *= scalar; 625 | this.y *= scalar; 626 | return this; 627 | }; 628 | 629 | /** 630 | * Multiplies the X axis by the given scalar 631 | * 632 | * ### Examples: 633 | * var vec = new Victor(100, 50); 634 | * 635 | * vec.multiplyScalarX(2); 636 | * vec.toString(); 637 | * // => x:200, y:50 638 | * 639 | * @param {Number} The scalar to multiply the axis with 640 | * @return {Victor} `this` for chaining capabilities 641 | * @api public 642 | */ 643 | Victor.prototype.multiplyScalarX = function (scalar) { 644 | this.x *= scalar; 645 | return this; 646 | }; 647 | 648 | /** 649 | * Multiplies the Y axis by the given scalar 650 | * 651 | * ### Examples: 652 | * var vec = new Victor(100, 50); 653 | * 654 | * vec.multiplyScalarY(2); 655 | * vec.toString(); 656 | * // => x:100, y:100 657 | * 658 | * @param {Number} The scalar to multiply the axis with 659 | * @return {Victor} `this` for chaining capabilities 660 | * @api public 661 | */ 662 | Victor.prototype.multiplyScalarY = function (scalar) { 663 | this.y *= scalar; 664 | return this; 665 | }; 666 | 667 | /** 668 | * Normalize 669 | * 670 | * @return {Victor} `this` for chaining capabilities 671 | * @api public 672 | */ 673 | Victor.prototype.normalize = function () { 674 | var length = this.length(); 675 | 676 | if (length === 0) { 677 | this.x = 1; 678 | this.y = 0; 679 | } else { 680 | this.divide(Victor(length, length)); 681 | } 682 | return this; 683 | }; 684 | 685 | Victor.prototype.norm = Victor.prototype.normalize; 686 | 687 | /** 688 | * If the absolute vector axis is greater than `max`, multiplies the axis by `factor` 689 | * 690 | * ### Examples: 691 | * var vec = new Victor(100, 50); 692 | * 693 | * vec.limit(80, 0.9); 694 | * vec.toString(); 695 | * // => x:90, y:50 696 | * 697 | * @param {Number} max The maximum value for both x and y axis 698 | * @param {Number} factor Factor by which the axis are to be multiplied with 699 | * @return {Victor} `this` for chaining capabilities 700 | * @api public 701 | */ 702 | Victor.prototype.limit = function (max, factor) { 703 | if (Math.abs(this.x) > max){ this.x *= factor; } 704 | if (Math.abs(this.y) > max){ this.y *= factor; } 705 | return this; 706 | }; 707 | 708 | /** 709 | * Randomizes both vector axis with a value between 2 vectors 710 | * 711 | * ### Examples: 712 | * var vec = new Victor(100, 50); 713 | * 714 | * vec.randomize(new Victor(50, 60), new Victor(70, 80`)); 715 | * vec.toString(); 716 | * // => x:67, y:73 717 | * 718 | * @param {Victor} topLeft first vector 719 | * @param {Victor} bottomRight second vector 720 | * @return {Victor} `this` for chaining capabilities 721 | * @api public 722 | */ 723 | Victor.prototype.randomize = function (topLeft, bottomRight) { 724 | this.randomizeX(topLeft, bottomRight); 725 | this.randomizeY(topLeft, bottomRight); 726 | 727 | return this; 728 | }; 729 | 730 | /** 731 | * Randomizes the y axis with a value between 2 vectors 732 | * 733 | * ### Examples: 734 | * var vec = new Victor(100, 50); 735 | * 736 | * vec.randomizeX(new Victor(50, 60), new Victor(70, 80`)); 737 | * vec.toString(); 738 | * // => x:55, y:50 739 | * 740 | * @param {Victor} topLeft first vector 741 | * @param {Victor} bottomRight second vector 742 | * @return {Victor} `this` for chaining capabilities 743 | * @api public 744 | */ 745 | Victor.prototype.randomizeX = function (topLeft, bottomRight) { 746 | var min = Math.min(topLeft.x, bottomRight.x); 747 | var max = Math.max(topLeft.x, bottomRight.x); 748 | this.x = random(min, max); 749 | return this; 750 | }; 751 | 752 | /** 753 | * Randomizes the y axis with a value between 2 vectors 754 | * 755 | * ### Examples: 756 | * var vec = new Victor(100, 50); 757 | * 758 | * vec.randomizeY(new Victor(50, 60), new Victor(70, 80`)); 759 | * vec.toString(); 760 | * // => x:100, y:66 761 | * 762 | * @param {Victor} topLeft first vector 763 | * @param {Victor} bottomRight second vector 764 | * @return {Victor} `this` for chaining capabilities 765 | * @api public 766 | */ 767 | Victor.prototype.randomizeY = function (topLeft, bottomRight) { 768 | var min = Math.min(topLeft.y, bottomRight.y); 769 | var max = Math.max(topLeft.y, bottomRight.y); 770 | this.y = random(min, max); 771 | return this; 772 | }; 773 | 774 | /** 775 | * Randomly randomizes either axis between 2 vectors 776 | * 777 | * ### Examples: 778 | * var vec = new Victor(100, 50); 779 | * 780 | * vec.randomizeAny(new Victor(50, 60), new Victor(70, 80)); 781 | * vec.toString(); 782 | * // => x:100, y:77 783 | * 784 | * @param {Victor} topLeft first vector 785 | * @param {Victor} bottomRight second vector 786 | * @return {Victor} `this` for chaining capabilities 787 | * @api public 788 | */ 789 | Victor.prototype.randomizeAny = function (topLeft, bottomRight) { 790 | if (!! Math.round(Math.random())) { 791 | this.randomizeX(topLeft, bottomRight); 792 | } else { 793 | this.randomizeY(topLeft, bottomRight); 794 | } 795 | return this; 796 | }; 797 | 798 | /** 799 | * Rounds both axis to an integer value 800 | * 801 | * ### Examples: 802 | * var vec = new Victor(100.2, 50.9); 803 | * 804 | * vec.unfloat(); 805 | * vec.toString(); 806 | * // => x:100, y:51 807 | * 808 | * @return {Victor} `this` for chaining capabilities 809 | * @api public 810 | */ 811 | Victor.prototype.unfloat = function () { 812 | this.x = Math.round(this.x); 813 | this.y = Math.round(this.y); 814 | return this; 815 | }; 816 | 817 | /** 818 | * Rounds both axis to a certain precision 819 | * 820 | * ### Examples: 821 | * var vec = new Victor(100.2, 50.9); 822 | * 823 | * vec.unfloat(); 824 | * vec.toString(); 825 | * // => x:100, y:51 826 | * 827 | * @param {Number} Precision (default: 8) 828 | * @return {Victor} `this` for chaining capabilities 829 | * @api public 830 | */ 831 | Victor.prototype.toFixed = function (precision) { 832 | if (typeof precision === 'undefined') { precision = 8; } 833 | this.x = this.x.toFixed(precision); 834 | this.y = this.y.toFixed(precision); 835 | return this; 836 | }; 837 | 838 | /** 839 | * Performs a linear blend / interpolation of the X axis towards another vector 840 | * 841 | * ### Examples: 842 | * var vec1 = new Victor(100, 100); 843 | * var vec2 = new Victor(200, 200); 844 | * 845 | * vec1.mixX(vec2, 0.5); 846 | * vec.toString(); 847 | * // => x:150, y:100 848 | * 849 | * @param {Victor} vector The other vector 850 | * @param {Number} amount The blend amount (optional, default: 0.5) 851 | * @return {Victor} `this` for chaining capabilities 852 | * @api public 853 | */ 854 | Victor.prototype.mixX = function (vec, amount) { 855 | if (typeof amount === 'undefined') { 856 | amount = 0.5; 857 | } 858 | 859 | this.x = (1 - amount) * this.x + amount * vec.x; 860 | return this; 861 | }; 862 | 863 | /** 864 | * Performs a linear blend / interpolation of the Y axis towards another vector 865 | * 866 | * ### Examples: 867 | * var vec1 = new Victor(100, 100); 868 | * var vec2 = new Victor(200, 200); 869 | * 870 | * vec1.mixY(vec2, 0.5); 871 | * vec.toString(); 872 | * // => x:100, y:150 873 | * 874 | * @param {Victor} vector The other vector 875 | * @param {Number} amount The blend amount (optional, default: 0.5) 876 | * @return {Victor} `this` for chaining capabilities 877 | * @api public 878 | */ 879 | Victor.prototype.mixY = function (vec, amount) { 880 | if (typeof amount === 'undefined') { 881 | amount = 0.5; 882 | } 883 | 884 | this.y = (1 - amount) * this.y + amount * vec.y; 885 | return this; 886 | }; 887 | 888 | /** 889 | * Performs a linear blend / interpolation towards another vector 890 | * 891 | * ### Examples: 892 | * var vec1 = new Victor(100, 100); 893 | * var vec2 = new Victor(200, 200); 894 | * 895 | * vec1.mix(vec2, 0.5); 896 | * vec.toString(); 897 | * // => x:150, y:150 898 | * 899 | * @param {Victor} vector The other vector 900 | * @param {Number} amount The blend amount (optional, default: 0.5) 901 | * @return {Victor} `this` for chaining capabilities 902 | * @api public 903 | */ 904 | Victor.prototype.mix = function (vec, amount) { 905 | this.mixX(vec, amount); 906 | this.mixY(vec, amount); 907 | return this; 908 | }; 909 | 910 | /** 911 | * # Products 912 | */ 913 | 914 | /** 915 | * Creates a clone of this vector 916 | * 917 | * ### Examples: 918 | * var vec1 = new Victor(10, 10); 919 | * var vec2 = vec1.clone(); 920 | * 921 | * vec2.toString(); 922 | * // => x:10, y:10 923 | * 924 | * @return {Victor} A clone of the vector 925 | * @api public 926 | */ 927 | Victor.prototype.clone = function () { 928 | return new Victor(this.x, this.y); 929 | }; 930 | 931 | /** 932 | * Copies another vector's X component in to its own 933 | * 934 | * ### Examples: 935 | * var vec1 = new Victor(10, 10); 936 | * var vec2 = new Victor(20, 20); 937 | * var vec2 = vec1.copyX(vec1); 938 | * 939 | * vec2.toString(); 940 | * // => x:20, y:10 941 | * 942 | * @return {Victor} `this` for chaining capabilities 943 | * @api public 944 | */ 945 | Victor.prototype.copyX = function (vec) { 946 | this.x = vec.x; 947 | return this; 948 | }; 949 | 950 | /** 951 | * Copies another vector's Y component in to its own 952 | * 953 | * ### Examples: 954 | * var vec1 = new Victor(10, 10); 955 | * var vec2 = new Victor(20, 20); 956 | * var vec2 = vec1.copyY(vec1); 957 | * 958 | * vec2.toString(); 959 | * // => x:10, y:20 960 | * 961 | * @return {Victor} `this` for chaining capabilities 962 | * @api public 963 | */ 964 | Victor.prototype.copyY = function (vec) { 965 | this.y = vec.y; 966 | return this; 967 | }; 968 | 969 | /** 970 | * Copies another vector's X and Y components in to its own 971 | * 972 | * ### Examples: 973 | * var vec1 = new Victor(10, 10); 974 | * var vec2 = new Victor(20, 20); 975 | * var vec2 = vec1.copy(vec1); 976 | * 977 | * vec2.toString(); 978 | * // => x:20, y:20 979 | * 980 | * @return {Victor} `this` for chaining capabilities 981 | * @api public 982 | */ 983 | Victor.prototype.copy = function (vec) { 984 | this.copyX(vec); 985 | this.copyY(vec); 986 | return this; 987 | }; 988 | 989 | /** 990 | * Sets the vector to zero (0,0) 991 | * 992 | * ### Examples: 993 | * var vec1 = new Victor(10, 10); 994 | * var1.zero(); 995 | * vec1.toString(); 996 | * // => x:0, y:0 997 | * 998 | * @return {Victor} `this` for chaining capabilities 999 | * @api public 1000 | */ 1001 | Victor.prototype.zero = function () { 1002 | this.x = this.y = 0; 1003 | return this; 1004 | }; 1005 | 1006 | /** 1007 | * Calculates the dot product of this vector and another 1008 | * 1009 | * ### Examples: 1010 | * var vec1 = new Victor(100, 50); 1011 | * var vec2 = new Victor(200, 60); 1012 | * 1013 | * vec1.dot(vec2); 1014 | * // => 23000 1015 | * 1016 | * @param {Victor} vector The second vector 1017 | * @return {Number} Dot product 1018 | * @api public 1019 | */ 1020 | Victor.prototype.dot = function (vec2) { 1021 | return this.x * vec2.x + this.y * vec2.y; 1022 | }; 1023 | 1024 | Victor.prototype.cross = function (vec2) { 1025 | return (this.x * vec2.y ) - (this.y * vec2.x ); 1026 | }; 1027 | 1028 | /** 1029 | * Projects a vector onto another vector, setting itself to the result. 1030 | * 1031 | * ### Examples: 1032 | * var vec = new Victor(100, 0); 1033 | * var vec2 = new Victor(100, 100); 1034 | * 1035 | * vec.projectOnto(vec2); 1036 | * vec.toString(); 1037 | * // => x:50, y:50 1038 | * 1039 | * @param {Victor} vector The other vector you want to project this vector onto 1040 | * @return {Victor} `this` for chaining capabilities 1041 | * @api public 1042 | */ 1043 | Victor.prototype.projectOnto = function (vec2) { 1044 | var coeff = ( (this.x * vec2.x)+(this.y * vec2.y) ) / ((vec2.x*vec2.x)+(vec2.y*vec2.y)); 1045 | this.x = coeff * vec2.x; 1046 | this.y = coeff * vec2.y; 1047 | return this; 1048 | }; 1049 | 1050 | 1051 | Victor.prototype.horizontalAngle = function () { 1052 | return Math.atan2(this.y, this.x); 1053 | }; 1054 | 1055 | Victor.prototype.horizontalAngleDeg = function () { 1056 | return radian2degrees(this.horizontalAngle()); 1057 | }; 1058 | 1059 | Victor.prototype.verticalAngle = function () { 1060 | return Math.atan2(this.x, this.y); 1061 | }; 1062 | 1063 | Victor.prototype.verticalAngleDeg = function () { 1064 | return radian2degrees(this.verticalAngle()); 1065 | }; 1066 | 1067 | Victor.prototype.angle = Victor.prototype.horizontalAngle; 1068 | Victor.prototype.angleDeg = Victor.prototype.horizontalAngleDeg; 1069 | Victor.prototype.direction = Victor.prototype.horizontalAngle; 1070 | 1071 | Victor.prototype.rotate = function (angle) { 1072 | var nx = (this.x * Math.cos(angle)) - (this.y * Math.sin(angle)); 1073 | var ny = (this.x * Math.sin(angle)) + (this.y * Math.cos(angle)); 1074 | 1075 | this.x = nx; 1076 | this.y = ny; 1077 | 1078 | return this; 1079 | }; 1080 | 1081 | Victor.prototype.rotateDeg = function (angle) { 1082 | angle = degrees2radian(angle); 1083 | return this.rotate(angle); 1084 | }; 1085 | 1086 | Victor.prototype.rotateTo = function(rotation) { 1087 | return this.rotate(rotation-this.angle()); 1088 | }; 1089 | 1090 | Victor.prototype.rotateToDeg = function(rotation) { 1091 | rotation = degrees2radian(rotation); 1092 | return this.rotateTo(rotation); 1093 | }; 1094 | 1095 | Victor.prototype.rotateBy = function (rotation) { 1096 | var angle = this.angle() + rotation; 1097 | 1098 | return this.rotate(angle); 1099 | }; 1100 | 1101 | Victor.prototype.rotateByDeg = function (rotation) { 1102 | rotation = degrees2radian(rotation); 1103 | return this.rotateBy(rotation); 1104 | }; 1105 | 1106 | /** 1107 | * Calculates the distance of the X axis between this vector and another 1108 | * 1109 | * ### Examples: 1110 | * var vec1 = new Victor(100, 50); 1111 | * var vec2 = new Victor(200, 60); 1112 | * 1113 | * vec1.distanceX(vec2); 1114 | * // => -100 1115 | * 1116 | * @param {Victor} vector The second vector 1117 | * @return {Number} Distance 1118 | * @api public 1119 | */ 1120 | Victor.prototype.distanceX = function (vec) { 1121 | return this.x - vec.x; 1122 | }; 1123 | 1124 | /** 1125 | * Same as `distanceX()` but always returns an absolute number 1126 | * 1127 | * ### Examples: 1128 | * var vec1 = new Victor(100, 50); 1129 | * var vec2 = new Victor(200, 60); 1130 | * 1131 | * vec1.absDistanceX(vec2); 1132 | * // => 100 1133 | * 1134 | * @param {Victor} vector The second vector 1135 | * @return {Number} Absolute distance 1136 | * @api public 1137 | */ 1138 | Victor.prototype.absDistanceX = function (vec) { 1139 | return Math.abs(this.distanceX(vec)); 1140 | }; 1141 | 1142 | /** 1143 | * Calculates the distance of the Y axis between this vector and another 1144 | * 1145 | * ### Examples: 1146 | * var vec1 = new Victor(100, 50); 1147 | * var vec2 = new Victor(200, 60); 1148 | * 1149 | * vec1.distanceY(vec2); 1150 | * // => -10 1151 | * 1152 | * @param {Victor} vector The second vector 1153 | * @return {Number} Distance 1154 | * @api public 1155 | */ 1156 | Victor.prototype.distanceY = function (vec) { 1157 | return this.y - vec.y; 1158 | }; 1159 | 1160 | /** 1161 | * Same as `distanceY()` but always returns an absolute number 1162 | * 1163 | * ### Examples: 1164 | * var vec1 = new Victor(100, 50); 1165 | * var vec2 = new Victor(200, 60); 1166 | * 1167 | * vec1.distanceY(vec2); 1168 | * // => 10 1169 | * 1170 | * @param {Victor} vector The second vector 1171 | * @return {Number} Absolute distance 1172 | * @api public 1173 | */ 1174 | Victor.prototype.absDistanceY = function (vec) { 1175 | return Math.abs(this.distanceY(vec)); 1176 | }; 1177 | 1178 | /** 1179 | * Calculates the euclidean distance between this vector and another 1180 | * 1181 | * ### Examples: 1182 | * var vec1 = new Victor(100, 50); 1183 | * var vec2 = new Victor(200, 60); 1184 | * 1185 | * vec1.distance(vec2); 1186 | * // => 100.4987562112089 1187 | * 1188 | * @param {Victor} vector The second vector 1189 | * @return {Number} Distance 1190 | * @api public 1191 | */ 1192 | Victor.prototype.distance = function (vec) { 1193 | return Math.sqrt(this.distanceSq(vec)); 1194 | }; 1195 | 1196 | /** 1197 | * Calculates the squared euclidean distance between this vector and another 1198 | * 1199 | * ### Examples: 1200 | * var vec1 = new Victor(100, 50); 1201 | * var vec2 = new Victor(200, 60); 1202 | * 1203 | * vec1.distanceSq(vec2); 1204 | * // => 10100 1205 | * 1206 | * @param {Victor} vector The second vector 1207 | * @return {Number} Distance 1208 | * @api public 1209 | */ 1210 | Victor.prototype.distanceSq = function (vec) { 1211 | var dx = this.distanceX(vec), 1212 | dy = this.distanceY(vec); 1213 | 1214 | return dx * dx + dy * dy; 1215 | }; 1216 | 1217 | /** 1218 | * Calculates the length or magnitude of the vector 1219 | * 1220 | * ### Examples: 1221 | * var vec = new Victor(100, 50); 1222 | * 1223 | * vec.length(); 1224 | * // => 111.80339887498948 1225 | * 1226 | * @return {Number} Length / Magnitude 1227 | * @api public 1228 | */ 1229 | Victor.prototype.length = function () { 1230 | return Math.sqrt(this.lengthSq()); 1231 | }; 1232 | 1233 | /** 1234 | * Squared length / magnitude 1235 | * 1236 | * ### Examples: 1237 | * var vec = new Victor(100, 50); 1238 | * 1239 | * vec.lengthSq(); 1240 | * // => 12500 1241 | * 1242 | * @return {Number} Length / Magnitude 1243 | * @api public 1244 | */ 1245 | Victor.prototype.lengthSq = function () { 1246 | return this.x * this.x + this.y * this.y; 1247 | }; 1248 | 1249 | Victor.prototype.magnitude = Victor.prototype.length; 1250 | 1251 | /** 1252 | * Returns a true if vector is (0, 0) 1253 | * 1254 | * ### Examples: 1255 | * var vec = new Victor(100, 50); 1256 | * vec.zero(); 1257 | * 1258 | * // => true 1259 | * 1260 | * @return {Boolean} 1261 | * @api public 1262 | */ 1263 | Victor.prototype.isZero = function() { 1264 | return this.x === 0 && this.y === 0; 1265 | }; 1266 | 1267 | /** 1268 | * Returns a true if this vector is the same as another 1269 | * 1270 | * ### Examples: 1271 | * var vec1 = new Victor(100, 50); 1272 | * var vec2 = new Victor(100, 50); 1273 | * vec1.isEqualTo(vec2); 1274 | * 1275 | * // => true 1276 | * 1277 | * @return {Boolean} 1278 | * @api public 1279 | */ 1280 | Victor.prototype.isEqualTo = function(vec2) { 1281 | return this.x === vec2.x && this.y === vec2.y; 1282 | }; 1283 | 1284 | /** 1285 | * # Utility Methods 1286 | */ 1287 | 1288 | /** 1289 | * Returns an string representation of the vector 1290 | * 1291 | * ### Examples: 1292 | * var vec = new Victor(10, 20); 1293 | * 1294 | * vec.toString(); 1295 | * // => x:10, y:20 1296 | * 1297 | * @return {String} 1298 | * @api public 1299 | */ 1300 | Victor.prototype.toString = function () { 1301 | return 'x:' + this.x + ', y:' + this.y; 1302 | }; 1303 | 1304 | /** 1305 | * Returns an array representation of the vector 1306 | * 1307 | * ### Examples: 1308 | * var vec = new Victor(10, 20); 1309 | * 1310 | * vec.toArray(); 1311 | * // => [10, 20] 1312 | * 1313 | * @return {Array} 1314 | * @api public 1315 | */ 1316 | Victor.prototype.toArray = function () { 1317 | return [ this.x, this.y ]; 1318 | }; 1319 | 1320 | /** 1321 | * Returns an object representation of the vector 1322 | * 1323 | * ### Examples: 1324 | * var vec = new Victor(10, 20); 1325 | * 1326 | * vec.toObject(); 1327 | * // => { x: 10, y: 20 } 1328 | * 1329 | * @return {Object} 1330 | * @api public 1331 | */ 1332 | Victor.prototype.toObject = function () { 1333 | return { x: this.x, y: this.y }; 1334 | }; 1335 | 1336 | 1337 | var degrees = 180 / Math.PI; 1338 | 1339 | function random (min, max) { 1340 | return Math.floor(Math.random() * (max - min + 1) + min); 1341 | } 1342 | 1343 | function radian2degrees (rad) { 1344 | return rad * degrees; 1345 | } 1346 | 1347 | function degrees2radian (deg) { 1348 | return deg / degrees; 1349 | } 1350 | 1351 | },{}]},{},[1]) 1352 | (1) 1353 | }); -------------------------------------------------------------------------------- /build/victor.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | MIT License 3 | 4 | Copyright (c) 2011 Max Kueng, George Crabtree 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | "Software"), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be 15 | included in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | !function(t){if("object"==typeof exports)module.exports=t();else if("function"==typeof define&&define.amd)define(t);else{var i;"undefined"!=typeof window?i=window:"undefined"!=typeof global?i=global:"undefined"!=typeof self&&(i=self),i.Victor=t()}}(function(){return function t(i,r,n){function o(s,h){if(!r[s]){if(!i[s]){var u="function"==typeof require&&require;if(!h&&u)return u(s,!0);if(e)return e(s,!0);throw new Error("Cannot find module '"+s+"'")}var p=r[s]={exports:{}};i[s][0].call(p.exports,function(t){var r=i[s][1][t];return o(r?r:t)},p,p.exports,t,i,r,n)}return r[s].exports}for(var e="function"==typeof require&&require,s=0;st&&(this.x*=i),Math.abs(this.y)>t&&(this.y*=i),this},n.prototype.randomize=function(t,i){return this.randomizeX(t,i),this.randomizeY(t,i),this},n.prototype.randomizeX=function(t,i){var r=Math.min(t.x,i.x),n=Math.max(t.x,i.x);return this.x=o(r,n),this},n.prototype.randomizeY=function(t,i){var r=Math.min(t.y,i.y),n=Math.max(t.y,i.y);return this.y=o(r,n),this},n.prototype.randomizeAny=function(t,i){return Math.round(Math.random())?this.randomizeX(t,i):this.randomizeY(t,i),this},n.prototype.unfloat=function(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this},n.prototype.toFixed=function(t){return"undefined"==typeof t&&(t=8),this.x=this.x.toFixed(t),this.y=this.y.toFixed(t),this},n.prototype.mixX=function(t,i){return"undefined"==typeof i&&(i=.5),this.x=(1-i)*this.x+i*t.x,this},n.prototype.mixY=function(t,i){return"undefined"==typeof i&&(i=.5),this.y=(1-i)*this.y+i*t.y,this},n.prototype.mix=function(t,i){return this.mixX(t,i),this.mixY(t,i),this},n.prototype.clone=function(){return new n(this.x,this.y)},n.prototype.copyX=function(t){return this.x=t.x,this},n.prototype.copyY=function(t){return this.y=t.y,this},n.prototype.copy=function(t){return this.copyX(t),this.copyY(t),this},n.prototype.zero=function(){return this.x=this.y=0,this},n.prototype.dot=function(t){return this.x*t.x+this.y*t.y},n.prototype.cross=function(t){return this.x*t.y-this.y*t.x},n.prototype.projectOnto=function(t){var i=(this.x*t.x+this.y*t.y)/(t.x*t.x+t.y*t.y);return this.x=i*t.x,this.y=i*t.y,this},n.prototype.horizontalAngle=function(){return Math.atan2(this.y,this.x)},n.prototype.horizontalAngleDeg=function(){return e(this.horizontalAngle())},n.prototype.verticalAngle=function(){return Math.atan2(this.x,this.y)},n.prototype.verticalAngleDeg=function(){return e(this.verticalAngle())},n.prototype.angle=n.prototype.horizontalAngle,n.prototype.angleDeg=n.prototype.horizontalAngleDeg,n.prototype.direction=n.prototype.horizontalAngle,n.prototype.rotate=function(t){var i=this.x*Math.cos(t)-this.y*Math.sin(t),r=this.x*Math.sin(t)+this.y*Math.cos(t);return this.x=i,this.y=r,this},n.prototype.rotateDeg=function(t){return t=s(t),this.rotate(t)},n.prototype.rotateTo=function(t){return this.rotate(t-this.angle())},n.prototype.rotateToDeg=function(t){return t=s(t),this.rotateTo(t)},n.prototype.rotateBy=function(t){var i=this.angle()+t;return this.rotate(i)},n.prototype.rotateByDeg=function(t){return t=s(t),this.rotateBy(t)},n.prototype.distanceX=function(t){return this.x-t.x},n.prototype.absDistanceX=function(t){return Math.abs(this.distanceX(t))},n.prototype.distanceY=function(t){return this.y-t.y},n.prototype.absDistanceY=function(t){return Math.abs(this.distanceY(t))},n.prototype.distance=function(t){return Math.sqrt(this.distanceSq(t))},n.prototype.distanceSq=function(t){var i=this.distanceX(t),r=this.distanceY(t);return i*i+r*r},n.prototype.length=function(){return Math.sqrt(this.lengthSq())},n.prototype.lengthSq=function(){return this.x*this.x+this.y*this.y},n.prototype.magnitude=n.prototype.length,n.prototype.isZero=function(){return 0===this.x&&0===this.y},n.prototype.isEqualTo=function(t){return this.x===t.x&&this.y===t.y},n.prototype.toString=function(){return"x:"+this.x+", y:"+this.y},n.prototype.toArray=function(){return[this.x,this.y]},n.prototype.toObject=function(){return{x:this.x,y:this.y}};var h=180/Math.PI},{}]},{},[1])(1)}); -------------------------------------------------------------------------------- /documentation/api.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | # Victor - A JavaScript 2D vector class with methods for common vector operations 6 | 7 | ## Victor(x, y) 8 | 9 | Constructor. Will also work without the `new` keyword 10 | 11 | ### Examples: 12 | var vec1 = new Victor(100, 50); 13 | var vec2 = Victor(42, 1337); 14 | 15 | ### Params: 16 | 17 | * **Number** *x* Value of the x axis 18 | * **Number** *y* Value of the y axis 19 | 20 | ### Return: 21 | 22 | * **Victor** 23 | 24 | ## x 25 | 26 | The X axis 27 | 28 | ### Examples: 29 | var vec = new Victor.fromArray(42, 21); 30 | 31 | vec.x; 32 | // => 42 33 | 34 | ## y 35 | 36 | The Y axis 37 | 38 | ### Examples: 39 | var vec = new Victor.fromArray(42, 21); 40 | 41 | vec.y; 42 | // => 21 43 | 44 | # Static 45 | 46 | ## Victor.fromArray(array) 47 | 48 | Creates a new instance from an array 49 | 50 | ### Examples: 51 | var vec = Victor.fromArray([42, 21]); 52 | 53 | vec.toString(); 54 | // => x:42, y:21 55 | 56 | ### Params: 57 | 58 | * **Array** *array* Array with the x and y values at index 0 and 1 respectively 59 | 60 | ### Return: 61 | 62 | * **Victor** The new instance 63 | 64 | ## Victor.fromObject(obj) 65 | 66 | Creates a new instance from an object 67 | 68 | ### Examples: 69 | var vec = Victor.fromObject({ x: 42, y: 21 }); 70 | 71 | vec.toString(); 72 | // => x:42, y:21 73 | 74 | ### Params: 75 | 76 | * **Object** *obj* Object with the values for x and y 77 | 78 | ### Return: 79 | 80 | * **Victor** The new instance 81 | 82 | # Manipulation 83 | 84 | These functions are chainable. 85 | 86 | ## addX(vector) 87 | 88 | Adds another vector's X axis to this one 89 | 90 | ### Examples: 91 | var vec1 = new Victor(10, 10); 92 | var vec2 = new Victor(20, 30); 93 | 94 | vec1.addX(vec2); 95 | vec1.toString(); 96 | // => x:30, y:10 97 | 98 | ### Params: 99 | 100 | * **Victor** *vector* The other vector you want to add to this one 101 | 102 | ### Return: 103 | 104 | * **Victor** `this` for chaining capabilities 105 | 106 | ## addY(vector) 107 | 108 | Adds another vector's Y axis to this one 109 | 110 | ### Examples: 111 | var vec1 = new Victor(10, 10); 112 | var vec2 = new Victor(20, 30); 113 | 114 | vec1.addY(vec2); 115 | vec1.toString(); 116 | // => x:10, y:40 117 | 118 | ### Params: 119 | 120 | * **Victor** *vector* The other vector you want to add to this one 121 | 122 | ### Return: 123 | 124 | * **Victor** `this` for chaining capabilities 125 | 126 | ## add(vector) 127 | 128 | Adds another vector to this one 129 | 130 | ### Examples: 131 | var vec1 = new Victor(10, 10); 132 | var vec2 = new Victor(20, 30); 133 | 134 | vec1.add(vec2); 135 | vec1.toString(); 136 | // => x:30, y:40 137 | 138 | ### Params: 139 | 140 | * **Victor** *vector* The other vector you want to add to this one 141 | 142 | ### Return: 143 | 144 | * **Victor** `this` for chaining capabilities 145 | 146 | ## addScalar(scalar) 147 | 148 | Adds the given scalar to both vector axis 149 | 150 | ### Examples: 151 | var vec = new Victor(1, 2); 152 | 153 | vec.addScalar(2); 154 | vec.toString(); 155 | // => x: 3, y: 4 156 | 157 | ### Params: 158 | 159 | * **Number** *scalar* The scalar to add 160 | 161 | ### Return: 162 | 163 | * **Victor** `this` for chaining capabilities 164 | 165 | ## addScalarX(scalar) 166 | 167 | Adds the given scalar to the X axis 168 | 169 | ### Examples: 170 | var vec = new Victor(1, 2); 171 | 172 | vec.addScalarX(2); 173 | vec.toString(); 174 | // => x: 3, y: 2 175 | 176 | ### Params: 177 | 178 | * **Number** *scalar* The scalar to add 179 | 180 | ### Return: 181 | 182 | * **Victor** `this` for chaining capabilities 183 | 184 | ## addScalarY(scalar) 185 | 186 | Adds the given scalar to the Y axis 187 | 188 | ### Examples: 189 | var vec = new Victor(1, 2); 190 | 191 | vec.addScalarY(2); 192 | vec.toString(); 193 | // => x: 1, y: 4 194 | 195 | ### Params: 196 | 197 | * **Number** *scalar* The scalar to add 198 | 199 | ### Return: 200 | 201 | * **Victor** `this` for chaining capabilities 202 | 203 | ## subtractX(vector) 204 | 205 | Subtracts the X axis of another vector from this one 206 | 207 | ### Examples: 208 | var vec1 = new Victor(100, 50); 209 | var vec2 = new Victor(20, 30); 210 | 211 | vec1.subtractX(vec2); 212 | vec1.toString(); 213 | // => x:80, y:50 214 | 215 | ### Params: 216 | 217 | * **Victor** *vector* The other vector you want subtract from this one 218 | 219 | ### Return: 220 | 221 | * **Victor** `this` for chaining capabilities 222 | 223 | ## subtractY(vector) 224 | 225 | Subtracts the Y axis of another vector from this one 226 | 227 | ### Examples: 228 | var vec1 = new Victor(100, 50); 229 | var vec2 = new Victor(20, 30); 230 | 231 | vec1.subtractY(vec2); 232 | vec1.toString(); 233 | // => x:100, y:20 234 | 235 | ### Params: 236 | 237 | * **Victor** *vector* The other vector you want subtract from this one 238 | 239 | ### Return: 240 | 241 | * **Victor** `this` for chaining capabilities 242 | 243 | ## subtract(vector) 244 | 245 | Subtracts another vector from this one 246 | 247 | ### Examples: 248 | var vec1 = new Victor(100, 50); 249 | var vec2 = new Victor(20, 30); 250 | 251 | vec1.subtract(vec2); 252 | vec1.toString(); 253 | // => x:80, y:20 254 | 255 | ### Params: 256 | 257 | * **Victor** *vector* The other vector you want subtract from this one 258 | 259 | ### Return: 260 | 261 | * **Victor** `this` for chaining capabilities 262 | 263 | ## subtractScalar(scalar) 264 | 265 | Subtracts the given scalar from both axis 266 | 267 | ### Examples: 268 | var vec = new Victor(100, 200); 269 | 270 | vec.subtractScalar(20); 271 | vec.toString(); 272 | // => x: 80, y: 180 273 | 274 | ### Params: 275 | 276 | * **Number** *scalar* The scalar to subtract 277 | 278 | ### Return: 279 | 280 | * **Victor** `this` for chaining capabilities 281 | 282 | ## subtractScalarX(scalar) 283 | 284 | Subtracts the given scalar from the X axis 285 | 286 | ### Examples: 287 | var vec = new Victor(100, 200); 288 | 289 | vec.subtractScalarX(20); 290 | vec.toString(); 291 | // => x: 80, y: 200 292 | 293 | ### Params: 294 | 295 | * **Number** *scalar* The scalar to subtract 296 | 297 | ### Return: 298 | 299 | * **Victor** `this` for chaining capabilities 300 | 301 | ## subtractScalarY(scalar) 302 | 303 | Subtracts the given scalar from the Y axis 304 | 305 | ### Examples: 306 | var vec = new Victor(100, 200); 307 | 308 | vec.subtractScalarY(20); 309 | vec.toString(); 310 | // => x: 100, y: 180 311 | 312 | ### Params: 313 | 314 | * **Number** *scalar* The scalar to subtract 315 | 316 | ### Return: 317 | 318 | * **Victor** `this` for chaining capabilities 319 | 320 | ## divideX(vector) 321 | 322 | Divides the X axis by the x component of given vector 323 | 324 | ### Examples: 325 | var vec = new Victor(100, 50); 326 | var vec2 = new Victor(2, 0); 327 | 328 | vec.divideX(vec2); 329 | vec.toString(); 330 | // => x:50, y:50 331 | 332 | ### Params: 333 | 334 | * **Victor** *vector* The other vector you want divide by 335 | 336 | ### Return: 337 | 338 | * **Victor** `this` for chaining capabilities 339 | 340 | ## divideY(vector) 341 | 342 | Divides the Y axis by the y component of given vector 343 | 344 | ### Examples: 345 | var vec = new Victor(100, 50); 346 | var vec2 = new Victor(0, 2); 347 | 348 | vec.divideY(vec2); 349 | vec.toString(); 350 | // => x:100, y:25 351 | 352 | ### Params: 353 | 354 | * **Victor** *vector* The other vector you want divide by 355 | 356 | ### Return: 357 | 358 | * **Victor** `this` for chaining capabilities 359 | 360 | ## divide(vector) 361 | 362 | Divides both vector axis by a axis values of given vector 363 | 364 | ### Examples: 365 | var vec = new Victor(100, 50); 366 | var vec2 = new Victor(2, 2); 367 | 368 | vec.divide(vec2); 369 | vec.toString(); 370 | // => x:50, y:25 371 | 372 | ### Params: 373 | 374 | * **Victor** *vector* The vector to divide by 375 | 376 | ### Return: 377 | 378 | * **Victor** `this` for chaining capabilities 379 | 380 | ## divideScalar(The) 381 | 382 | Divides both vector axis by the given scalar value 383 | 384 | ### Examples: 385 | var vec = new Victor(100, 50); 386 | 387 | vec.divideScalar(2); 388 | vec.toString(); 389 | // => x:50, y:25 390 | 391 | ### Params: 392 | 393 | * **Number** *The* scalar to divide by 394 | 395 | ### Return: 396 | 397 | * **Victor** `this` for chaining capabilities 398 | 399 | ## divideScalarX(The) 400 | 401 | Divides the X axis by the given scalar value 402 | 403 | ### Examples: 404 | var vec = new Victor(100, 50); 405 | 406 | vec.divideScalarX(2); 407 | vec.toString(); 408 | // => x:50, y:50 409 | 410 | ### Params: 411 | 412 | * **Number** *The* scalar to divide by 413 | 414 | ### Return: 415 | 416 | * **Victor** `this` for chaining capabilities 417 | 418 | ## divideScalarY(The) 419 | 420 | Divides the Y axis by the given scalar value 421 | 422 | ### Examples: 423 | var vec = new Victor(100, 50); 424 | 425 | vec.divideScalarY(2); 426 | vec.toString(); 427 | // => x:100, y:25 428 | 429 | ### Params: 430 | 431 | * **Number** *The* scalar to divide by 432 | 433 | ### Return: 434 | 435 | * **Victor** `this` for chaining capabilities 436 | 437 | ## invertX() 438 | 439 | Inverts the X axis 440 | 441 | ### Examples: 442 | var vec = new Victor(100, 50); 443 | 444 | vec.invertX(); 445 | vec.toString(); 446 | // => x:-100, y:50 447 | 448 | ### Return: 449 | 450 | * **Victor** `this` for chaining capabilities 451 | 452 | ## invertY() 453 | 454 | Inverts the Y axis 455 | 456 | ### Examples: 457 | var vec = new Victor(100, 50); 458 | 459 | vec.invertY(); 460 | vec.toString(); 461 | // => x:100, y:-50 462 | 463 | ### Return: 464 | 465 | * **Victor** `this` for chaining capabilities 466 | 467 | ## invert() 468 | 469 | Inverts both axis 470 | 471 | ### Examples: 472 | var vec = new Victor(100, 50); 473 | 474 | vec.invert(); 475 | vec.toString(); 476 | // => x:-100, y:-50 477 | 478 | ### Return: 479 | 480 | * **Victor** `this` for chaining capabilities 481 | 482 | ## multiplyX(vector) 483 | 484 | Multiplies the X axis by X component of given vector 485 | 486 | ### Examples: 487 | var vec = new Victor(100, 50); 488 | var vec2 = new Victor(2, 0); 489 | 490 | vec.multiplyX(vec2); 491 | vec.toString(); 492 | // => x:200, y:50 493 | 494 | ### Params: 495 | 496 | * **Victor** *vector* The vector to multiply the axis with 497 | 498 | ### Return: 499 | 500 | * **Victor** `this` for chaining capabilities 501 | 502 | ## multiplyY(vector) 503 | 504 | Multiplies the Y axis by Y component of given vector 505 | 506 | ### Examples: 507 | var vec = new Victor(100, 50); 508 | var vec2 = new Victor(0, 2); 509 | 510 | vec.multiplyX(vec2); 511 | vec.toString(); 512 | // => x:100, y:100 513 | 514 | ### Params: 515 | 516 | * **Victor** *vector* The vector to multiply the axis with 517 | 518 | ### Return: 519 | 520 | * **Victor** `this` for chaining capabilities 521 | 522 | ## multiply(vector) 523 | 524 | Multiplies both vector axis by values from a given vector 525 | 526 | ### Examples: 527 | var vec = new Victor(100, 50); 528 | var vec2 = new Victor(2, 2); 529 | 530 | vec.multiply(vec2); 531 | vec.toString(); 532 | // => x:200, y:100 533 | 534 | ### Params: 535 | 536 | * **Victor** *vector* The vector to multiply by 537 | 538 | ### Return: 539 | 540 | * **Victor** `this` for chaining capabilities 541 | 542 | ## multiplyScalar(The) 543 | 544 | Multiplies both vector axis by the given scalar value 545 | 546 | ### Examples: 547 | var vec = new Victor(100, 50); 548 | 549 | vec.multiplyScalar(2); 550 | vec.toString(); 551 | // => x:200, y:100 552 | 553 | ### Params: 554 | 555 | * **Number** *The* scalar to multiply by 556 | 557 | ### Return: 558 | 559 | * **Victor** `this` for chaining capabilities 560 | 561 | ## multiplyScalarX(The) 562 | 563 | Multiplies the X axis by the given scalar 564 | 565 | ### Examples: 566 | var vec = new Victor(100, 50); 567 | 568 | vec.multiplyScalarX(2); 569 | vec.toString(); 570 | // => x:200, y:50 571 | 572 | ### Params: 573 | 574 | * **Number** *The* scalar to multiply the axis with 575 | 576 | ### Return: 577 | 578 | * **Victor** `this` for chaining capabilities 579 | 580 | ## multiplyScalarY(The) 581 | 582 | Multiplies the Y axis by the given scalar 583 | 584 | ### Examples: 585 | var vec = new Victor(100, 50); 586 | 587 | vec.multiplyScalarY(2); 588 | vec.toString(); 589 | // => x:100, y:100 590 | 591 | ### Params: 592 | 593 | * **Number** *The* scalar to multiply the axis with 594 | 595 | ### Return: 596 | 597 | * **Victor** `this` for chaining capabilities 598 | 599 | ## normalize() 600 | 601 | Normalize 602 | 603 | ### Return: 604 | 605 | * **Victor** `this` for chaining capabilities 606 | 607 | ## limit(max, factor) 608 | 609 | If the absolute vector axis is greater than `max`, multiplies the axis by `factor` 610 | 611 | ### Examples: 612 | var vec = new Victor(100, 50); 613 | 614 | vec.limit(80, 0.9); 615 | vec.toString(); 616 | // => x:90, y:50 617 | 618 | ### Params: 619 | 620 | * **Number** *max* The maximum value for both x and y axis 621 | * **Number** *factor* Factor by which the axis are to be multiplied with 622 | 623 | ### Return: 624 | 625 | * **Victor** `this` for chaining capabilities 626 | 627 | ## randomize(topLeft, bottomRight) 628 | 629 | Randomizes both vector axis with a value between 2 vectors 630 | 631 | ### Examples: 632 | var vec = new Victor(100, 50); 633 | 634 | vec.randomize(new Victor(50, 60), new Victor(70, 80`)); 635 | vec.toString(); 636 | // => x:67, y:73 637 | 638 | ### Params: 639 | 640 | * **Victor** *topLeft* first vector 641 | * **Victor** *bottomRight* second vector 642 | 643 | ### Return: 644 | 645 | * **Victor** `this` for chaining capabilities 646 | 647 | ## randomizeX(topLeft, bottomRight) 648 | 649 | Randomizes the y axis with a value between 2 vectors 650 | 651 | ### Examples: 652 | var vec = new Victor(100, 50); 653 | 654 | vec.randomizeX(new Victor(50, 60), new Victor(70, 80`)); 655 | vec.toString(); 656 | // => x:55, y:50 657 | 658 | ### Params: 659 | 660 | * **Victor** *topLeft* first vector 661 | * **Victor** *bottomRight* second vector 662 | 663 | ### Return: 664 | 665 | * **Victor** `this` for chaining capabilities 666 | 667 | ## randomizeY(topLeft, bottomRight) 668 | 669 | Randomizes the y axis with a value between 2 vectors 670 | 671 | ### Examples: 672 | var vec = new Victor(100, 50); 673 | 674 | vec.randomizeY(new Victor(50, 60), new Victor(70, 80`)); 675 | vec.toString(); 676 | // => x:100, y:66 677 | 678 | ### Params: 679 | 680 | * **Victor** *topLeft* first vector 681 | * **Victor** *bottomRight* second vector 682 | 683 | ### Return: 684 | 685 | * **Victor** `this` for chaining capabilities 686 | 687 | ## randomizeAny(topLeft, bottomRight) 688 | 689 | Randomly randomizes either axis between 2 vectors 690 | 691 | ### Examples: 692 | var vec = new Victor(100, 50); 693 | 694 | vec.randomizeAny(new Victor(50, 60), new Victor(70, 80)); 695 | vec.toString(); 696 | // => x:100, y:77 697 | 698 | ### Params: 699 | 700 | * **Victor** *topLeft* first vector 701 | * **Victor** *bottomRight* second vector 702 | 703 | ### Return: 704 | 705 | * **Victor** `this` for chaining capabilities 706 | 707 | ## unfloat() 708 | 709 | Rounds both axis to an integer value 710 | 711 | ### Examples: 712 | var vec = new Victor(100.2, 50.9); 713 | 714 | vec.unfloat(); 715 | vec.toString(); 716 | // => x:100, y:51 717 | 718 | ### Return: 719 | 720 | * **Victor** `this` for chaining capabilities 721 | 722 | ## toFixed(Precision) 723 | 724 | Rounds both axis to a certain precision 725 | 726 | ### Examples: 727 | var vec = new Victor(100.2, 50.9); 728 | 729 | vec.unfloat(); 730 | vec.toString(); 731 | // => x:100, y:51 732 | 733 | ### Params: 734 | 735 | * **Number** *Precision* (default: 8) 736 | 737 | ### Return: 738 | 739 | * **Victor** `this` for chaining capabilities 740 | 741 | ## mixX(vector, amount) 742 | 743 | Performs a linear blend / interpolation of the X axis towards another vector 744 | 745 | ### Examples: 746 | var vec1 = new Victor(100, 100); 747 | var vec2 = new Victor(200, 200); 748 | 749 | vec1.mixX(vec2, 0.5); 750 | vec.toString(); 751 | // => x:150, y:100 752 | 753 | ### Params: 754 | 755 | * **Victor** *vector* The other vector 756 | * **Number** *amount* The blend amount (optional, default: 0.5) 757 | 758 | ### Return: 759 | 760 | * **Victor** `this` for chaining capabilities 761 | 762 | ## mixY(vector, amount) 763 | 764 | Performs a linear blend / interpolation of the Y axis towards another vector 765 | 766 | ### Examples: 767 | var vec1 = new Victor(100, 100); 768 | var vec2 = new Victor(200, 200); 769 | 770 | vec1.mixY(vec2, 0.5); 771 | vec.toString(); 772 | // => x:100, y:150 773 | 774 | ### Params: 775 | 776 | * **Victor** *vector* The other vector 777 | * **Number** *amount* The blend amount (optional, default: 0.5) 778 | 779 | ### Return: 780 | 781 | * **Victor** `this` for chaining capabilities 782 | 783 | ## mix(vector, amount) 784 | 785 | Performs a linear blend / interpolation towards another vector 786 | 787 | ### Examples: 788 | var vec1 = new Victor(100, 100); 789 | var vec2 = new Victor(200, 200); 790 | 791 | vec1.mix(vec2, 0.5); 792 | vec.toString(); 793 | // => x:150, y:150 794 | 795 | ### Params: 796 | 797 | * **Victor** *vector* The other vector 798 | * **Number** *amount* The blend amount (optional, default: 0.5) 799 | 800 | ### Return: 801 | 802 | * **Victor** `this` for chaining capabilities 803 | 804 | # Products 805 | 806 | ## clone() 807 | 808 | Creates a clone of this vector 809 | 810 | ### Examples: 811 | var vec1 = new Victor(10, 10); 812 | var vec2 = vec1.clone(); 813 | 814 | vec2.toString(); 815 | // => x:10, y:10 816 | 817 | ### Return: 818 | 819 | * **Victor** A clone of the vector 820 | 821 | ## copyX() 822 | 823 | Copies another vector's X component in to its own 824 | 825 | ### Examples: 826 | var vec1 = new Victor(10, 10); 827 | var vec2 = new Victor(20, 20); 828 | var vec2 = vec1.copyX(vec1); 829 | 830 | vec2.toString(); 831 | // => x:20, y:10 832 | 833 | ### Return: 834 | 835 | * **Victor** `this` for chaining capabilities 836 | 837 | ## copyY() 838 | 839 | Copies another vector's Y component in to its own 840 | 841 | ### Examples: 842 | var vec1 = new Victor(10, 10); 843 | var vec2 = new Victor(20, 20); 844 | var vec2 = vec1.copyY(vec1); 845 | 846 | vec2.toString(); 847 | // => x:10, y:20 848 | 849 | ### Return: 850 | 851 | * **Victor** `this` for chaining capabilities 852 | 853 | ## copy() 854 | 855 | Copies another vector's X and Y components in to its own 856 | 857 | ### Examples: 858 | var vec1 = new Victor(10, 10); 859 | var vec2 = new Victor(20, 20); 860 | var vec2 = vec1.copy(vec1); 861 | 862 | vec2.toString(); 863 | // => x:20, y:20 864 | 865 | ### Return: 866 | 867 | * **Victor** `this` for chaining capabilities 868 | 869 | ## zero() 870 | 871 | Sets the vector to zero (0,0) 872 | 873 | ### Examples: 874 | var vec1 = new Victor(10, 10); 875 | var1.zero(); 876 | vec1.toString(); 877 | // => x:0, y:0 878 | 879 | ### Return: 880 | 881 | * **Victor** `this` for chaining capabilities 882 | 883 | ## dot(vector) 884 | 885 | Calculates the dot product of this vector and another 886 | 887 | ### Examples: 888 | var vec1 = new Victor(100, 50); 889 | var vec2 = new Victor(200, 60); 890 | 891 | vec1.dot(vec2); 892 | // => 23000 893 | 894 | ### Params: 895 | 896 | * **Victor** *vector* The second vector 897 | 898 | ### Return: 899 | 900 | * **Number** Dot product 901 | 902 | ## projectOnto(vector) 903 | 904 | Projects a vector onto another vector, setting itself to the result. 905 | 906 | ### Examples: 907 | var vec = new Victor(100, 0); 908 | var vec2 = new Victor(100, 100); 909 | 910 | vec.projectOnto(vec2); 911 | vec.toString(); 912 | // => x:50, y:50 913 | 914 | ### Params: 915 | 916 | * **Victor** *vector* The other vector you want to project this vector onto 917 | 918 | ### Return: 919 | 920 | * **Victor** `this` for chaining capabilities 921 | 922 | ## distanceX(vector) 923 | 924 | Calculates the distance of the X axis between this vector and another 925 | 926 | ### Examples: 927 | var vec1 = new Victor(100, 50); 928 | var vec2 = new Victor(200, 60); 929 | 930 | vec1.distanceX(vec2); 931 | // => -100 932 | 933 | ### Params: 934 | 935 | * **Victor** *vector* The second vector 936 | 937 | ### Return: 938 | 939 | * **Number** Distance 940 | 941 | ## absDistanceX(vector) 942 | 943 | Same as `distanceX()` but always returns an absolute number 944 | 945 | ### Examples: 946 | var vec1 = new Victor(100, 50); 947 | var vec2 = new Victor(200, 60); 948 | 949 | vec1.absDistanceX(vec2); 950 | // => 100 951 | 952 | ### Params: 953 | 954 | * **Victor** *vector* The second vector 955 | 956 | ### Return: 957 | 958 | * **Number** Absolute distance 959 | 960 | ## distanceY(vector) 961 | 962 | Calculates the distance of the Y axis between this vector and another 963 | 964 | ### Examples: 965 | var vec1 = new Victor(100, 50); 966 | var vec2 = new Victor(200, 60); 967 | 968 | vec1.distanceY(vec2); 969 | // => -10 970 | 971 | ### Params: 972 | 973 | * **Victor** *vector* The second vector 974 | 975 | ### Return: 976 | 977 | * **Number** Distance 978 | 979 | ## absDistanceY(vector) 980 | 981 | Same as `distanceY()` but always returns an absolute number 982 | 983 | ### Examples: 984 | var vec1 = new Victor(100, 50); 985 | var vec2 = new Victor(200, 60); 986 | 987 | vec1.distanceY(vec2); 988 | // => 10 989 | 990 | ### Params: 991 | 992 | * **Victor** *vector* The second vector 993 | 994 | ### Return: 995 | 996 | * **Number** Absolute distance 997 | 998 | ## distance(vector) 999 | 1000 | Calculates the euclidean distance between this vector and another 1001 | 1002 | ### Examples: 1003 | var vec1 = new Victor(100, 50); 1004 | var vec2 = new Victor(200, 60); 1005 | 1006 | vec1.distance(vec2); 1007 | // => 100.4987562112089 1008 | 1009 | ### Params: 1010 | 1011 | * **Victor** *vector* The second vector 1012 | 1013 | ### Return: 1014 | 1015 | * **Number** Distance 1016 | 1017 | ## distanceSq(vector) 1018 | 1019 | Calculates the squared euclidean distance between this vector and another 1020 | 1021 | ### Examples: 1022 | var vec1 = new Victor(100, 50); 1023 | var vec2 = new Victor(200, 60); 1024 | 1025 | vec1.distanceSq(vec2); 1026 | // => 10100 1027 | 1028 | ### Params: 1029 | 1030 | * **Victor** *vector* The second vector 1031 | 1032 | ### Return: 1033 | 1034 | * **Number** Distance 1035 | 1036 | ## length() 1037 | 1038 | Calculates the length or magnitude of the vector 1039 | 1040 | ### Examples: 1041 | var vec = new Victor(100, 50); 1042 | 1043 | vec.length(); 1044 | // => 111.80339887498948 1045 | 1046 | ### Return: 1047 | 1048 | * **Number** Length / Magnitude 1049 | 1050 | ## lengthSq() 1051 | 1052 | Squared length / magnitude 1053 | 1054 | ### Examples: 1055 | var vec = new Victor(100, 50); 1056 | 1057 | vec.lengthSq(); 1058 | // => 12500 1059 | 1060 | ### Return: 1061 | 1062 | * **Number** Length / Magnitude 1063 | 1064 | ## isZero() 1065 | 1066 | Returns a true if vector is (0, 0) 1067 | 1068 | ### Examples: 1069 | var vec = new Victor(100, 50); 1070 | vec.zero(); 1071 | 1072 | // => true 1073 | 1074 | ### Return: 1075 | 1076 | * **Boolean** 1077 | 1078 | ## isEqualTo() 1079 | 1080 | Returns a true if this vector is the same as another 1081 | 1082 | ### Examples: 1083 | var vec1 = new Victor(100, 50); 1084 | var vec2 = new Victor(100, 50); 1085 | vec1.isEqualTo(vec2); 1086 | 1087 | // => true 1088 | 1089 | ### Return: 1090 | 1091 | * **Boolean** 1092 | 1093 | # Utility Methods 1094 | 1095 | ## toString() 1096 | 1097 | Returns an string representation of the vector 1098 | 1099 | ### Examples: 1100 | var vec = new Victor(10, 20); 1101 | 1102 | vec.toString(); 1103 | // => x:10, y:20 1104 | 1105 | ### Return: 1106 | 1107 | * **String** 1108 | 1109 | ## toArray() 1110 | 1111 | Returns an array representation of the vector 1112 | 1113 | ### Examples: 1114 | var vec = new Victor(10, 20); 1115 | 1116 | vec.toArray(); 1117 | // => [10, 20] 1118 | 1119 | ### Return: 1120 | 1121 | * **Array** 1122 | 1123 | ## toObject() 1124 | 1125 | Returns an object representation of the vector 1126 | 1127 | ### Examples: 1128 | var vec = new Victor(10, 20); 1129 | 1130 | vec.toObject(); 1131 | // => { x: 10, y: 20 } 1132 | 1133 | ### Return: 1134 | 1135 | * **Object** 1136 | 1137 | 1138 | 1139 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | exports = module.exports = Victor; 2 | 3 | /** 4 | * # Victor - A JavaScript 2D vector class with methods for common vector operations 5 | */ 6 | 7 | /** 8 | * Constructor. Will also work without the `new` keyword 9 | * 10 | * ### Examples: 11 | * var vec1 = new Victor(100, 50); 12 | * var vec2 = Victor(42, 1337); 13 | * 14 | * @param {Number} x Value of the x axis 15 | * @param {Number} y Value of the y axis 16 | * @return {Victor} 17 | * @api public 18 | */ 19 | function Victor (x, y) { 20 | if (!(this instanceof Victor)) { 21 | return new Victor(x, y); 22 | } 23 | 24 | /** 25 | * The X axis 26 | * 27 | * ### Examples: 28 | * var vec = new Victor.fromArray(42, 21); 29 | * 30 | * vec.x; 31 | * // => 42 32 | * 33 | * @api public 34 | */ 35 | this.x = x || 0; 36 | 37 | /** 38 | * The Y axis 39 | * 40 | * ### Examples: 41 | * var vec = new Victor.fromArray(42, 21); 42 | * 43 | * vec.y; 44 | * // => 21 45 | * 46 | * @api public 47 | */ 48 | this.y = y || 0; 49 | }; 50 | 51 | /** 52 | * # Static 53 | */ 54 | 55 | /** 56 | * Creates a new instance from an array 57 | * 58 | * ### Examples: 59 | * var vec = Victor.fromArray([42, 21]); 60 | * 61 | * vec.toString(); 62 | * // => x:42, y:21 63 | * 64 | * @name Victor.fromArray 65 | * @param {Array} array Array with the x and y values at index 0 and 1 respectively 66 | * @return {Victor} The new instance 67 | * @api public 68 | */ 69 | Victor.fromArray = function (arr) { 70 | return new Victor(arr[0] || 0, arr[1] || 0); 71 | }; 72 | 73 | /** 74 | * Creates a new instance from an object 75 | * 76 | * ### Examples: 77 | * var vec = Victor.fromObject({ x: 42, y: 21 }); 78 | * 79 | * vec.toString(); 80 | * // => x:42, y:21 81 | * 82 | * @name Victor.fromObject 83 | * @param {Object} obj Object with the values for x and y 84 | * @return {Victor} The new instance 85 | * @api public 86 | */ 87 | Victor.fromObject = function (obj) { 88 | return new Victor(obj.x || 0, obj.y || 0); 89 | }; 90 | 91 | /** 92 | * # Manipulation 93 | * 94 | * These functions are chainable. 95 | */ 96 | 97 | /** 98 | * Adds another vector's X axis to this one 99 | * 100 | * ### Examples: 101 | * var vec1 = new Victor(10, 10); 102 | * var vec2 = new Victor(20, 30); 103 | * 104 | * vec1.addX(vec2); 105 | * vec1.toString(); 106 | * // => x:30, y:10 107 | * 108 | * @param {Victor} vector The other vector you want to add to this one 109 | * @return {Victor} `this` for chaining capabilities 110 | * @api public 111 | */ 112 | Victor.prototype.addX = function (vec) { 113 | this.x += vec.x; 114 | return this; 115 | }; 116 | 117 | /** 118 | * Adds another vector's Y axis to this one 119 | * 120 | * ### Examples: 121 | * var vec1 = new Victor(10, 10); 122 | * var vec2 = new Victor(20, 30); 123 | * 124 | * vec1.addY(vec2); 125 | * vec1.toString(); 126 | * // => x:10, y:40 127 | * 128 | * @param {Victor} vector The other vector you want to add to this one 129 | * @return {Victor} `this` for chaining capabilities 130 | * @api public 131 | */ 132 | Victor.prototype.addY = function (vec) { 133 | this.y += vec.y; 134 | return this; 135 | }; 136 | 137 | /** 138 | * Adds another vector to this one 139 | * 140 | * ### Examples: 141 | * var vec1 = new Victor(10, 10); 142 | * var vec2 = new Victor(20, 30); 143 | * 144 | * vec1.add(vec2); 145 | * vec1.toString(); 146 | * // => x:30, y:40 147 | * 148 | * @param {Victor} vector The other vector you want to add to this one 149 | * @return {Victor} `this` for chaining capabilities 150 | * @api public 151 | */ 152 | Victor.prototype.add = function (vec) { 153 | this.x += vec.x; 154 | this.y += vec.y; 155 | return this; 156 | }; 157 | 158 | /** 159 | * Adds the given scalar to both vector axis 160 | * 161 | * ### Examples: 162 | * var vec = new Victor(1, 2); 163 | * 164 | * vec.addScalar(2); 165 | * vec.toString(); 166 | * // => x: 3, y: 4 167 | * 168 | * @param {Number} scalar The scalar to add 169 | * @return {Victor} `this` for chaining capabilities 170 | * @api public 171 | */ 172 | Victor.prototype.addScalar = function (scalar) { 173 | this.x += scalar; 174 | this.y += scalar; 175 | return this; 176 | }; 177 | 178 | /** 179 | * Adds the given scalar to the X axis 180 | * 181 | * ### Examples: 182 | * var vec = new Victor(1, 2); 183 | * 184 | * vec.addScalarX(2); 185 | * vec.toString(); 186 | * // => x: 3, y: 2 187 | * 188 | * @param {Number} scalar The scalar to add 189 | * @return {Victor} `this` for chaining capabilities 190 | * @api public 191 | */ 192 | Victor.prototype.addScalarX = function (scalar) { 193 | this.x += scalar; 194 | return this; 195 | }; 196 | 197 | /** 198 | * Adds the given scalar to the Y axis 199 | * 200 | * ### Examples: 201 | * var vec = new Victor(1, 2); 202 | * 203 | * vec.addScalarY(2); 204 | * vec.toString(); 205 | * // => x: 1, y: 4 206 | * 207 | * @param {Number} scalar The scalar to add 208 | * @return {Victor} `this` for chaining capabilities 209 | * @api public 210 | */ 211 | Victor.prototype.addScalarY = function (scalar) { 212 | this.y += scalar; 213 | return this; 214 | }; 215 | 216 | /** 217 | * Subtracts the X axis of another vector from this one 218 | * 219 | * ### Examples: 220 | * var vec1 = new Victor(100, 50); 221 | * var vec2 = new Victor(20, 30); 222 | * 223 | * vec1.subtractX(vec2); 224 | * vec1.toString(); 225 | * // => x:80, y:50 226 | * 227 | * @param {Victor} vector The other vector you want subtract from this one 228 | * @return {Victor} `this` for chaining capabilities 229 | * @api public 230 | */ 231 | Victor.prototype.subtractX = function (vec) { 232 | this.x -= vec.x; 233 | return this; 234 | }; 235 | 236 | /** 237 | * Subtracts the Y axis of another vector from this one 238 | * 239 | * ### Examples: 240 | * var vec1 = new Victor(100, 50); 241 | * var vec2 = new Victor(20, 30); 242 | * 243 | * vec1.subtractY(vec2); 244 | * vec1.toString(); 245 | * // => x:100, y:20 246 | * 247 | * @param {Victor} vector The other vector you want subtract from this one 248 | * @return {Victor} `this` for chaining capabilities 249 | * @api public 250 | */ 251 | Victor.prototype.subtractY = function (vec) { 252 | this.y -= vec.y; 253 | return this; 254 | }; 255 | 256 | /** 257 | * Subtracts another vector from this one 258 | * 259 | * ### Examples: 260 | * var vec1 = new Victor(100, 50); 261 | * var vec2 = new Victor(20, 30); 262 | * 263 | * vec1.subtract(vec2); 264 | * vec1.toString(); 265 | * // => x:80, y:20 266 | * 267 | * @param {Victor} vector The other vector you want subtract from this one 268 | * @return {Victor} `this` for chaining capabilities 269 | * @api public 270 | */ 271 | Victor.prototype.subtract = function (vec) { 272 | this.x -= vec.x; 273 | this.y -= vec.y; 274 | return this; 275 | }; 276 | 277 | /** 278 | * Subtracts the given scalar from both axis 279 | * 280 | * ### Examples: 281 | * var vec = new Victor(100, 200); 282 | * 283 | * vec.subtractScalar(20); 284 | * vec.toString(); 285 | * // => x: 80, y: 180 286 | * 287 | * @param {Number} scalar The scalar to subtract 288 | * @return {Victor} `this` for chaining capabilities 289 | * @api public 290 | */ 291 | Victor.prototype.subtractScalar = function (scalar) { 292 | this.x -= scalar; 293 | this.y -= scalar; 294 | return this; 295 | }; 296 | 297 | /** 298 | * Subtracts the given scalar from the X axis 299 | * 300 | * ### Examples: 301 | * var vec = new Victor(100, 200); 302 | * 303 | * vec.subtractScalarX(20); 304 | * vec.toString(); 305 | * // => x: 80, y: 200 306 | * 307 | * @param {Number} scalar The scalar to subtract 308 | * @return {Victor} `this` for chaining capabilities 309 | * @api public 310 | */ 311 | Victor.prototype.subtractScalarX = function (scalar) { 312 | this.x -= scalar; 313 | return this; 314 | }; 315 | 316 | /** 317 | * Subtracts the given scalar from the Y axis 318 | * 319 | * ### Examples: 320 | * var vec = new Victor(100, 200); 321 | * 322 | * vec.subtractScalarY(20); 323 | * vec.toString(); 324 | * // => x: 100, y: 180 325 | * 326 | * @param {Number} scalar The scalar to subtract 327 | * @return {Victor} `this` for chaining capabilities 328 | * @api public 329 | */ 330 | Victor.prototype.subtractScalarY = function (scalar) { 331 | this.y -= scalar; 332 | return this; 333 | }; 334 | 335 | /** 336 | * Divides the X axis by the x component of given vector 337 | * 338 | * ### Examples: 339 | * var vec = new Victor(100, 50); 340 | * var vec2 = new Victor(2, 0); 341 | * 342 | * vec.divideX(vec2); 343 | * vec.toString(); 344 | * // => x:50, y:50 345 | * 346 | * @param {Victor} vector The other vector you want divide by 347 | * @return {Victor} `this` for chaining capabilities 348 | * @api public 349 | */ 350 | Victor.prototype.divideX = function (vector) { 351 | this.x /= vector.x; 352 | return this; 353 | }; 354 | 355 | /** 356 | * Divides the Y axis by the y component of given vector 357 | * 358 | * ### Examples: 359 | * var vec = new Victor(100, 50); 360 | * var vec2 = new Victor(0, 2); 361 | * 362 | * vec.divideY(vec2); 363 | * vec.toString(); 364 | * // => x:100, y:25 365 | * 366 | * @param {Victor} vector The other vector you want divide by 367 | * @return {Victor} `this` for chaining capabilities 368 | * @api public 369 | */ 370 | Victor.prototype.divideY = function (vector) { 371 | this.y /= vector.y; 372 | return this; 373 | }; 374 | 375 | /** 376 | * Divides both vector axis by a axis values of given vector 377 | * 378 | * ### Examples: 379 | * var vec = new Victor(100, 50); 380 | * var vec2 = new Victor(2, 2); 381 | * 382 | * vec.divide(vec2); 383 | * vec.toString(); 384 | * // => x:50, y:25 385 | * 386 | * @param {Victor} vector The vector to divide by 387 | * @return {Victor} `this` for chaining capabilities 388 | * @api public 389 | */ 390 | Victor.prototype.divide = function (vector) { 391 | this.x /= vector.x; 392 | this.y /= vector.y; 393 | return this; 394 | }; 395 | 396 | /** 397 | * Divides both vector axis by the given scalar value 398 | * 399 | * ### Examples: 400 | * var vec = new Victor(100, 50); 401 | * 402 | * vec.divideScalar(2); 403 | * vec.toString(); 404 | * // => x:50, y:25 405 | * 406 | * @param {Number} The scalar to divide by 407 | * @return {Victor} `this` for chaining capabilities 408 | * @api public 409 | */ 410 | Victor.prototype.divideScalar = function (scalar) { 411 | if (scalar !== 0) { 412 | this.x /= scalar; 413 | this.y /= scalar; 414 | } else { 415 | this.x = 0; 416 | this.y = 0; 417 | } 418 | 419 | return this; 420 | }; 421 | 422 | /** 423 | * Divides the X axis by the given scalar value 424 | * 425 | * ### Examples: 426 | * var vec = new Victor(100, 50); 427 | * 428 | * vec.divideScalarX(2); 429 | * vec.toString(); 430 | * // => x:50, y:50 431 | * 432 | * @param {Number} The scalar to divide by 433 | * @return {Victor} `this` for chaining capabilities 434 | * @api public 435 | */ 436 | Victor.prototype.divideScalarX = function (scalar) { 437 | if (scalar !== 0) { 438 | this.x /= scalar; 439 | } else { 440 | this.x = 0; 441 | } 442 | return this; 443 | }; 444 | 445 | /** 446 | * Divides the Y axis by the given scalar value 447 | * 448 | * ### Examples: 449 | * var vec = new Victor(100, 50); 450 | * 451 | * vec.divideScalarY(2); 452 | * vec.toString(); 453 | * // => x:100, y:25 454 | * 455 | * @param {Number} The scalar to divide by 456 | * @return {Victor} `this` for chaining capabilities 457 | * @api public 458 | */ 459 | Victor.prototype.divideScalarY = function (scalar) { 460 | if (scalar !== 0) { 461 | this.y /= scalar; 462 | } else { 463 | this.y = 0; 464 | } 465 | return this; 466 | }; 467 | 468 | /** 469 | * Inverts the X axis 470 | * 471 | * ### Examples: 472 | * var vec = new Victor(100, 50); 473 | * 474 | * vec.invertX(); 475 | * vec.toString(); 476 | * // => x:-100, y:50 477 | * 478 | * @return {Victor} `this` for chaining capabilities 479 | * @api public 480 | */ 481 | Victor.prototype.invertX = function () { 482 | this.x *= -1; 483 | return this; 484 | }; 485 | 486 | /** 487 | * Inverts the Y axis 488 | * 489 | * ### Examples: 490 | * var vec = new Victor(100, 50); 491 | * 492 | * vec.invertY(); 493 | * vec.toString(); 494 | * // => x:100, y:-50 495 | * 496 | * @return {Victor} `this` for chaining capabilities 497 | * @api public 498 | */ 499 | Victor.prototype.invertY = function () { 500 | this.y *= -1; 501 | return this; 502 | }; 503 | 504 | /** 505 | * Inverts both axis 506 | * 507 | * ### Examples: 508 | * var vec = new Victor(100, 50); 509 | * 510 | * vec.invert(); 511 | * vec.toString(); 512 | * // => x:-100, y:-50 513 | * 514 | * @return {Victor} `this` for chaining capabilities 515 | * @api public 516 | */ 517 | Victor.prototype.invert = function () { 518 | this.invertX(); 519 | this.invertY(); 520 | return this; 521 | }; 522 | 523 | /** 524 | * Multiplies the X axis by X component of given vector 525 | * 526 | * ### Examples: 527 | * var vec = new Victor(100, 50); 528 | * var vec2 = new Victor(2, 0); 529 | * 530 | * vec.multiplyX(vec2); 531 | * vec.toString(); 532 | * // => x:200, y:50 533 | * 534 | * @param {Victor} vector The vector to multiply the axis with 535 | * @return {Victor} `this` for chaining capabilities 536 | * @api public 537 | */ 538 | Victor.prototype.multiplyX = function (vector) { 539 | this.x *= vector.x; 540 | return this; 541 | }; 542 | 543 | /** 544 | * Multiplies the Y axis by Y component of given vector 545 | * 546 | * ### Examples: 547 | * var vec = new Victor(100, 50); 548 | * var vec2 = new Victor(0, 2); 549 | * 550 | * vec.multiplyX(vec2); 551 | * vec.toString(); 552 | * // => x:100, y:100 553 | * 554 | * @param {Victor} vector The vector to multiply the axis with 555 | * @return {Victor} `this` for chaining capabilities 556 | * @api public 557 | */ 558 | Victor.prototype.multiplyY = function (vector) { 559 | this.y *= vector.y; 560 | return this; 561 | }; 562 | 563 | /** 564 | * Multiplies both vector axis by values from a given vector 565 | * 566 | * ### Examples: 567 | * var vec = new Victor(100, 50); 568 | * var vec2 = new Victor(2, 2); 569 | * 570 | * vec.multiply(vec2); 571 | * vec.toString(); 572 | * // => x:200, y:100 573 | * 574 | * @param {Victor} vector The vector to multiply by 575 | * @return {Victor} `this` for chaining capabilities 576 | * @api public 577 | */ 578 | Victor.prototype.multiply = function (vector) { 579 | this.x *= vector.x; 580 | this.y *= vector.y; 581 | return this; 582 | }; 583 | 584 | /** 585 | * Multiplies both vector axis by the given scalar value 586 | * 587 | * ### Examples: 588 | * var vec = new Victor(100, 50); 589 | * 590 | * vec.multiplyScalar(2); 591 | * vec.toString(); 592 | * // => x:200, y:100 593 | * 594 | * @param {Number} The scalar to multiply by 595 | * @return {Victor} `this` for chaining capabilities 596 | * @api public 597 | */ 598 | Victor.prototype.multiplyScalar = function (scalar) { 599 | this.x *= scalar; 600 | this.y *= scalar; 601 | return this; 602 | }; 603 | 604 | /** 605 | * Multiplies the X axis by the given scalar 606 | * 607 | * ### Examples: 608 | * var vec = new Victor(100, 50); 609 | * 610 | * vec.multiplyScalarX(2); 611 | * vec.toString(); 612 | * // => x:200, y:50 613 | * 614 | * @param {Number} The scalar to multiply the axis with 615 | * @return {Victor} `this` for chaining capabilities 616 | * @api public 617 | */ 618 | Victor.prototype.multiplyScalarX = function (scalar) { 619 | this.x *= scalar; 620 | return this; 621 | }; 622 | 623 | /** 624 | * Multiplies the Y axis by the given scalar 625 | * 626 | * ### Examples: 627 | * var vec = new Victor(100, 50); 628 | * 629 | * vec.multiplyScalarY(2); 630 | * vec.toString(); 631 | * // => x:100, y:100 632 | * 633 | * @param {Number} The scalar to multiply the axis with 634 | * @return {Victor} `this` for chaining capabilities 635 | * @api public 636 | */ 637 | Victor.prototype.multiplyScalarY = function (scalar) { 638 | this.y *= scalar; 639 | return this; 640 | }; 641 | 642 | /** 643 | * Normalize 644 | * 645 | * @return {Victor} `this` for chaining capabilities 646 | * @api public 647 | */ 648 | Victor.prototype.normalize = function () { 649 | var length = this.length(); 650 | 651 | if (length === 0) { 652 | this.x = 1; 653 | this.y = 0; 654 | } else { 655 | this.divide(Victor(length, length)); 656 | } 657 | return this; 658 | }; 659 | 660 | Victor.prototype.norm = Victor.prototype.normalize; 661 | 662 | /** 663 | * If the absolute vector axis is greater than `max`, multiplies the axis by `factor` 664 | * 665 | * ### Examples: 666 | * var vec = new Victor(100, 50); 667 | * 668 | * vec.limit(80, 0.9); 669 | * vec.toString(); 670 | * // => x:90, y:50 671 | * 672 | * @param {Number} max The maximum value for both x and y axis 673 | * @param {Number} factor Factor by which the axis are to be multiplied with 674 | * @return {Victor} `this` for chaining capabilities 675 | * @api public 676 | */ 677 | Victor.prototype.limit = function (max, factor) { 678 | if (Math.abs(this.x) > max){ this.x *= factor; } 679 | if (Math.abs(this.y) > max){ this.y *= factor; } 680 | return this; 681 | }; 682 | 683 | /** 684 | * Randomizes both vector axis with a value between 2 vectors 685 | * 686 | * ### Examples: 687 | * var vec = new Victor(100, 50); 688 | * 689 | * vec.randomize(new Victor(50, 60), new Victor(70, 80`)); 690 | * vec.toString(); 691 | * // => x:67, y:73 692 | * 693 | * @param {Victor} topLeft first vector 694 | * @param {Victor} bottomRight second vector 695 | * @return {Victor} `this` for chaining capabilities 696 | * @api public 697 | */ 698 | Victor.prototype.randomize = function (topLeft, bottomRight) { 699 | this.randomizeX(topLeft, bottomRight); 700 | this.randomizeY(topLeft, bottomRight); 701 | 702 | return this; 703 | }; 704 | 705 | /** 706 | * Randomizes the y axis with a value between 2 vectors 707 | * 708 | * ### Examples: 709 | * var vec = new Victor(100, 50); 710 | * 711 | * vec.randomizeX(new Victor(50, 60), new Victor(70, 80`)); 712 | * vec.toString(); 713 | * // => x:55, y:50 714 | * 715 | * @param {Victor} topLeft first vector 716 | * @param {Victor} bottomRight second vector 717 | * @return {Victor} `this` for chaining capabilities 718 | * @api public 719 | */ 720 | Victor.prototype.randomizeX = function (topLeft, bottomRight) { 721 | var min = Math.min(topLeft.x, bottomRight.x); 722 | var max = Math.max(topLeft.x, bottomRight.x); 723 | this.x = random(min, max); 724 | return this; 725 | }; 726 | 727 | /** 728 | * Randomizes the y axis with a value between 2 vectors 729 | * 730 | * ### Examples: 731 | * var vec = new Victor(100, 50); 732 | * 733 | * vec.randomizeY(new Victor(50, 60), new Victor(70, 80`)); 734 | * vec.toString(); 735 | * // => x:100, y:66 736 | * 737 | * @param {Victor} topLeft first vector 738 | * @param {Victor} bottomRight second vector 739 | * @return {Victor} `this` for chaining capabilities 740 | * @api public 741 | */ 742 | Victor.prototype.randomizeY = function (topLeft, bottomRight) { 743 | var min = Math.min(topLeft.y, bottomRight.y); 744 | var max = Math.max(topLeft.y, bottomRight.y); 745 | this.y = random(min, max); 746 | return this; 747 | }; 748 | 749 | /** 750 | * Randomly randomizes either axis between 2 vectors 751 | * 752 | * ### Examples: 753 | * var vec = new Victor(100, 50); 754 | * 755 | * vec.randomizeAny(new Victor(50, 60), new Victor(70, 80)); 756 | * vec.toString(); 757 | * // => x:100, y:77 758 | * 759 | * @param {Victor} topLeft first vector 760 | * @param {Victor} bottomRight second vector 761 | * @return {Victor} `this` for chaining capabilities 762 | * @api public 763 | */ 764 | Victor.prototype.randomizeAny = function (topLeft, bottomRight) { 765 | if (!! Math.round(Math.random())) { 766 | this.randomizeX(topLeft, bottomRight); 767 | } else { 768 | this.randomizeY(topLeft, bottomRight); 769 | } 770 | return this; 771 | }; 772 | 773 | /** 774 | * Rounds both axis to an integer value 775 | * 776 | * ### Examples: 777 | * var vec = new Victor(100.2, 50.9); 778 | * 779 | * vec.unfloat(); 780 | * vec.toString(); 781 | * // => x:100, y:51 782 | * 783 | * @return {Victor} `this` for chaining capabilities 784 | * @api public 785 | */ 786 | Victor.prototype.unfloat = function () { 787 | this.x = Math.round(this.x); 788 | this.y = Math.round(this.y); 789 | return this; 790 | }; 791 | 792 | /** 793 | * Rounds both axis to a certain precision 794 | * 795 | * ### Examples: 796 | * var vec = new Victor(100.2, 50.9); 797 | * 798 | * vec.unfloat(); 799 | * vec.toString(); 800 | * // => x:100, y:51 801 | * 802 | * @param {Number} Precision (default: 8) 803 | * @return {Victor} `this` for chaining capabilities 804 | * @api public 805 | */ 806 | Victor.prototype.toFixed = function (precision) { 807 | if (typeof precision === 'undefined') { precision = 8; } 808 | this.x = this.x.toFixed(precision); 809 | this.y = this.y.toFixed(precision); 810 | return this; 811 | }; 812 | 813 | /** 814 | * Performs a linear blend / interpolation of the X axis towards another vector 815 | * 816 | * ### Examples: 817 | * var vec1 = new Victor(100, 100); 818 | * var vec2 = new Victor(200, 200); 819 | * 820 | * vec1.mixX(vec2, 0.5); 821 | * vec.toString(); 822 | * // => x:150, y:100 823 | * 824 | * @param {Victor} vector The other vector 825 | * @param {Number} amount The blend amount (optional, default: 0.5) 826 | * @return {Victor} `this` for chaining capabilities 827 | * @api public 828 | */ 829 | Victor.prototype.mixX = function (vec, amount) { 830 | if (typeof amount === 'undefined') { 831 | amount = 0.5; 832 | } 833 | 834 | this.x = (1 - amount) * this.x + amount * vec.x; 835 | return this; 836 | }; 837 | 838 | /** 839 | * Performs a linear blend / interpolation of the Y axis towards another vector 840 | * 841 | * ### Examples: 842 | * var vec1 = new Victor(100, 100); 843 | * var vec2 = new Victor(200, 200); 844 | * 845 | * vec1.mixY(vec2, 0.5); 846 | * vec.toString(); 847 | * // => x:100, y:150 848 | * 849 | * @param {Victor} vector The other vector 850 | * @param {Number} amount The blend amount (optional, default: 0.5) 851 | * @return {Victor} `this` for chaining capabilities 852 | * @api public 853 | */ 854 | Victor.prototype.mixY = function (vec, amount) { 855 | if (typeof amount === 'undefined') { 856 | amount = 0.5; 857 | } 858 | 859 | this.y = (1 - amount) * this.y + amount * vec.y; 860 | return this; 861 | }; 862 | 863 | /** 864 | * Performs a linear blend / interpolation towards another vector 865 | * 866 | * ### Examples: 867 | * var vec1 = new Victor(100, 100); 868 | * var vec2 = new Victor(200, 200); 869 | * 870 | * vec1.mix(vec2, 0.5); 871 | * vec.toString(); 872 | * // => x:150, y:150 873 | * 874 | * @param {Victor} vector The other vector 875 | * @param {Number} amount The blend amount (optional, default: 0.5) 876 | * @return {Victor} `this` for chaining capabilities 877 | * @api public 878 | */ 879 | Victor.prototype.mix = function (vec, amount) { 880 | this.mixX(vec, amount); 881 | this.mixY(vec, amount); 882 | return this; 883 | }; 884 | 885 | /** 886 | * # Products 887 | */ 888 | 889 | /** 890 | * Creates a clone of this vector 891 | * 892 | * ### Examples: 893 | * var vec1 = new Victor(10, 10); 894 | * var vec2 = vec1.clone(); 895 | * 896 | * vec2.toString(); 897 | * // => x:10, y:10 898 | * 899 | * @return {Victor} A clone of the vector 900 | * @api public 901 | */ 902 | Victor.prototype.clone = function () { 903 | return new Victor(this.x, this.y); 904 | }; 905 | 906 | /** 907 | * Copies another vector's X component in to its own 908 | * 909 | * ### Examples: 910 | * var vec1 = new Victor(10, 10); 911 | * var vec2 = new Victor(20, 20); 912 | * var vec2 = vec1.copyX(vec1); 913 | * 914 | * vec2.toString(); 915 | * // => x:20, y:10 916 | * 917 | * @return {Victor} `this` for chaining capabilities 918 | * @api public 919 | */ 920 | Victor.prototype.copyX = function (vec) { 921 | this.x = vec.x; 922 | return this; 923 | }; 924 | 925 | /** 926 | * Copies another vector's Y component in to its own 927 | * 928 | * ### Examples: 929 | * var vec1 = new Victor(10, 10); 930 | * var vec2 = new Victor(20, 20); 931 | * var vec2 = vec1.copyY(vec1); 932 | * 933 | * vec2.toString(); 934 | * // => x:10, y:20 935 | * 936 | * @return {Victor} `this` for chaining capabilities 937 | * @api public 938 | */ 939 | Victor.prototype.copyY = function (vec) { 940 | this.y = vec.y; 941 | return this; 942 | }; 943 | 944 | /** 945 | * Copies another vector's X and Y components in to its own 946 | * 947 | * ### Examples: 948 | * var vec1 = new Victor(10, 10); 949 | * var vec2 = new Victor(20, 20); 950 | * var vec2 = vec1.copy(vec1); 951 | * 952 | * vec2.toString(); 953 | * // => x:20, y:20 954 | * 955 | * @return {Victor} `this` for chaining capabilities 956 | * @api public 957 | */ 958 | Victor.prototype.copy = function (vec) { 959 | this.copyX(vec); 960 | this.copyY(vec); 961 | return this; 962 | }; 963 | 964 | /** 965 | * Sets the vector to zero (0,0) 966 | * 967 | * ### Examples: 968 | * var vec1 = new Victor(10, 10); 969 | * var1.zero(); 970 | * vec1.toString(); 971 | * // => x:0, y:0 972 | * 973 | * @return {Victor} `this` for chaining capabilities 974 | * @api public 975 | */ 976 | Victor.prototype.zero = function () { 977 | this.x = this.y = 0; 978 | return this; 979 | }; 980 | 981 | /** 982 | * Calculates the dot product of this vector and another 983 | * 984 | * ### Examples: 985 | * var vec1 = new Victor(100, 50); 986 | * var vec2 = new Victor(200, 60); 987 | * 988 | * vec1.dot(vec2); 989 | * // => 23000 990 | * 991 | * @param {Victor} vector The second vector 992 | * @return {Number} Dot product 993 | * @api public 994 | */ 995 | Victor.prototype.dot = function (vec2) { 996 | return this.x * vec2.x + this.y * vec2.y; 997 | }; 998 | 999 | Victor.prototype.cross = function (vec2) { 1000 | return (this.x * vec2.y ) - (this.y * vec2.x ); 1001 | }; 1002 | 1003 | /** 1004 | * Projects a vector onto another vector, setting itself to the result. 1005 | * 1006 | * ### Examples: 1007 | * var vec = new Victor(100, 0); 1008 | * var vec2 = new Victor(100, 100); 1009 | * 1010 | * vec.projectOnto(vec2); 1011 | * vec.toString(); 1012 | * // => x:50, y:50 1013 | * 1014 | * @param {Victor} vector The other vector you want to project this vector onto 1015 | * @return {Victor} `this` for chaining capabilities 1016 | * @api public 1017 | */ 1018 | Victor.prototype.projectOnto = function (vec2) { 1019 | var coeff = ( (this.x * vec2.x)+(this.y * vec2.y) ) / ((vec2.x*vec2.x)+(vec2.y*vec2.y)); 1020 | this.x = coeff * vec2.x; 1021 | this.y = coeff * vec2.y; 1022 | return this; 1023 | }; 1024 | 1025 | 1026 | Victor.prototype.horizontalAngle = function () { 1027 | return Math.atan2(this.y, this.x); 1028 | }; 1029 | 1030 | Victor.prototype.horizontalAngleDeg = function () { 1031 | return radian2degrees(this.horizontalAngle()); 1032 | }; 1033 | 1034 | Victor.prototype.verticalAngle = function () { 1035 | return Math.atan2(this.x, this.y); 1036 | }; 1037 | 1038 | Victor.prototype.verticalAngleDeg = function () { 1039 | return radian2degrees(this.verticalAngle()); 1040 | }; 1041 | 1042 | Victor.prototype.angle = Victor.prototype.horizontalAngle; 1043 | Victor.prototype.angleDeg = Victor.prototype.horizontalAngleDeg; 1044 | Victor.prototype.direction = Victor.prototype.horizontalAngle; 1045 | 1046 | Victor.prototype.rotate = function (angle) { 1047 | var nx = (this.x * Math.cos(angle)) - (this.y * Math.sin(angle)); 1048 | var ny = (this.x * Math.sin(angle)) + (this.y * Math.cos(angle)); 1049 | 1050 | this.x = nx; 1051 | this.y = ny; 1052 | 1053 | return this; 1054 | }; 1055 | 1056 | Victor.prototype.rotateDeg = function (angle) { 1057 | angle = degrees2radian(angle); 1058 | return this.rotate(angle); 1059 | }; 1060 | 1061 | Victor.prototype.rotateTo = function(rotation) { 1062 | return this.rotate(rotation-this.angle()); 1063 | }; 1064 | 1065 | Victor.prototype.rotateToDeg = function(rotation) { 1066 | rotation = degrees2radian(rotation); 1067 | return this.rotateTo(rotation); 1068 | }; 1069 | 1070 | Victor.prototype.rotateBy = function (rotation) { 1071 | var angle = this.angle() + rotation; 1072 | 1073 | return this.rotate(angle); 1074 | }; 1075 | 1076 | Victor.prototype.rotateByDeg = function (rotation) { 1077 | rotation = degrees2radian(rotation); 1078 | return this.rotateBy(rotation); 1079 | }; 1080 | 1081 | /** 1082 | * Calculates the distance of the X axis between this vector and another 1083 | * 1084 | * ### Examples: 1085 | * var vec1 = new Victor(100, 50); 1086 | * var vec2 = new Victor(200, 60); 1087 | * 1088 | * vec1.distanceX(vec2); 1089 | * // => -100 1090 | * 1091 | * @param {Victor} vector The second vector 1092 | * @return {Number} Distance 1093 | * @api public 1094 | */ 1095 | Victor.prototype.distanceX = function (vec) { 1096 | return this.x - vec.x; 1097 | }; 1098 | 1099 | /** 1100 | * Same as `distanceX()` but always returns an absolute number 1101 | * 1102 | * ### Examples: 1103 | * var vec1 = new Victor(100, 50); 1104 | * var vec2 = new Victor(200, 60); 1105 | * 1106 | * vec1.absDistanceX(vec2); 1107 | * // => 100 1108 | * 1109 | * @param {Victor} vector The second vector 1110 | * @return {Number} Absolute distance 1111 | * @api public 1112 | */ 1113 | Victor.prototype.absDistanceX = function (vec) { 1114 | return Math.abs(this.distanceX(vec)); 1115 | }; 1116 | 1117 | /** 1118 | * Calculates the distance of the Y axis between this vector and another 1119 | * 1120 | * ### Examples: 1121 | * var vec1 = new Victor(100, 50); 1122 | * var vec2 = new Victor(200, 60); 1123 | * 1124 | * vec1.distanceY(vec2); 1125 | * // => -10 1126 | * 1127 | * @param {Victor} vector The second vector 1128 | * @return {Number} Distance 1129 | * @api public 1130 | */ 1131 | Victor.prototype.distanceY = function (vec) { 1132 | return this.y - vec.y; 1133 | }; 1134 | 1135 | /** 1136 | * Same as `distanceY()` but always returns an absolute number 1137 | * 1138 | * ### Examples: 1139 | * var vec1 = new Victor(100, 50); 1140 | * var vec2 = new Victor(200, 60); 1141 | * 1142 | * vec1.distanceY(vec2); 1143 | * // => 10 1144 | * 1145 | * @param {Victor} vector The second vector 1146 | * @return {Number} Absolute distance 1147 | * @api public 1148 | */ 1149 | Victor.prototype.absDistanceY = function (vec) { 1150 | return Math.abs(this.distanceY(vec)); 1151 | }; 1152 | 1153 | /** 1154 | * Calculates the euclidean distance between this vector and another 1155 | * 1156 | * ### Examples: 1157 | * var vec1 = new Victor(100, 50); 1158 | * var vec2 = new Victor(200, 60); 1159 | * 1160 | * vec1.distance(vec2); 1161 | * // => 100.4987562112089 1162 | * 1163 | * @param {Victor} vector The second vector 1164 | * @return {Number} Distance 1165 | * @api public 1166 | */ 1167 | Victor.prototype.distance = function (vec) { 1168 | return Math.sqrt(this.distanceSq(vec)); 1169 | }; 1170 | 1171 | /** 1172 | * Calculates the squared euclidean distance between this vector and another 1173 | * 1174 | * ### Examples: 1175 | * var vec1 = new Victor(100, 50); 1176 | * var vec2 = new Victor(200, 60); 1177 | * 1178 | * vec1.distanceSq(vec2); 1179 | * // => 10100 1180 | * 1181 | * @param {Victor} vector The second vector 1182 | * @return {Number} Distance 1183 | * @api public 1184 | */ 1185 | Victor.prototype.distanceSq = function (vec) { 1186 | var dx = this.distanceX(vec), 1187 | dy = this.distanceY(vec); 1188 | 1189 | return dx * dx + dy * dy; 1190 | }; 1191 | 1192 | /** 1193 | * Calculates the length or magnitude of the vector 1194 | * 1195 | * ### Examples: 1196 | * var vec = new Victor(100, 50); 1197 | * 1198 | * vec.length(); 1199 | * // => 111.80339887498948 1200 | * 1201 | * @return {Number} Length / Magnitude 1202 | * @api public 1203 | */ 1204 | Victor.prototype.length = function () { 1205 | return Math.sqrt(this.lengthSq()); 1206 | }; 1207 | 1208 | /** 1209 | * Squared length / magnitude 1210 | * 1211 | * ### Examples: 1212 | * var vec = new Victor(100, 50); 1213 | * 1214 | * vec.lengthSq(); 1215 | * // => 12500 1216 | * 1217 | * @return {Number} Length / Magnitude 1218 | * @api public 1219 | */ 1220 | Victor.prototype.lengthSq = function () { 1221 | return this.x * this.x + this.y * this.y; 1222 | }; 1223 | 1224 | Victor.prototype.magnitude = Victor.prototype.length; 1225 | 1226 | /** 1227 | * Returns a true if vector is (0, 0) 1228 | * 1229 | * ### Examples: 1230 | * var vec = new Victor(100, 50); 1231 | * vec.zero(); 1232 | * 1233 | * // => true 1234 | * 1235 | * @return {Boolean} 1236 | * @api public 1237 | */ 1238 | Victor.prototype.isZero = function() { 1239 | return this.x === 0 && this.y === 0; 1240 | }; 1241 | 1242 | /** 1243 | * Returns a true if this vector is the same as another 1244 | * 1245 | * ### Examples: 1246 | * var vec1 = new Victor(100, 50); 1247 | * var vec2 = new Victor(100, 50); 1248 | * vec1.isEqualTo(vec2); 1249 | * 1250 | * // => true 1251 | * 1252 | * @return {Boolean} 1253 | * @api public 1254 | */ 1255 | Victor.prototype.isEqualTo = function(vec2) { 1256 | return this.x === vec2.x && this.y === vec2.y; 1257 | }; 1258 | 1259 | /** 1260 | * # Utility Methods 1261 | */ 1262 | 1263 | /** 1264 | * Returns an string representation of the vector 1265 | * 1266 | * ### Examples: 1267 | * var vec = new Victor(10, 20); 1268 | * 1269 | * vec.toString(); 1270 | * // => x:10, y:20 1271 | * 1272 | * @return {String} 1273 | * @api public 1274 | */ 1275 | Victor.prototype.toString = function () { 1276 | return 'x:' + this.x + ', y:' + this.y; 1277 | }; 1278 | 1279 | /** 1280 | * Returns an array representation of the vector 1281 | * 1282 | * ### Examples: 1283 | * var vec = new Victor(10, 20); 1284 | * 1285 | * vec.toArray(); 1286 | * // => [10, 20] 1287 | * 1288 | * @return {Array} 1289 | * @api public 1290 | */ 1291 | Victor.prototype.toArray = function () { 1292 | return [ this.x, this.y ]; 1293 | }; 1294 | 1295 | /** 1296 | * Returns an object representation of the vector 1297 | * 1298 | * ### Examples: 1299 | * var vec = new Victor(10, 20); 1300 | * 1301 | * vec.toObject(); 1302 | * // => { x: 10, y: 20 } 1303 | * 1304 | * @return {Object} 1305 | * @api public 1306 | */ 1307 | Victor.prototype.toObject = function () { 1308 | return { x: this.x, y: this.y }; 1309 | }; 1310 | 1311 | 1312 | var degrees = 180 / Math.PI; 1313 | 1314 | function random (min, max) { 1315 | return Math.floor(Math.random() * (max - min + 1) + min); 1316 | } 1317 | 1318 | function radian2degrees (rad) { 1319 | return rad * degrees; 1320 | } 1321 | 1322 | function degrees2radian (deg) { 1323 | return deg / degrees; 1324 | } 1325 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "victor", 3 | "version": "1.1.0", 4 | "description": "A JavaScript 2D vector class with methods for common vector operations", 5 | "keywords": [ 6 | "vector", 7 | "2d" 8 | ], 9 | "main": "index.js", 10 | "repository": { 11 | "type": "git", 12 | "url": "git://github.com/maxkueng/victor.git" 13 | }, 14 | "scripts": { 15 | "build": "(echo '/*!' ; cat ./LICENSE ; echo '*/' ; browserify index.js --standalone Victor) > build/victor.js && cat build/victor.js | uglifyjs -mc --comments '/^!/' > build/victor.min.js", 16 | "doc": "markdox index.js -o documentation/api.md", 17 | "test": "mocha --ui bdd --reporter spec" 18 | }, 19 | "homepage": "http://victorjs.org/", 20 | "author": "Max Kueng (http://maxkueng.com/)", 21 | "maintainers": [ 22 | "Max Kueng (http://maxkueng.com/)", 23 | "George Crabtree (http://georgecrabtree.com/)" 24 | ], 25 | "licenses": [ 26 | { 27 | "type": "MIT", 28 | "url": "https://github.com/maxkueng/victor/raw/master/LICENSE" 29 | } 30 | ], 31 | "devDependencies": { 32 | "browserify": "^3.33.0", 33 | "uglify-js": "^2.4.13", 34 | "chai": "~1.9.1", 35 | "mocha": "~1.18.2", 36 | "markdox": "^0.1.4" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /test.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxkueng/victor/8383f436d63f6741e5529b09a39e7fb2b7f1dbfb/test.txt -------------------------------------------------------------------------------- /test/victor.js: -------------------------------------------------------------------------------- 1 | var expect = require('chai').expect; 2 | var Victor = require('../index'); 3 | 4 | var EPSILON = 0.0001; 5 | 6 | describe('static methods', function () { 7 | 8 | describe('new Victor', function () { 9 | var x, y, vec1, vec2; 10 | 11 | before(function () { 12 | x = 100; 13 | y = 200; 14 | vec1 = new Victor(x, y); 15 | vec2 = Victor(x, y); 16 | }); 17 | 18 | it('should be an instance of Victor', function () { 19 | expect(vec1).to.be.an.instanceof(Victor); 20 | expect(vec2).to.be.an.instanceof(Victor); 21 | }); 22 | 23 | it('should have axis from arguments', function () { 24 | expect(vec1).to.have.property('x', x); 25 | expect(vec1).to.have.property('y', y); 26 | 27 | expect(vec2).to.have.property('x', x); 28 | expect(vec2).to.have.property('y', y); 29 | }); 30 | }); 31 | 32 | describe('#fromArray()', function () { 33 | var arr, vec; 34 | 35 | before(function () { 36 | arr = [100, 200]; 37 | vec = Victor.fromArray(arr); 38 | }); 39 | 40 | it('should return an instance of Victor', function () { 41 | expect(vec).to.be.an.instanceof(Victor); 42 | }); 43 | 44 | it('should have axis from array', function () { 45 | expect(vec).to.have.property('x', arr[0]); 46 | expect(vec).to.have.property('y', arr[1]); 47 | }); 48 | }); 49 | 50 | describe('#fromObject()', function () { 51 | var obj, vec; 52 | 53 | before(function () { 54 | obj = { x: 100, y: 200 }; 55 | vec = Victor.fromObject(obj); 56 | }); 57 | 58 | it('should return an instance of Victor', function () { 59 | expect(vec).to.be.an.instanceof(Victor); 60 | }); 61 | 62 | it('should have axis from object', function () { 63 | expect(vec).to.have.property('x', obj.x); 64 | expect(vec).to.have.property('y', obj.y); 65 | }); 66 | }); 67 | 68 | }); 69 | 70 | describe('chainable instance methods', function () { 71 | 72 | describe('#addX()', function () { 73 | var vec1, vec2, ret; 74 | 75 | before(function () { 76 | vec1 = new Victor(20, 40); 77 | vec2 = new Victor(30, 20); 78 | ret = vec1.addX(vec2); 79 | }); 80 | 81 | it('should be chainable', function () { 82 | expect(ret).to.equal(vec1); 83 | }); 84 | 85 | it('should add only the X axis of a vector', function () { 86 | expect(vec1).to.have.property('x', 50); 87 | expect(vec1).to.have.property('y', 40); 88 | }); 89 | }); 90 | 91 | describe('#addY()', function () { 92 | var vec1, vec2, ret; 93 | 94 | before(function () { 95 | vec1 = new Victor(20, 40); 96 | vec2 = new Victor(30, 20); 97 | ret = vec1.addY(vec2); 98 | }); 99 | 100 | it('should be chainable', function () { 101 | expect(ret).to.equal(vec1); 102 | }); 103 | 104 | it('should add only the Y axis of a vector', function () { 105 | expect(vec1).to.have.property('x', 20); 106 | expect(vec1).to.have.property('y', 60); 107 | }); 108 | }); 109 | 110 | describe('#add()', function () { 111 | var vec1, vec2, ret; 112 | 113 | before(function () { 114 | vec1 = new Victor(20, 40); 115 | vec2 = new Victor(30, 20); 116 | ret = vec1.add(vec2); 117 | }); 118 | 119 | it('should be chainable', function () { 120 | expect(ret).to.equal(vec1); 121 | }); 122 | 123 | it('should add a vector', function () { 124 | expect(vec1).to.have.property('x', 50); 125 | expect(vec1).to.have.property('y', 60); 126 | }); 127 | }); 128 | 129 | describe('#subtractX()', function () { 130 | var vec1, vec2, ret; 131 | 132 | before(function () { 133 | vec1 = new Victor(30, 20); 134 | vec2 = new Victor(20, 40); 135 | ret = vec1.subtractX(vec2); 136 | }); 137 | 138 | it('should be chainable', function () { 139 | expect(ret).to.equal(vec1); 140 | }); 141 | 142 | it('should subtract only the X axis of a vector', function () { 143 | expect(vec1).to.have.property('x', 10); 144 | expect(vec1).to.have.property('y', 20); 145 | }); 146 | }); 147 | 148 | describe('#subtractY()', function () { 149 | var vec1, vec2, ret; 150 | 151 | before(function () { 152 | vec1 = new Victor(30, 20); 153 | vec2 = new Victor(20, 40); 154 | ret = vec1.subtractY(vec2); 155 | }); 156 | 157 | it('should be chainable', function () { 158 | expect(ret).to.equal(vec1); 159 | }); 160 | 161 | it('should subtract only the Y axis of a vector', function () { 162 | expect(vec1).to.have.property('x', 30); 163 | expect(vec1).to.have.property('y', -20); 164 | }); 165 | }); 166 | 167 | describe('#subtract()', function () { 168 | var vec1, vec2, ret; 169 | 170 | before(function () { 171 | vec1 = new Victor(30, 20); 172 | vec2 = new Victor(20, 40); 173 | ret = vec1.subtract(vec2); 174 | }); 175 | 176 | it('should be chainable', function () { 177 | expect(ret).to.equal(vec1); 178 | }); 179 | 180 | it('should subtract a vector', function () { 181 | expect(vec1).to.have.property('x', 10); 182 | expect(vec1).to.have.property('y', -20); 183 | }); 184 | }); 185 | 186 | describe('#divideX()', function () { 187 | var vec, vec2, ret; 188 | 189 | before(function () { 190 | vec = new Victor(30, 20); 191 | vec2 = new Victor(2, 2); 192 | ret = vec.divideX(vec2); 193 | }); 194 | 195 | it('should be chainable', function () { 196 | expect(ret).to.equal(vec); 197 | }); 198 | 199 | it('should divide the X axis by 2', function () { 200 | expect(vec).to.have.property('x', 15); 201 | expect(vec).to.have.property('y', 20); 202 | }); 203 | }); 204 | 205 | describe('#divideY()', function () { 206 | var vec, vec2, ret; 207 | 208 | before(function () { 209 | vec = new Victor(30, 20); 210 | vec2 = new Victor(2, 2); 211 | ret = vec.divideY(vec2); 212 | }); 213 | 214 | it('should be chainable', function () { 215 | expect(ret).to.equal(vec); 216 | }); 217 | 218 | it('should divide the Y axis by 2', function () { 219 | expect(vec).to.have.property('x', 30); 220 | expect(vec).to.have.property('y', 10); 221 | }); 222 | }); 223 | 224 | describe('#divide()', function () { 225 | var vec, vec2, ret; 226 | 227 | before(function () { 228 | vec = new Victor(30, 20); 229 | vec2 = new Victor(2, 2); 230 | ret = vec.divide(vec2); 231 | }); 232 | 233 | it('should be chainable', function () { 234 | expect(ret).to.equal(vec); 235 | }); 236 | 237 | it('should divide both vector axis by 2', function () { 238 | expect(vec).to.have.property('x', 15); 239 | expect(vec).to.have.property('y', 10); 240 | }); 241 | }); 242 | 243 | describe('#divideScalar()', function () { 244 | var vec, scal, ret; 245 | 246 | before(function () { 247 | vec = new Victor(30, 20); 248 | scal = 2; 249 | ret = vec.divideScalar(scal); 250 | }); 251 | 252 | it('should be chainable', function () { 253 | expect(ret).to.equal(vec); 254 | }); 255 | 256 | it('should divide both vector axis by 2', function () { 257 | expect(vec).to.have.property('x', 15); 258 | expect(vec).to.have.property('y', 10); 259 | }); 260 | 261 | it('should return a zero vector when dividing by 0', function() { 262 | vec = new Victor(30, 20); 263 | scal = 0; 264 | ret = vec.divideScalar(scal); 265 | 266 | expect(vec).to.have.property('x', 0); 267 | expect(vec).to.have.property('y', 0); 268 | }); 269 | }); 270 | 271 | describe('#divideScalarX()', function () { 272 | var vec, scal, ret; 273 | 274 | before(function () { 275 | vec = new Victor(30, 20); 276 | scal = 2; 277 | ret = vec.divideScalarX(scal); 278 | }); 279 | 280 | it('should be chainable', function () { 281 | expect(ret).to.equal(vec); 282 | }); 283 | 284 | it('should divide the X axis by 2', function () { 285 | expect(vec).to.have.property('x', 15); 286 | expect(vec).to.have.property('y', 20); 287 | }); 288 | 289 | it('should return a zero X when dividing by 0', function() { 290 | vec = new Victor(30, 20); 291 | scal = 0; 292 | ret = vec.divideScalarX(scal); 293 | 294 | expect(vec).to.have.property('x', 0); 295 | }); 296 | }); 297 | 298 | describe('#divideScalarY()', function () { 299 | var vec, scal, ret; 300 | 301 | before(function () { 302 | vec = new Victor(30, 20); 303 | scal = 2; 304 | ret = vec.divideScalarY(scal); 305 | }); 306 | 307 | it('should be chainable', function () { 308 | expect(ret).to.equal(vec); 309 | }); 310 | 311 | it('should divide the Y axis by 2', function () { 312 | expect(vec).to.have.property('x', 30); 313 | expect(vec).to.have.property('y', 10); 314 | }); 315 | 316 | it('should return a zero Y when dividing by 0', function() { 317 | vec = new Victor(30, 20); 318 | scal = 0; 319 | ret = vec.divideScalarY(scal); 320 | 321 | expect(vec).to.have.property('y', 0); 322 | }); 323 | }); 324 | 325 | describe('#multiplyX()', function () { 326 | var vec, vec2, ret; 327 | 328 | before(function () { 329 | vec = new Victor(30, 20); 330 | vec2 = new Victor(2, 2); 331 | ret = vec.multiplyX(vec2); 332 | }); 333 | 334 | it('should be chainable', function () { 335 | expect(ret).to.equal(vec); 336 | }); 337 | 338 | it('should multiply the X axis by 2', function () { 339 | expect(vec).to.have.property('x', 60); 340 | expect(vec).to.have.property('y', 20); 341 | }); 342 | }); 343 | 344 | describe('#multiplyY()', function () { 345 | var vec, vec2, ret; 346 | 347 | before(function () { 348 | vec = new Victor(30, 20); 349 | vec2 = new Victor(2, 2); 350 | ret = vec.multiplyY(vec2); 351 | }); 352 | 353 | it('should be chainable', function () { 354 | expect(ret).to.equal(vec); 355 | }); 356 | 357 | it('should multiply the Y axis by 2', function () { 358 | expect(vec).to.have.property('x', 30); 359 | expect(vec).to.have.property('y', 40); 360 | }); 361 | }); 362 | 363 | describe('#multiply()', function () { 364 | var vec, vec2, ret; 365 | 366 | before(function () { 367 | vec = new Victor(30, 20); 368 | vec2 = new Victor(2, 2); 369 | ret = vec.multiply(vec2); 370 | }); 371 | 372 | it('should be chainable', function () { 373 | expect(ret).to.equal(vec); 374 | }); 375 | 376 | it('should multiply both vector axis by 2', function () { 377 | expect(vec).to.have.property('x', 60); 378 | expect(vec).to.have.property('y', 40); 379 | }); 380 | }); 381 | 382 | describe('#multiplyScalar()', function () { 383 | var vec, scal, ret; 384 | 385 | before(function () { 386 | vec = new Victor(30, 20); 387 | scal = 2; 388 | ret = vec.multiplyScalar(scal); 389 | }); 390 | 391 | it('should be chainable', function () { 392 | expect(ret).to.equal(vec); 393 | }); 394 | 395 | it('should multiply both vector axis by 2', function () { 396 | expect(vec).to.have.property('x', 60); 397 | expect(vec).to.have.property('y', 40); 398 | }); 399 | }); 400 | 401 | describe('#multiplyScalarX()', function () { 402 | var vec, scal, ret; 403 | 404 | before(function () { 405 | vec = new Victor(30, 20); 406 | scal = 2; 407 | ret = vec.multiplyScalarX(scal); 408 | }); 409 | 410 | it('should multiply the X axis by 2', function () { 411 | expect(vec).to.have.property('x', 60); 412 | expect(vec).to.have.property('y', 20); 413 | }); 414 | 415 | it('should be chainable', function () { 416 | expect(ret).to.equal(vec); 417 | }); 418 | }); 419 | 420 | describe('#multiplyScalarY()', function () { 421 | var vec, scal, ret; 422 | 423 | before(function () { 424 | vec = new Victor(30, 20); 425 | scal = 2; 426 | ret = vec.multiplyScalarY(scal); 427 | }); 428 | 429 | it('should be chainable', function () { 430 | expect(ret).to.equal(vec); 431 | }); 432 | 433 | it('should multiply the Y axis by 2', function () { 434 | expect(vec).to.have.property('x', 30); 435 | expect(vec).to.have.property('y', 40); 436 | }); 437 | }); 438 | 439 | describe('#addScalar()', function () { 440 | var vec, scalar, ret; 441 | 442 | before(function () { 443 | vec = new Victor(1, 2); 444 | scalar = 2; 445 | ret = vec.addScalar(scalar); 446 | }); 447 | 448 | it('should be chainable', function () { 449 | expect(ret).to.equal(vec); 450 | }); 451 | 452 | it('should add 2 to both vector axis', function () { 453 | expect(vec).to.have.property('x', 3); 454 | expect(vec).to.have.property('y', 4); 455 | }); 456 | }); 457 | 458 | describe('#addScalarX()', function () { 459 | var vec, scalar, ret; 460 | 461 | before(function () { 462 | vec = new Victor(1, 2); 463 | scalar = 2; 464 | ret = vec.addScalarX(scalar); 465 | }); 466 | 467 | it('should be chainable', function () { 468 | expect(ret).to.equal(vec); 469 | }); 470 | 471 | it('should add 2 to the x axis', function () { 472 | expect(vec).to.have.property('x', 3); 473 | expect(vec).to.have.property('y', 2); 474 | }); 475 | }); 476 | 477 | describe('#addScalarY()', function () { 478 | var vec, scalar, ret; 479 | 480 | before(function () { 481 | vec = new Victor(10, 20); 482 | scalar = 2; 483 | ret = vec.addScalarY(scalar); 484 | }); 485 | 486 | it('should be chainable', function () { 487 | expect(ret).to.equal(vec); 488 | }); 489 | 490 | it('should add 2 to the y axis', function () { 491 | expect(vec).to.have.property('x', 10); 492 | expect(vec).to.have.property('y', 22); 493 | }); 494 | }); 495 | 496 | describe('#subtractScalar()', function () { 497 | var vec, scalar, ret; 498 | 499 | before(function () { 500 | vec = new Victor(10, 20); 501 | scalar = 2; 502 | ret = vec.subtractScalar(scalar); 503 | }); 504 | 505 | it('should be chainable', function () { 506 | expect(ret).to.equal(vec); 507 | }); 508 | 509 | it('should subtract 2 from both vector axis', function () { 510 | expect(vec).to.have.property('x', 8); 511 | expect(vec).to.have.property('y', 18); 512 | }); 513 | }); 514 | 515 | describe('#subtractScalarX()', function () { 516 | var vec, scalar, ret; 517 | 518 | before(function () { 519 | vec = new Victor(10, 20); 520 | scalar = 2; 521 | ret = vec.subtractScalarX(scalar); 522 | }); 523 | 524 | it('should be chainable', function () { 525 | expect(ret).to.equal(vec); 526 | }); 527 | 528 | it('should subtract 2 from the x axis', function () { 529 | expect(vec).to.have.property('x', 8); 530 | expect(vec).to.have.property('y', 20); 531 | }); 532 | }); 533 | 534 | describe('#subtractScalarY()', function () { 535 | var vec, scalar, ret; 536 | 537 | before(function () { 538 | vec = new Victor(10, 20); 539 | scalar = 2; 540 | ret = vec.subtractScalarY(scalar); 541 | }); 542 | 543 | it('should be chainable', function () { 544 | expect(ret).to.equal(vec); 545 | }); 546 | 547 | it('should add 2 to the y axis', function () { 548 | expect(vec).to.have.property('x', 10); 549 | expect(vec).to.have.property('y', 18); 550 | }); 551 | }); 552 | 553 | describe('#norm()', function () { 554 | var vec, ret; 555 | 556 | before(function () { 557 | vec = new Victor(13.37, 42.42); 558 | ret = vec.norm(); 559 | }); 560 | 561 | it('should be chainable', function () { 562 | expect(ret).to.equal(vec); 563 | }); 564 | 565 | it.skip('should?', function () { 566 | expect(vec).to.have.property('x'); 567 | expect(vec).to.have.property('y'); 568 | }); 569 | }); 570 | 571 | describe('#limit()', function () { 572 | var vec, ret; 573 | 574 | before(function () { 575 | vec = new Victor(30, 20); 576 | ret = vec.limit(20, 0.5); 577 | }); 578 | 579 | it('should be chainable', function () { 580 | expect(ret).to.equal(vec); 581 | }); 582 | 583 | it('should limit both vector axis by limit', function () { 584 | expect(vec).to.have.property('x', 15); 585 | expect(vec).to.have.property('y', 20); 586 | }); 587 | }); 588 | 589 | describe('#randomize()', function () { 590 | var topLeft = new Victor(-50, 100); 591 | var bottomRight = new Victor(300, -500); 592 | 593 | it('should be chainable', function () { 594 | var vec = new Victor(30, 20); 595 | expect(vec.randomize(topLeft, bottomRight)).to.equal(vec); 596 | }); 597 | 598 | it('should randomize both vector axis and respect the boundaries', function () { 599 | var i, count = 100; 600 | var vec = new Victor(30, 20); 601 | 602 | var minX = Math.min(topLeft.x, bottomRight.x); 603 | var maxX = Math.max(topLeft.x, bottomRight.x); 604 | var minY = Math.min(topLeft.y, bottomRight.y); 605 | var maxY = Math.max(topLeft.y, bottomRight.y); 606 | 607 | for (i = 0; i < count; i++) { 608 | vec.randomize(topLeft, bottomRight); 609 | 610 | expect(vec.x).to.be.within(minX, maxX); 611 | expect(vec.y).to.be.within(minY, maxY); 612 | } 613 | }); 614 | }); 615 | 616 | describe('#randomizeX()', function () { 617 | var topLeft = new Victor(-50, 100); 618 | var bottomRight = new Victor(300, -500); 619 | 620 | it('should be chainable', function () { 621 | var vec = new Victor(30, 20); 622 | expect(vec.randomizeX(topLeft, bottomRight)).to.equal(vec); 623 | }); 624 | 625 | it('should randomize only the X axis and respect the boundaries', function () { 626 | var i, count = 100; 627 | var vec = new Victor(30, 20); 628 | 629 | var y = vec.y; 630 | var minX = Math.min(topLeft.x, bottomRight.x); 631 | var maxX = Math.max(topLeft.x, bottomRight.x); 632 | 633 | for (i = 0; i < count; i++) { 634 | vec.randomizeX(topLeft, bottomRight); 635 | 636 | expect(vec).to.have.property('x') 637 | .that.is.within(minX, maxX); 638 | 639 | expect(vec).to.have.property('y', y); 640 | } 641 | }); 642 | }); 643 | 644 | describe('#randomizeY()', function () { 645 | var topLeft = new Victor(-50, 100); 646 | var bottomRight = new Victor(300, -500); 647 | 648 | it('should be chainable', function () { 649 | var vec = new Victor(30, 20); 650 | expect(vec.randomizeY(topLeft, bottomRight)).to.equal(vec); 651 | }); 652 | 653 | it('should randomize only the X axis and respect the boundaries', function () { 654 | var i, count = 100; 655 | var vec = new Victor(30, 20); 656 | 657 | var x = vec.x; 658 | var minY = Math.min(topLeft.y, bottomRight.y); 659 | var maxY = Math.max(topLeft.y, bottomRight.y); 660 | 661 | for (i = 0; i < count; i++) { 662 | vec.randomizeY(topLeft, bottomRight); 663 | 664 | expect(vec).to.have.property('y') 665 | .that.is.within(minY, maxY); 666 | 667 | expect(vec).to.have.property('x', x); 668 | } 669 | }); 670 | }); 671 | 672 | describe('#randomizeAny()', function () { 673 | var topLeft = new Victor(100, 100); 674 | var bottomRight = new Victor(300, 300); 675 | 676 | it('should be chainable', function () { 677 | var vec = new Victor(30, 20); 678 | expect(vec.randomizeAny(topLeft, bottomRight)).to.equal(vec); 679 | }); 680 | 681 | it('should randomize only one vector axis and respect the boundaries', function () { 682 | var vec, i, count = 100, originX = 50, originY = 50; 683 | 684 | var minX = Math.min(topLeft.x, bottomRight.x); 685 | var maxX = Math.max(topLeft.x, bottomRight.x); 686 | var minY = Math.min(topLeft.y, bottomRight.y); 687 | var maxY = Math.max(topLeft.y, bottomRight.y); 688 | 689 | for (i = 0; i < count; i++) { 690 | vec = new Victor(originX, originY); 691 | vec.randomizeAny(topLeft, bottomRight); 692 | 693 | if (vec.x !== originX) { 694 | expect(vec).to.have.property('x') 695 | .that.is.within(minX, maxX); 696 | expect(vec).to.have.property('y', originY); 697 | 698 | } else { 699 | expect(vec).to.have.property('y') 700 | .that.is.within(minY, maxY); 701 | expect(vec).to.have.property('x', originX); 702 | } 703 | } 704 | }); 705 | }); 706 | 707 | describe('#unfloat()', function () { 708 | var vec, ret; 709 | 710 | before(function () { 711 | vec = new Victor(30.333, 20.666); 712 | ret = vec.unfloat(); 713 | }); 714 | 715 | it('should be chainable', function () { 716 | expect(ret).to.equal(vec); 717 | }); 718 | 719 | it('should round both vector axis to integers', function () { 720 | expect(vec).to.have.property('x', 30); 721 | expect(vec).to.have.property('y', 21); 722 | }); 723 | }); 724 | 725 | describe('#mixX()', function () { 726 | var vec1, vec2, ret; 727 | 728 | before(function () { 729 | vec1 = new Victor(100, 100); 730 | vec2 = new Victor(200, 200); 731 | ret = vec1.mixX(vec2, 0.5); 732 | }); 733 | 734 | it('should be chainable', function () { 735 | expect(ret).to.equal(vec1); 736 | }); 737 | 738 | it('should interpolate the X axis half way', function () { 739 | expect(vec1).to.have.property('x', 150); 740 | expect(vec1).to.have.property('y', 100); 741 | }); 742 | }); 743 | 744 | describe('#mixY()', function () { 745 | var vec1, vec2, ret; 746 | 747 | before(function () { 748 | vec1 = new Victor(100, 100); 749 | vec2 = new Victor(200, 200); 750 | ret = vec1.mixY(vec2, 0.5); 751 | }); 752 | 753 | it('should be chainable', function () { 754 | expect(ret).to.equal(vec1); 755 | }); 756 | 757 | it('should interpolate the Y axis half way', function () { 758 | expect(vec1).to.have.property('x', 100); 759 | expect(vec1).to.have.property('y', 150); 760 | }); 761 | }); 762 | 763 | describe('#mix()', function () { 764 | var vec1, vec2, ret; 765 | 766 | before(function () { 767 | vec1 = new Victor(100, 100); 768 | vec2 = new Victor(200, 200); 769 | ret = vec1.mix(vec2, 0.5); 770 | }); 771 | 772 | it('should be chainable', function () { 773 | expect(ret).to.equal(vec1); 774 | }); 775 | 776 | it('should interpolate half way', function () { 777 | expect(vec1).to.have.property('x', 150); 778 | expect(vec1).to.have.property('y', 150); 779 | }); 780 | }); 781 | 782 | describe('#zero()', function () { 783 | var vec, ret; 784 | 785 | before(function () { 786 | vec = new Victor(100, 100); 787 | ret = vec.zero(); 788 | }); 789 | 790 | it('should be chainable', function () { 791 | expect(ret).to.equal(vec); 792 | }); 793 | 794 | it('should interpolate half way', function () { 795 | expect(vec).to.have.property('x', 0); 796 | expect(vec).to.have.property('y', 0); 797 | }); 798 | }); 799 | 800 | describe('#horizontalAngle()', function(){ 801 | 802 | var angleX,angleY; 803 | before(function(){ 804 | angleX = new Victor(100,0).horizontalAngle(); 805 | angleY = new Victor(0,100).horizontalAngle(); 806 | angleXPi = new Victor(-100,0).horizontalAngle(); 807 | }); 808 | 809 | it('should x directed vector to 0°', function(){ 810 | expect(Math.abs(angleX - 0)).to.lte(0,EPSILON); 811 | }); 812 | 813 | it('should y directed vector to 90°', function(){ 814 | expect(Math.abs(angleY - Math.PI/2)).to.lte(EPSILON); 815 | }); 816 | 817 | it('should negative x directed vector to 180°', function(){ 818 | expect(Math.abs(angleXPi - Math.PI)).to.lte(EPSILON); 819 | }); 820 | }); 821 | 822 | describe('#rotate()', function () { 823 | var vec, ret; 824 | 825 | before(function () { 826 | vec = new Victor(100, 100); 827 | ret = vec.rotate(90 * Math.PI / 180); 828 | }); 829 | 830 | it('should be chainable', function () { 831 | expect(ret).to.equal(vec); 832 | }); 833 | 834 | it('should rotate the vector by certain degrees', function () { 835 | expect(vec).to.have.property('x', -100); 836 | expect(vec).to.have.property('y', 100); 837 | expect(Math.abs(vec.horizontalAngle() - 135 * Math.PI / 180)).to.lte(EPSILON); 838 | }); 839 | }); 840 | 841 | 842 | describe('#rotateDeg()', function () { 843 | var vec, ret; 844 | 845 | before(function () { 846 | vec = new Victor(100, 100); 847 | ret = vec.rotateDeg(90); 848 | }); 849 | 850 | it('should be chainable', function () { 851 | expect(ret).to.equal(vec); 852 | }); 853 | 854 | it('should set the rotation angle in degrees', function () { 855 | expect(vec).to.have.property('x', -100); 856 | expect(vec).to.have.property('y', 100); 857 | }); 858 | }); 859 | 860 | 861 | describe('#rotateTo()', function(){ 862 | var vecX,vecY, retX, retY; 863 | 864 | 865 | before(function(){ 866 | vecX = new Victor(100,0); 867 | vecY = new Victor(0,100); 868 | retX = vecX.rotateTo(120 * Math.PI / 180); 869 | retY = vecY.rotateTo(120 * Math.PI / 180); 870 | }); 871 | 872 | it('should be chainable', function(){ 873 | expect(retX).to.equal(vecX); 874 | }); 875 | 876 | it('should rotate any Vector to a given angle', function(){ 877 | expect(vecX.angle()).to.equal(120 * Math.PI /180); 878 | expect(vecY.angle()).to.equal(120 * Math.PI /180); 879 | }); 880 | 881 | it('should keep the length', function(){ 882 | expect(retX.length()).to.equal(100); 883 | expect(retY.length()).to.equal(100); 884 | }); 885 | 886 | }); 887 | 888 | describe('#rotateToDeg()', function(){ 889 | var vec,ret; 890 | before(function(){ 891 | vec = new Victor(100,0); 892 | 893 | ret = vec.rotateToDeg(120); 894 | 895 | }); 896 | 897 | it('should be chainable', function(){ 898 | expect(ret).to.equal(vec); 899 | }); 900 | 901 | it('should rotate any Vector to a given angle', function(){ 902 | expect(Math.abs(vec.angleDeg()-120)).to.lte(EPSILON); 903 | 904 | }); 905 | 906 | it('should keep the length', function(){ 907 | expect(ret.length()).to.equal(100); 908 | 909 | }); 910 | 911 | }); 912 | 913 | describe('#rotateBy()', function () { 914 | var vec, ret; 915 | 916 | before(function () { 917 | vec = new Victor(100, 100); 918 | ret = vec.rotateBy(45 * Math.PI / 180); 919 | }); 920 | 921 | it('should be chainable', function () { 922 | expect(ret).to.equal(vec); 923 | }); 924 | 925 | it('should rotate by the given angle', function () { 926 | expect(vec).to.have.property('x', -100); 927 | expect(vec).to.have.property('y', 100); 928 | }); 929 | }); 930 | 931 | describe('#rotateByDeg()', function () { 932 | var vec, ret; 933 | 934 | before(function () { 935 | vec = new Victor(100, 100); 936 | ret = vec.rotateByDeg(45); 937 | }); 938 | 939 | it('should be chainable', function () { 940 | expect(ret).to.equal(vec); 941 | }); 942 | 943 | it('should rotate by the given angle in degrees', function () { 944 | expect(vec).to.have.property('x', -100); 945 | expect(vec).to.have.property('y', 100); 946 | }); 947 | }); 948 | 949 | describe('#projectOnto()', function () { 950 | var vec1, vec2, var3, selfRet, perpRet, paraRet, middleRet; 951 | 952 | before(function () { 953 | vec1 = new Victor(100, 0); 954 | vec2 = new Victor(100, 100); 955 | vec3 = new Victor(0,100); 956 | vec4 = new Victor(200,0); 957 | selfRet = vec1.projectOnto(vec1); 958 | perpRet = vec1.clone().projectOnto(vec3); 959 | paraRet = vec1.clone().projectOnto(vec4); 960 | middleRet = vec1.clone().projectOnto(vec2); 961 | }); 962 | 963 | it('should be chainable', function () { 964 | expect(selfRet).to.equal(vec1); 965 | }); 966 | 967 | it('should project same vector onto itself without change', function() { 968 | expect(selfRet).to.have.property('x',100); 969 | expect(selfRet).to.have.property('y',0); 970 | }); 971 | 972 | it('should project orthogonal vectors into a zero-length vector', function () { 973 | expect(perpRet).to.have.property('x',0); 974 | expect(perpRet).to.have.property('y',0); 975 | }); 976 | 977 | it('shuld project parallel vectors into a vector of same direction and magnitude', function () { 978 | expect(paraRet).to.have.property('x', 100); 979 | expect(paraRet).to.have.property('y', 0); 980 | }); 981 | 982 | it('should project non-orthogonal non-parallel vectors correctly', function () { 983 | expect(middleRet).to.have.property('x', 50); 984 | expect(middleRet).to.have.property('y', 50); 985 | }); 986 | }); 987 | }); 988 | 989 | describe('regular instance methods', function () { 990 | 991 | describe('#clone()', function () { 992 | var vec1, vec2; 993 | 994 | before(function () { 995 | vec1 = new Victor(42, 21); 996 | vec2 = vec1.clone(); 997 | }); 998 | 999 | it('should return a clone of a vector', function () { 1000 | expect(vec2).to.be.an.instanceof(Victor); 1001 | expect(vec2).to.not.equal(vec1); 1002 | }); 1003 | 1004 | it('should have the same values as the original', function () { 1005 | expect(vec1.x).to.equal(vec2.x); 1006 | expect(vec1.y).to.equal(vec2.y); 1007 | }); 1008 | }); 1009 | 1010 | describe('#dot()', function () { 1011 | var vec1, vec2, ret; 1012 | 1013 | before(function () { 1014 | vec1 = new Victor(42, 21); 1015 | vec2 = new Victor(44, 42); 1016 | ret = vec1.dot(vec2); 1017 | }); 1018 | 1019 | it('should return the dot product of 2 vectors', function () { 1020 | expect(ret).to.equal(2730); 1021 | }); 1022 | }); 1023 | 1024 | describe('#distanceX()', function () { 1025 | var vec1, vec2, ret; 1026 | 1027 | before(function () { 1028 | vec1 = new Victor(42, 21); 1029 | vec2 = new Victor(44, 42); 1030 | ret = vec1.distanceX(vec2); 1031 | }); 1032 | 1033 | it('should return the distance between the X axis of 2 vectors', function () { 1034 | expect(ret).to.equal(-2); 1035 | }); 1036 | }); 1037 | 1038 | describe('#distanceY()', function () { 1039 | var vec1, vec2, ret; 1040 | 1041 | before(function () { 1042 | vec1 = new Victor(42, 21); 1043 | vec2 = new Victor(44, 42); 1044 | ret = vec1.distanceY(vec2); 1045 | }); 1046 | 1047 | it('should return the distance between the Y axis of 2 vectors', function () { 1048 | expect(ret).to.equal(-21); 1049 | }); 1050 | }); 1051 | 1052 | describe.skip('#distance()', function () { 1053 | var vec1, vec2, ret; 1054 | 1055 | before(function () { 1056 | vec1 = new Victor(100, 100); 1057 | vec2 = new Victor(200, 100); 1058 | ret = vec1.distance(vec2); 1059 | }); 1060 | 1061 | it('should return the euclidean distance between 2 vectors', function () { 1062 | expect(ret).to.equal(-21); 1063 | }); 1064 | }); 1065 | 1066 | describe('#length()', function () { 1067 | var vec, ret; 1068 | 1069 | before(function () { 1070 | vec = new Victor(100, 100); 1071 | ret = vec.length(); 1072 | }); 1073 | 1074 | it('should return the length of the vector', function () { 1075 | expect(Math.round(ret)).to.equal(141); 1076 | }); 1077 | }); 1078 | 1079 | describe('#isZero()', function () { 1080 | var vec; 1081 | 1082 | before(function () { 1083 | vec = new Victor(100, 100); 1084 | vec.zero(); 1085 | }); 1086 | 1087 | it('should return true if the vector is zero', function () { 1088 | expect(vec.isZero()).to.equal(true); 1089 | }); 1090 | }); 1091 | 1092 | describe('#isEqualTo()', function () { 1093 | var vec1, vec2, vec3; 1094 | 1095 | before(function () { 1096 | vec1 = new Victor(100, 100); 1097 | vec2 = new Victor(100, 120); 1098 | vec3 = new Victor(100, 120); 1099 | }); 1100 | 1101 | it('should return false if the vectors are not the same', function () { 1102 | expect(vec1.isEqualTo(vec2)).to.equal(false); 1103 | }); 1104 | it('should return true if the vectors are the same', function () { 1105 | expect(vec2.isEqualTo(vec3)).to.equal(true); 1106 | }); 1107 | }); 1108 | 1109 | }); 1110 | 1111 | describe('utility methods', function () { 1112 | 1113 | describe('#toString()', function () { 1114 | var vec, ret; 1115 | 1116 | before(function () { 1117 | vec = new Victor(100, 200); 1118 | ret = vec.toString(); 1119 | }); 1120 | 1121 | it('should return a string representation of the vector', function () { 1122 | expect(ret).to.be.a('string'); 1123 | expect(ret).to.have.string('x:100, y:200'); 1124 | }); 1125 | }); 1126 | 1127 | describe('#toArray()', function () { 1128 | var vec, ret; 1129 | 1130 | before(function () { 1131 | vec = new Victor(100, 200); 1132 | ret = vec.toArray(); 1133 | }); 1134 | 1135 | it('should return an array representation of the vector', function () { 1136 | expect(ret).to.be.instanceof(Array); 1137 | expect(ret).to.eql([ 100, 200 ]); 1138 | }); 1139 | }); 1140 | 1141 | describe('#toObject()', function () { 1142 | var vec, ret; 1143 | 1144 | before(function () { 1145 | vec = new Victor(100, 200); 1146 | ret = vec.toObject(); 1147 | }); 1148 | 1149 | it('should return an object representation of the vector', function () { 1150 | expect(ret).to.be.instanceof(Object); 1151 | expect(ret).to.eql({ x: 100, y: 200 }); 1152 | }); 1153 | }); 1154 | }); 1155 | --------------------------------------------------------------------------------