Spaces:
Running
Running
import { Matrix4 } from "./Matrix4"; | |
class Vector3 { | |
public readonly x: number; | |
public readonly y: number; | |
public readonly z: number; | |
constructor(x: number = 0, y: number = 0, z: number = 0) { | |
this.x = x; | |
this.y = y; | |
this.z = z; | |
} | |
equals(v: Vector3): boolean { | |
if (this.x !== v.x) { | |
return false; | |
} | |
if (this.y !== v.y) { | |
return false; | |
} | |
if (this.z !== v.z) { | |
return false; | |
} | |
return true; | |
} | |
add(v: number): Vector3; | |
add(v: Vector3): Vector3; | |
add(v: number | Vector3): Vector3 { | |
if (typeof v === "number") { | |
return new Vector3(this.x + v, this.y + v, this.z + v); | |
} else { | |
return new Vector3(this.x + v.x, this.y + v.y, this.z + v.z); | |
} | |
} | |
subtract(v: number): Vector3; | |
subtract(v: Vector3): Vector3; | |
subtract(v: number | Vector3): Vector3 { | |
if (typeof v === "number") { | |
return new Vector3(this.x - v, this.y - v, this.z - v); | |
} else { | |
return new Vector3(this.x - v.x, this.y - v.y, this.z - v.z); | |
} | |
} | |
multiply(v: number): Vector3; | |
multiply(v: Vector3): Vector3; | |
multiply(v: Matrix4): Vector3; | |
multiply(v: number | Vector3 | Matrix4): Vector3 { | |
if (typeof v === "number") { | |
return new Vector3(this.x * v, this.y * v, this.z * v); | |
} else if (v instanceof Vector3) { | |
return new Vector3(this.x * v.x, this.y * v.y, this.z * v.z); | |
} else { | |
return new Vector3( | |
this.x * v.buffer[0] + this.y * v.buffer[4] + this.z * v.buffer[8] + v.buffer[12], | |
this.x * v.buffer[1] + this.y * v.buffer[5] + this.z * v.buffer[9] + v.buffer[13], | |
this.x * v.buffer[2] + this.y * v.buffer[6] + this.z * v.buffer[10] + v.buffer[14], | |
); | |
} | |
} | |
divide(v: number): Vector3; | |
divide(v: Vector3): Vector3; | |
divide(v: number | Vector3): Vector3 { | |
if (typeof v === "number") { | |
return new Vector3(this.x / v, this.y / v, this.z / v); | |
} else { | |
return new Vector3(this.x / v.x, this.y / v.y, this.z / v.z); | |
} | |
} | |
cross(v: Vector3): Vector3 { | |
const x = this.y * v.z - this.z * v.y; | |
const y = this.z * v.x - this.x * v.z; | |
const z = this.x * v.y - this.y * v.x; | |
return new Vector3(x, y, z); | |
} | |
dot(v: Vector3): number { | |
return this.x * v.x + this.y * v.y + this.z * v.z; | |
} | |
lerp(v: Vector3, t: number): Vector3 { | |
return new Vector3(this.x + (v.x - this.x) * t, this.y + (v.y - this.y) * t, this.z + (v.z - this.z) * t); | |
} | |
min(v: Vector3): Vector3 { | |
return new Vector3(Math.min(this.x, v.x), Math.min(this.y, v.y), Math.min(this.z, v.z)); | |
} | |
max(v: Vector3): Vector3 { | |
return new Vector3(Math.max(this.x, v.x), Math.max(this.y, v.y), Math.max(this.z, v.z)); | |
} | |
getComponent(axis: number) { | |
switch (axis) { | |
case 0: | |
return this.x; | |
case 1: | |
return this.y; | |
case 2: | |
return this.z; | |
default: | |
throw new Error(`Invalid component index: ${axis}`); | |
} | |
} | |
minComponent(): number { | |
if (this.x < this.y && this.x < this.z) { | |
return 0; | |
} else if (this.y < this.z) { | |
return 1; | |
} else { | |
return 2; | |
} | |
} | |
maxComponent(): number { | |
if (this.x > this.y && this.x > this.z) { | |
return 0; | |
} else if (this.y > this.z) { | |
return 1; | |
} else { | |
return 2; | |
} | |
} | |
magnitude(): number { | |
return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); | |
} | |
distanceTo(v: Vector3): number { | |
return Math.sqrt((this.x - v.x) ** 2 + (this.y - v.y) ** 2 + (this.z - v.z) ** 2); | |
} | |
normalize(): Vector3 { | |
const length = this.magnitude(); | |
return new Vector3(this.x / length, this.y / length, this.z / length); | |
} | |
flat(): number[] { | |
return [this.x, this.y, this.z]; | |
} | |
clone(): Vector3 { | |
return new Vector3(this.x, this.y, this.z); | |
} | |
toString(): string { | |
return `[${this.flat().join(", ")}]`; | |
} | |
static One(value: number = 1): Vector3 { | |
return new Vector3(value, value, value); | |
} | |
} | |
export { Vector3 }; | |