Created
January 25, 2021 10:52
-
-
Save statox/df5b450a2058f3b062c394b14630bb32 to your computer and use it in GitHub Desktop.
A typescript vector classe that I use in codingame challenges
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const degrees = 180 / Math.PI; | |
function radian2degrees (rad: number): number { | |
return rad * degrees; | |
} | |
function degrees2radian (deg: number): number { | |
return deg / degrees; | |
} | |
/* | |
* Vector class largely inspired by | |
* https://www.npmjs.com/package/victor | |
* https://github.com/processing/p5.js/blob/main/src/math/p5.Vector.js | |
* | |
* TODO: Use an original name | |
*/ | |
class Victor { | |
x: number; | |
y: number; | |
constructor(x: number, y: number) { | |
this.x = x; | |
this.y = y; | |
} | |
clone(): Victor { | |
return new Victor(this.x, this.y); | |
} | |
copy(vec: Victor): Victor { | |
this.x = vec.x; | |
this.y = vec.y; | |
return this; | |
} | |
add(vec: Victor): Victor { | |
this.x += vec.x; | |
this.y += vec.y; | |
return this; | |
} | |
substract(vec: Victor): Victor { | |
this.x -= vec.x; | |
this.y -= vec.y; | |
return this; | |
} | |
normalize(): Victor { | |
var length = this.length(); | |
if (length === 0) { | |
this.x = 1; | |
this.y = 0; | |
} else { | |
this.divide(new Victor(length, length)); | |
} | |
return this; | |
} | |
unfloat() { | |
this.x = Math.ceil(this.x); | |
this.y = Math.ceil(this.y); | |
return this; | |
} | |
divide(vec: Victor) { | |
this.x /= vec.x; | |
this.y /= vec.y; | |
return this; | |
} | |
multiplyScalar(scalar: number) { | |
this.x *= scalar; | |
this.y *= scalar; | |
return this; | |
} | |
rotate(angle: number): Victor { | |
var nx = this.x * Math.cos(angle) - this.y * Math.sin(angle); | |
var ny = this.x * Math.sin(angle) + this.y * Math.cos(angle); | |
this.x = nx; | |
this.y = ny; | |
return this; | |
} | |
rotateDeg(angle: number): Victor { | |
angle = degrees2radian(angle); | |
return this.rotate(angle); | |
} | |
horizontalAngle(): number { | |
return Math.atan2(this.y, this.x); | |
} | |
angle(): number { | |
return this.horizontalAngle(); | |
} | |
rotateBy(rotation: number): Victor { | |
var angle = this.angle() + rotation; | |
return this.rotate(angle); | |
} | |
rotateByDeg(rotation: number): Victor { | |
rotation = degrees2radian(rotation); | |
return this.rotateBy(rotation); | |
} | |
dot(vec: Victor): number { | |
return this.x * vec.x + this.y * vec.y; | |
} | |
cross(vec: Victor): number { | |
return this.x * vec.y - this.y * vec.x; | |
} | |
lengthSq(): number { | |
return this.x * this.x + this.y * this.y; | |
} | |
length(): number { | |
return Math.sqrt(this.lengthSq()); | |
} | |
magnitude(): number { | |
return this.length(); | |
} | |
distanceX(vec: Victor): number { | |
return this.x - vec.x; | |
} | |
distanceY(vec: Victor): number { | |
return this.y - vec.y; | |
} | |
distanceSq(vec: Victor): number { | |
var dx = this.distanceX(vec), | |
dy = this.distanceY(vec); | |
return dx * dx + dy * dy; | |
} | |
distance(vec: Victor): number { | |
return Math.sqrt(this.distanceSq(vec)); | |
} | |
isEqualTo(vec: Victor): boolean { | |
return this.x === vec.x && this.y === vec.y; | |
} | |
angleBetween(vec: Victor) { | |
const dotmagmag = this.dot(vec) / (this.length() * vec.length()); | |
let angle; | |
angle = Math.acos(Math.min(1, Math.max(-1, dotmagmag))); | |
return radian2degrees(angle); | |
} | |
toString(): String { | |
return `${this.x} - ${this.y}`; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment