Skip to content

Instantly share code, notes, and snippets.

@leicht-io
Last active October 17, 2019 07:21
Show Gist options
  • Save leicht-io/eb8dfdf4188d0a555523f3720e21f822 to your computer and use it in GitHub Desktop.
Save leicht-io/eb8dfdf4188d0a555523f3720e21f822 to your computer and use it in GitHub Desktop.
Typescript class for manipulating vectors in 2D and 3D
export class Vector {
public x;
public y;
public z;
constructor(x: number, y: number, z?: number) {
this.x = x || 0;
this.y = y || 0;
this.z = z || 0;
}
public negative(): Vector {
return new Vector(-this.x, -this.y, -this.z);
}
public add(v: Vector): Vector {
return new Vector(this.x + v.x, this.y + v.y, this.z + v.z);
}
public subtract(v: Vector): Vector {
return new Vector(this.x - v.x, this.y - v.y, this.z - v.z);
}
public multiply(v: Vector): Vector {
return new Vector(this.x * v.x, this.y * v.y, this.z * v.z);
}
public divide(v: Vector): Vector {
return new Vector(this.x / v.x, this.y / v.y, this.z / v.z);
}
public equals(v: Vector): boolean {
return this.x === v.x && this.y === v.y && this.z === v.z;
}
public dot(v: Vector): number {
return this.x * v.x + this.y * v.y + this.z * v.z;
}
public cross(v: Vector): Vector {
return new Vector(
this.y * v.z - this.z * v.y,
this.z * v.x - this.x * v.z,
this.x * v.y - this.y * v.x
);
}
public length(): number {
return Math.sqrt(this.dot(this));
}
public min(): number {
return Math.min(Math.min(this.x, this.y), this.z);
}
public max(): number {
return Math.max(Math.max(this.x, this.y), this.z);
}
public toAngles(): { theta: number, phi: number } {
return {
theta: Math.atan2(this.z, this.x),
phi: Math.asin(this.y / this.length())
};
}
public angleTo(a: Vector): number {
return Math.acos(this.dot(a) / (this.length() * a.length()));
}
public toArray(n: number): number[] {
return [this.x, this.y, this.z].slice(0, n || 3);
}
public clone(): Vector {
return new Vector(this.x, this.y, this.z);
}
public init(x: number, y: number, z?: number): Vector {
this.x = x;
this.y = y;
this.z = z;
return this;
}
public static negative(a: Vector, b: Vector): Vector {
b.x = -a.x;
b.y = -a.y;
b.z = -a.z;
return b;
}
public static add(a: Vector, b: Vector, c: Vector): Vector {
c.x = a.x + b.x;
c.y = a.y + b.y;
c.z = a.z + b.z;
return c;
}
public static subtract(a: Vector, b: Vector, c: Vector): Vector {
c.x = a.x - b.x;
c.y = a.y - b.y;
c.z = a.z - b.z;
return c;
}
public static multiply(a: Vector, b: Vector, c: Vector): Vector {
c.x = a.x * b.x;
c.y = a.y * b.y;
c.z = a.z * b.z;
return c;
}
public static divide(a: Vector, b: Vector, c: Vector): Vector {
c.x = a.x / b.x;
c.y = a.y / b.y;
c.z = a.z / b.z;
return c;
}
public static cross(a: Vector, b: Vector, c: Vector): Vector {
c.x = a.y * b.z - a.z * b.y;
c.y = a.z * b.x - a.x * b.z;
c.z = a.x * b.y - a.y * b.x;
return c;
}
public static unit(a: Vector, b: Vector): Vector {
const length = a.length();
b.x = a.x / length;
b.y = a.y / length;
b.z = a.z / length;
return b;
}
public static fromAngles(theta: number, phi: number): Vector {
return new Vector(Math.cos(theta) * Math.cos(phi), Math.sin(phi), Math.sin(theta) * Math.cos(phi));
}
public static randomDirection(): Vector {
return Vector.fromAngles(Math.random() * Math.PI * 2, Math.asin(Math.random() * 2 - 1));
}
public static min(a: Vector, b: Vector): Vector {
return new Vector(Math.min(a.x, b.x), Math.min(a.y, b.y), Math.min(a.z, b.z));
}
public static max(a: Vector, b: Vector): Vector {
return new Vector(Math.max(a.x, b.x), Math.max(a.y, b.y), Math.max(a.z, b.z));
}
public static lerp(a: Vector, b: Vector, fraction): Vector {
return b.subtract(a).multiply(fraction).add(a);
}
public static fromArray(a: Vector): Vector {
return new Vector(a[0], a[1], a[2]);
}
public static angleBetween(a: Vector, b: Vector): number {
return a.angleTo(b);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment