-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvector2d.lua
202 lines (176 loc) · 7.45 KB
/
vector2d.lua
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
------------------------------------------------------------------------------------------------
-- The vector2d module.
--
-- @module vector2d
-- @author Łukasz Durniat
-- @license MIT
-- @copyright Łukasz Durniat, Sep-2024
------------------------------------------------------------------------------------------------
-- ------------------------------------------------------------------------------------------ --
-- REQUIRED MODULES --
-- ------------------------------------------------------------------------------------------ --
-- ------------------------------------------------------------------------------------------ --
-- MODULE DECLARATION --
-- ------------------------------------------------------------------------------------------ --
local M = {}
-- ------------------------------------------------------------------------------------------ --
-- LOCALISED VARIABLES --
-- ------------------------------------------------------------------------------------------ --
local sqrt = math.sqrt
local cos = math.cos
local sin = math.sin
local rad = math.rad
local atan2 = math.atan2
local deg = math.deg
local rand = math.random
-- ------------------------------------------------------------------------------------------ --
-- PRIVATE METHODS --
-- ------------------------------------------------------------------------------------------ --
-- Constructor function of vector2d module.
--
-- @param `x`: The x-coordinate position.
-- @param `y`: The y-coordinate position.
--
-- @return The new new vector.
function M.new(x, y)
-- Set default values
x = x or 0
y = y or 0
return {x = x, y = y}
end
-- Adds two vectors.
--
-- @param `vector1`: The first vector, represented as a table with `x` and `y` keys.
-- @param `vector2`: The second vector, represented as a table with `x` and `y` keys.
--
-- @return A new vector representing the sum of `vector1` and `vector2`.
function M.add(vector1, vector2)
return {x = vector1.x + vector2.x, y = vector1.y + vector2.y}
end
-- Subtracts the second vector from the first.
--
-- @param `vector1`: The vector to subtract from, represented as a table with `x` and `y` keys.
-- @param `vector2`: The vector to subtract, represented as a table with `x` and `y` keys.
--
-- @return A new vector representing the difference between `vector1` and `vector2`.
function M.subtract(vector1, vector2)
return {x = vector1.x - vector2.x, y = vector1.y - vector2.y}
end
-- Multiplies a vector by a scalar value.
--
-- @param `vector`: The vector to multiply, represented as a table with `x` and `y` keys.
-- @param `scalar`: The scalar value to multiply the vector by.
--
-- @return A new vector representing the product of the original vector and the scalar.
function M.multiply(vector, scalar)
return {x = vector.x * scalar, y = vector.y * scalar}
end
-- Divides a vector by a scalar value.
--
-- @param `vector`: The vector to divide, represented as a table with `x` and `y` keys.
-- @param `scalar`: The scalar value to divide the vector by.
--
-- @return A new vector representing the quotient of the original vector divided by the scalar.
function M.divide(vector, scalar)
return {x = vector.x / scalar, y = vector.y / scalar}
end
-- Calculates the magnitude of a vector.
--
-- @param `vector`: The vector whose magnitude is to be calculated, represented as a table with `x` and `y` keys.
--
-- @return A floating-point number representing the magnitude of the vector.
function M.magnitude(vector)
return sqrt(vector.x * vector.x + vector.y * vector.y)
end
-- Normalizes a vector to a unit vector (magnitude of 1).
--
-- @param `vector`: The vector to normalize, represented as a table with `x` and `y` keys.
--
-- @return A normalized vector with the same direction as the original vector. If the vector is zero-length, it returns the original vector.
function M.normalize(vector)
local mag = M.magnitude(vector)
if mag == 0 then
return vector -- Return the original vector if its magnitude is 0.
else
return {x = vector.x / mag, y = vector.y / mag}
end
end
-- Converts an angle (in degrees) to a unit vector in the Cartesian coordinate system.
--
-- @param `angle`: The angle in degrees to convert to a unit vector.
--
-- @return A new unit vector represented as a table with `x` and `y` keys.
function M.fromAngle(angle)
local radians = angle * (math.pi / 180) -- Convert degrees to radians
return {x = cos(radians), y = sin(radians)}
end
--- Calculates the distance between two vectors in the Cartesian coordinate system.
--
-- @param `vectorA`: The first vector, represented as a table with `x` and `y` keys.
-- @param `vectorB`: The second vector, represented as a table with `x` and `y` keys.
--
-- @return The distance between `vectorA` and `vectorB` as a number.
function M.distance(vectorA, vectorB)
local dx = vectorB.x - vectorA.x
local dy = vectorB.y - vectorA.y
return sqrt(dx * dx + dy * dy)
end
-- Calculates the dot product of two vectors.
--
-- @param `vectorA`: The first vector, represented as a table with `x` and `y` keys.
-- @param `vectorB`: The second vector, represented as a table with `x` and `y` keys.
--
-- @return A number representing the dot product of `vectorA` and `vectorB`.
function M.dot(vectorA, vectorB)
return vectorA.x * vectorB.x + vectorA.y * vectorB.y
end
-- Negates a vector, reversing its direction in place.
--
-- @param `vector`: The vector to negate, represented as a table with `x` and `y` keys.
--
-- @return The original vector with both `x` and `y` components negated.
function M.negate(vector)
vector.x = -vector.x
vector.y = -vector.y
return vector
end
-- Rotates a vector by a given angle and returns a new vector.
--
-- @param `vector`: The vector to rotate, represented as a table with `x` and `y` keys.
-- @param `angle`: The angle in degrees by which to rotate the vector.
--
-- @return A new vector with `x` and `y` components representing the rotated vector.
function M.rotate(vector, angle)
local radians = rad(angle)
local cosAngle = cos(radians)
local sinAngle = sin(radians)
local rotatedX = vector.x * cosAngle - vector.y * sinAngle
local rotatedY = vector.x * sinAngle + vector.y * cosAngle
return {x = rotatedX, y = rotatedY}
end
-- Calculates the angle of the vector relative to the X-axis in the Cartesian coordinate system.
--
-- @param `vector`: The vector for which to calculate the angle, represented as a table with `x` and `y` keys.
--
-- @return The angle in degrees between the vector and the positive X-axis.
function M.angle(vector)
return deg(atan2(vector.y, vector.x))
end
-- Generates a random vector within a specified range.
--
-- @param `minX`: The minimum value for the x-component.
-- @param `maxX`: The maximum value for the x-component.
-- @param `minY`: The minimum value for the y-component.
-- @param `maxY`: The maximum value for the y-component.
--
-- @return A new vector with `x` and `y` components set to random values within the specified range.
function M.random(minX, maxX, minY, maxY)
minX = minX or 0
maxX = maxX or 1
minY = minY or 0
maxY = maxY or 1
local x = rand() * (maxX - minX) + minX
local y = rand() * (maxY - minY) + minY
return {x = x, y = y}
end
return M