Skip to content

Instantly share code, notes, and snippets.

@statox
Created January 25, 2021 10:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save statox/df5b450a2058f3b062c394b14630bb32 to your computer and use it in GitHub Desktop.
Save statox/df5b450a2058f3b062c394b14630bb32 to your computer and use it in GitHub Desktop.
A typescript vector classe that I use in codingame challenges
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