-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVector.ts
74 lines (74 loc) · 2.89 KB
/
Vector.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
class Vector {
protected _components: number[]
constructor(components: number[]) {
this._components = components;
}
get components(): number[] {
return this._components;
}
add(other: Vector) {
return new Vector(other.components.map((component, index) => this.components[index] + component))
}
subtract(other: Vector) {
return new Vector(other.components.map((component, index) => this.components[index] + component))
}
set(components: number[]) {
this._components = components;
return this;
}
scalar(scale: number): number {
return new Vector(this.components.map(component => component * scale));
}
length(): number {
return Math.hypot(...this.components)
}
distanceTo(other: Vector): number {
return this.components.map((component, index) => (other.components[index] - component) ** 2).reduce((acc, current) => acc += current) ** 0.5;
}
public dotProduct(other: Vector) {
return other.components.reduce((acc, component, index) => acc + component * this.components[index], 0);
}
public negate(): Vector {
return this.scalar(-1);
}
public normalize(): Vector {
return this.scalar(1 / this.length());
}
public haveSameDirectionWith(other: Vector): boolean {
return this.normalize().dotProduct(other.normalize()) === 1;
}
public haveOppositeDirectionTo(other: Vector): boolean {
return this.normalize().dotProduct(other.normalize()) === -1;
}
public isPerpendicularTo(other: Vector): boolean {
return this.normalize().dotProduct(other.normalize()) === 0;
}
public angleBetween(other: Vector): number {
return ((Math.acos(this.dotProduct(other) / (this.length() * other.length()))) * 180) / Math.PI;
}
public projectOn(other: Vector): Vector {
const normalized = other.normalize();
return normalized.scalar(this.dotProduct(normalized));
}
public withLength(length: number): Vector {
return this.normalize().scalar(length);
}
public equalTo(other: Vector): boolean {
if (this.components.length != other.components.length) return false;
return this.components.every((component, index) => component === other.components[index]);
}
public midpoint(other: Vector): Vector {
return new Vector(this.components.map((component, index) => (component + other.components[index]) / 2));
}
public distanceToSquared(other: Vector): number {
return this.components.reduce((acc, component, index) => acc + (component - other.components[index]) ** 2, 0);
}
public toString(): string {
let out = '[ '
this.components.forEach(component => {
if (component === this.components[this.components.length - 1]) out += `${component} ]`
else out += `${component}, `
})
return out;
}
}