Last active
October 17, 2019 07:21
-
-
Save leicht-io/eb8dfdf4188d0a555523f3720e21f822 to your computer and use it in GitHub Desktop.
Typescript class for manipulating vectors in 2D and 3D
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
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