forked from TheAlgorithms/JavaScript
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Vector2.js
139 lines (126 loc) · 3.28 KB
/
Vector2.js
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/**
* In mathematics and physics, a vector is an element of a vector space.
*
* The Vector2-class implements 2-dimensional vectors together with various vector-operations.
* @see https://en.wikipedia.org/wiki/Vector_(mathematics_and_physics).
*/
class Vector2 {
constructor (x, y) {
this.x = x
this.y = y
}
/**
* Check for exact vector equality.
*
* @param vector The vector to compare to.
* @returns Whether they are exactly equal or not.
*/
equalsExactly (vector) {
return this.x === vector.x && this.y === vector.y
}
/**
* Check for approximate vector equality.
*
* @param vector The vector to compare to.
* @param epsilon The allowed discrepancy for the x-values and the y-values.
* @returns Whether they are approximately equal or not.
*/
equalsApproximately (vector, epsilon) {
return (Math.abs(this.x - vector.x) < epsilon && Math.abs(this.y - vector.y) < epsilon)
}
/**
* Vector length.
*
* @returns The length of the vector.
*/
length () {
return Math.sqrt(this.x * this.x + this.y * this.y)
}
/**
* Normalization sets the vector to length 1 while maintaining its direction.
*
* @returns The normalized vector.
*/
normalize () {
const length = this.length()
if (length === 0) {
throw new Error('Cannot normalize vectors of length 0')
}
return new Vector2(this.x / length, this.y / length)
}
/**
* Vector addition
*
* @param vector The vector to be added.
* @returns The sum-vector.
*/
add (vector) {
const x = this.x + vector.x
const y = this.y + vector.y
return new Vector2(x, y)
}
/**
* Vector subtraction
*
* @param vector The vector to be subtracted.
* @returns The difference-vector.
*/
subtract (vector) {
const x = this.x - vector.x
const y = this.y - vector.y
return new Vector2(x, y)
}
/**
* Vector scalar multiplication
*
* @param scalar The factor by which to multiply the vector.
* @returns The scaled vector.
*/
multiply (scalar) {
const x = this.x * scalar
const y = this.y * scalar
return new Vector2(x, y)
}
/**
* Distance between this vector and another vector.
*
* @param vector The vector to which to calculate the distance.
* @returns The distance.
*/
distance (vector) {
const difference = vector.subtract(this)
return difference.length()
}
/**
* Vector dot product
*
* @param vector The vector used for the multiplication.
* @returns The resulting dot product.
*/
dotProduct (vector) {
return this.x * vector.x + this.y * vector.y
}
/**
* Vector rotation (see https://en.wikipedia.org/wiki/Rotation_matrix)
*
* @param angleInRadians The angle in radians by which to rotate the vector.
* @returns The rotated vector.
*/
rotate (angleInRadians) {
const ca = Math.cos(angleInRadians)
const sa = Math.sin(angleInRadians)
const x = ca * this.x - sa * this.y
const y = sa * this.x + ca * this.y
return new Vector2(x, y)
}
/**
* Measure angle between two vectors
*
* @param vector The 2nd vector for the measurement.
* @returns The angle in radians.
*/
angleBetween (vector) {
return Math.atan2(vector.y, vector.x) - Math.atan2(this.y, this.x)
}
}
export { Vector2 }