e2D 1.4.19__tar.gz → 1.4.21__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {e2d-1.4.19 → e2d-1.4.21}/LICENSE +21 -21
- {e2d-1.4.19 → e2d-1.4.21}/PKG-INFO +3 -2
- {e2d-1.4.19 → e2d-1.4.21}/e2D/__init__.py +58 -7
- {e2d-1.4.19 → e2d-1.4.21}/e2D/__init__.pyi +294 -5
- {e2d-1.4.19 → e2d-1.4.21}/e2D/colors.py +53 -23
- {e2d-1.4.19 → e2d-1.4.21}/e2D/envs.py +71 -23
- e2d-1.4.21/e2D/utils.py +577 -0
- {e2d-1.4.19 → e2d-1.4.21}/e2D.egg-info/PKG-INFO +3 -2
- {e2d-1.4.19 → e2d-1.4.21}/setup.cfg +1 -1
- e2d-1.4.19/e2D/utils.py +0 -191
- {e2d-1.4.19 → e2d-1.4.21}/README.md +0 -0
- {e2d-1.4.19 → e2d-1.4.21}/e2D/def_colors.py +0 -0
- {e2d-1.4.19 → e2d-1.4.21}/e2D/plots.py +0 -0
- {e2d-1.4.19 → e2d-1.4.21}/e2D/winrec.py +0 -0
- {e2d-1.4.19 → e2d-1.4.21}/e2D.egg-info/SOURCES.txt +0 -0
- {e2d-1.4.19 → e2d-1.4.21}/e2D.egg-info/dependency_links.txt +0 -0
- {e2d-1.4.19 → e2d-1.4.21}/e2D.egg-info/requires.txt +0 -0
- {e2d-1.4.19 → e2d-1.4.21}/e2D.egg-info/top_level.txt +0 -0
- {e2d-1.4.19 → e2d-1.4.21}/pyproject.toml +0 -0
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 Riccardo Mariani
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Riccardo Mariani
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: e2D
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.21
|
|
4
4
|
Summary: Python library for 2D games. Streamlines dev with keyboard/mouse input, vector calculations, color manipulation, and collision detection. Simplify game creation and unleash creativity!
|
|
5
5
|
Home-page: https://github.com/marick-py/e2D
|
|
6
6
|
Author: Riccardo Mariani
|
|
@@ -13,6 +13,7 @@ Description-Content-Type: text/markdown
|
|
|
13
13
|
License-File: LICENSE
|
|
14
14
|
Requires-Dist: numpy
|
|
15
15
|
Requires-Dist: pygame
|
|
16
|
+
Dynamic: license-file
|
|
16
17
|
|
|
17
18
|
# e2D
|
|
18
19
|
## A Python Game Development Library
|
|
@@ -10,6 +10,7 @@ PI_QUARTER = PI/4
|
|
|
10
10
|
PI_DOUBLE = PI*2
|
|
11
11
|
|
|
12
12
|
sign = lambda val: -1 if val < 0 else (1 if val > 0 else 0)
|
|
13
|
+
clamp = lambda x, minn, maxx: x if x > minn and x < maxx else (minn if x < minn else maxx)
|
|
13
14
|
|
|
14
15
|
class Vector2D:
|
|
15
16
|
round_values_on_print = 2
|
|
@@ -34,6 +35,22 @@ class Vector2D:
|
|
|
34
35
|
@angle.setter
|
|
35
36
|
def angle(self, new_angle) -> None:
|
|
36
37
|
self.rotate(new_angle - self.angle)
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def aspect_x(self) -> float:
|
|
41
|
+
return self.x / self.y if self.y != 0 else 0
|
|
42
|
+
|
|
43
|
+
@aspect_x.setter
|
|
44
|
+
def aspect_x(self, new_aspect) -> None:
|
|
45
|
+
self.x = self.y * new_aspect
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def aspect_y(self) -> float:
|
|
49
|
+
return self.y / self.x if self.x != 0 else 0
|
|
50
|
+
|
|
51
|
+
@aspect_y.setter
|
|
52
|
+
def aspect_y(self, new_aspect) -> None:
|
|
53
|
+
self.y = self.x * new_aspect
|
|
37
54
|
|
|
38
55
|
@property
|
|
39
56
|
def copy(self) -> "Vector2D":
|
|
@@ -42,9 +59,16 @@ class Vector2D:
|
|
|
42
59
|
@property
|
|
43
60
|
def sign(self) -> "Vector2D":
|
|
44
61
|
return Vector2D(sign(self.x), sign(self.y))
|
|
62
|
+
|
|
63
|
+
def clamp(self, min_val: Vector2D, max_val: Vector2D) -> "Vector2D":
|
|
64
|
+
return Vector2D(clamp(self.x, min_val.x, max_val.x), clamp(self.y, min_val.y, max_val.y))
|
|
65
|
+
|
|
66
|
+
def iclamp(self, min_val: Vector2D, max_val: Vector2D) -> None:
|
|
67
|
+
self.x = clamp(self.x, min_val.x, max_val.x)
|
|
68
|
+
self.y = clamp(self.y, min_val.y, max_val.y)
|
|
45
69
|
|
|
46
70
|
@property
|
|
47
|
-
def
|
|
71
|
+
def normalized(self) -> "Vector2D":
|
|
48
72
|
if (mag:=self.length) == 0:
|
|
49
73
|
return self.copy
|
|
50
74
|
return Vector2D(self.x / mag, self.y / mag)
|
|
@@ -52,11 +76,31 @@ class Vector2D:
|
|
|
52
76
|
@property
|
|
53
77
|
def length(self) -> float:
|
|
54
78
|
return (self.x ** 2 + self.y ** 2) ** .5
|
|
55
|
-
|
|
79
|
+
|
|
80
|
+
@length.setter
|
|
81
|
+
def length(self, new_length: float) -> None:
|
|
82
|
+
current_length = self.length
|
|
83
|
+
if current_length == 0:
|
|
84
|
+
self.x = new_length
|
|
85
|
+
self.y = 0
|
|
86
|
+
else:
|
|
87
|
+
self.x *= new_length / current_length
|
|
88
|
+
self.y *= new_length / current_length
|
|
89
|
+
|
|
56
90
|
@property
|
|
57
91
|
def length_sqrd(self) -> float:
|
|
58
92
|
return self.x ** 2 + self.y ** 2
|
|
59
|
-
|
|
93
|
+
|
|
94
|
+
@length_sqrd.setter
|
|
95
|
+
def length_sqrd(self, new_length_sqrd: float) -> None:
|
|
96
|
+
current_length = self.length
|
|
97
|
+
if current_length == 0:
|
|
98
|
+
self.x = _mt.sqrt(new_length_sqrd)
|
|
99
|
+
self.y = 0
|
|
100
|
+
else:
|
|
101
|
+
self.x *= _mt.sqrt(new_length_sqrd) / current_length
|
|
102
|
+
self.y *= _mt.sqrt(new_length_sqrd) / current_length
|
|
103
|
+
|
|
60
104
|
@property
|
|
61
105
|
def inverse(self) -> "Vector2D":
|
|
62
106
|
return self.mult(-1)
|
|
@@ -111,6 +155,13 @@ class Vector2D:
|
|
|
111
155
|
def complex_to_cartesian(cls, complex_n) -> "Vector2D":
|
|
112
156
|
return cls(complex_n.real, complex_n.imag)
|
|
113
157
|
|
|
158
|
+
def cartesian_to_linear(self, size) -> int:
|
|
159
|
+
return int(self.x + self.y * size)
|
|
160
|
+
|
|
161
|
+
@classmethod
|
|
162
|
+
def linear_to_cartesian(cls, linear, size) -> "Vector2D":
|
|
163
|
+
return cls(linear % size, linear // size)
|
|
164
|
+
|
|
114
165
|
def lerp(self, other, t=.1) -> "Vector2D":
|
|
115
166
|
return Vector2D(self.x + (other.x - self.x) * t, self.y + (other.y - self.y) * t)
|
|
116
167
|
|
|
@@ -487,10 +538,10 @@ V2down_right = Vector2D(1, -1)
|
|
|
487
538
|
V2up_left = Vector2D(-1, 1)
|
|
488
539
|
V2down_left = Vector2D(-1, -1)
|
|
489
540
|
|
|
490
|
-
V2up_right_norm = V2up_right.
|
|
491
|
-
V2down_right_norm = V2down_right.
|
|
492
|
-
V2up_left_norm = V2up_left.
|
|
493
|
-
V2down_left_norm = V2down_left.
|
|
541
|
+
V2up_right_norm = V2up_right.normalized
|
|
542
|
+
V2down_right_norm = V2down_right.normalized
|
|
543
|
+
V2up_left_norm = V2up_left.normalized
|
|
544
|
+
V2down_left_norm = V2down_left.normalized
|
|
494
545
|
|
|
495
546
|
VECTORS_4_DIRECTIONS = (V2right, V2down, V2left, V2up)
|
|
496
547
|
VECTORS_4_SEMIDIRECTIONS = (V2down_right, V2down_left, V2up_left, V2up_right)
|
|
@@ -12,6 +12,7 @@ PI_DOUBLE : float
|
|
|
12
12
|
#
|
|
13
13
|
|
|
14
14
|
sign : Callable[[int|float], Literal[-1,0,1]]
|
|
15
|
+
clamp: Callable[[int|float, int|float, int|float], int|float]
|
|
15
16
|
|
|
16
17
|
class Vector2D:
|
|
17
18
|
round_values_on_print : int|float
|
|
@@ -140,10 +141,59 @@ class Vector2D:
|
|
|
140
141
|
...
|
|
141
142
|
|
|
142
143
|
@property
|
|
143
|
-
def angle(self:"Vector2D") -> int|float:
|
|
144
|
+
def angle(self:"Vector2D") -> int|float:
|
|
145
|
+
"""
|
|
146
|
+
# Vector Angle
|
|
147
|
+
## Returns:
|
|
148
|
+
float: The angle (in radians) of the vector from the positive x-axis.
|
|
149
|
+
## Example:
|
|
150
|
+
v = Vector2D(1, 1)
|
|
151
|
+
angle = v.angle
|
|
152
|
+
print(angle) # Output: 0.7853981633974483
|
|
153
|
+
## Explanation:
|
|
154
|
+
This property calculates the angle of the vector from the positive x-axis using the `atan2` function.
|
|
155
|
+
"""
|
|
156
|
+
...
|
|
144
157
|
|
|
145
158
|
@angle.setter
|
|
146
|
-
def angle(self:"Vector2D", argv) -> None:
|
|
159
|
+
def angle(self:"Vector2D", argv) -> None:
|
|
160
|
+
...
|
|
161
|
+
|
|
162
|
+
@property
|
|
163
|
+
def aspect_x(self: "Vector2D") -> float:
|
|
164
|
+
"""
|
|
165
|
+
# Aspect Ratio (X over Y)
|
|
166
|
+
## Returns:
|
|
167
|
+
float: The aspect ratio of the vector, calculated as the x component divided by the y component. Returns 0 if the y component is zero.
|
|
168
|
+
## Example:
|
|
169
|
+
v = Vector2D(4, 2)
|
|
170
|
+
aspect = v.aspect_x
|
|
171
|
+
print(aspect) # Output: 2.0
|
|
172
|
+
## Explanation:
|
|
173
|
+
This property computes the ratio of the x component to the y component of the vector. If the y component is zero, it returns 0 to avoid division by zero.
|
|
174
|
+
"""
|
|
175
|
+
...
|
|
176
|
+
|
|
177
|
+
@aspect_x.setter
|
|
178
|
+
def aspect_x(self: "Vector2D", new_aspect) -> None: ...
|
|
179
|
+
|
|
180
|
+
@property
|
|
181
|
+
def aspect_y(self: "Vector2D") -> float:
|
|
182
|
+
"""
|
|
183
|
+
# Aspect Ratio (Y over X)
|
|
184
|
+
## Returns:
|
|
185
|
+
float: The aspect ratio of the vector, calculated as the y component divided by the x component. Returns 0 if the x component is zero.
|
|
186
|
+
## Example:
|
|
187
|
+
v = Vector2D(2, 4)
|
|
188
|
+
aspect = v.aspect_y
|
|
189
|
+
print(aspect) # Output: 2.0
|
|
190
|
+
## Explanation:
|
|
191
|
+
This property computes the ratio of the y component to the x component of the vector. If the x component is zero, it returns 0 to avoid division by zero.
|
|
192
|
+
"""
|
|
193
|
+
...
|
|
194
|
+
|
|
195
|
+
@aspect_y.setter
|
|
196
|
+
def aspect_y(self: "Vector2D", new_aspect) -> None: ...
|
|
147
197
|
|
|
148
198
|
@property
|
|
149
199
|
def copy(self:"Vector2D") -> "Vector2D":
|
|
@@ -211,8 +261,56 @@ class Vector2D:
|
|
|
211
261
|
"""
|
|
212
262
|
...
|
|
213
263
|
|
|
264
|
+
def clamp(self, min_val: Vector2D, max_val: Vector2D) -> "Vector2D":
|
|
265
|
+
"""
|
|
266
|
+
# Clamp the vector's components between the corresponding components of two other vectors.
|
|
267
|
+
|
|
268
|
+
## Parameters:
|
|
269
|
+
min_val (Vector2D): The minimum vector for clamping.
|
|
270
|
+
max_val (Vector2D): The maximum vector for clamping.
|
|
271
|
+
|
|
272
|
+
## Returns:
|
|
273
|
+
Vector2D: A new vector with its components clamped between the corresponding components of `min_val` and `max_val`.
|
|
274
|
+
|
|
275
|
+
## Example:
|
|
276
|
+
v = Vector2D(5, 10)
|
|
277
|
+
min_val = Vector2D(0, 8)
|
|
278
|
+
max_val = Vector2D(6, 12)
|
|
279
|
+
clamped_v = v.clamp(min_val, max_val)
|
|
280
|
+
print(clamped_v) # Output: (5, 10)
|
|
281
|
+
|
|
282
|
+
## Explanation:
|
|
283
|
+
This method clamps the x and y components of the current vector between the corresponding x and y components
|
|
284
|
+
of the `min_val` and `max_val` vectors. The resulting vector is returned as a new Vector2D instance.
|
|
285
|
+
"""
|
|
286
|
+
...
|
|
287
|
+
|
|
288
|
+
def iclamp(self, min_val: Vector2D, max_val: Vector2D) -> None:
|
|
289
|
+
"""
|
|
290
|
+
# Clamp the vector's components in place between the corresponding components of two other vectors.
|
|
291
|
+
|
|
292
|
+
## Parameters:
|
|
293
|
+
min_val (Vector2D): The minimum vector for clamping.
|
|
294
|
+
max_val (Vector2D): The maximum vector for clamping.
|
|
295
|
+
|
|
296
|
+
## Returns:
|
|
297
|
+
None
|
|
298
|
+
|
|
299
|
+
## Example:
|
|
300
|
+
v = Vector2D(5, 10)
|
|
301
|
+
min_val = Vector2D(0, 8)
|
|
302
|
+
max_val = Vector2D(6, 12)
|
|
303
|
+
v.iclamp(min_val, max_val)
|
|
304
|
+
print(v) # Output: (5, 10)
|
|
305
|
+
|
|
306
|
+
## Explanation:
|
|
307
|
+
This method clamps the x and y components of the current vector in place between the corresponding x and y components
|
|
308
|
+
of the `min_val` and `max_val` vectors. The method modifies the current vector directly.
|
|
309
|
+
"""
|
|
310
|
+
...
|
|
311
|
+
|
|
214
312
|
@property
|
|
215
|
-
def
|
|
313
|
+
def normalized(self:"Vector2D") -> "Vector2D":
|
|
216
314
|
"""
|
|
217
315
|
# Vector Normalization
|
|
218
316
|
|
|
@@ -224,7 +322,7 @@ class Vector2D:
|
|
|
224
322
|
|
|
225
323
|
## Example:
|
|
226
324
|
v = Vector2D(3, 4)
|
|
227
|
-
normalized_v = v.
|
|
325
|
+
normalized_v = v.normalized() # Normalize the vector (3, 4)
|
|
228
326
|
print(normalized_v) # Output: (0.6, 0.8)
|
|
229
327
|
|
|
230
328
|
## Explanation:
|
|
@@ -244,23 +342,123 @@ class Vector2D:
|
|
|
244
342
|
|
|
245
343
|
@property
|
|
246
344
|
def length(self:"Vector2D") -> float:
|
|
345
|
+
"""
|
|
346
|
+
# Vector Length
|
|
347
|
+
|
|
348
|
+
## Returns:
|
|
349
|
+
float: The length (magnitude) of the vector.
|
|
350
|
+
|
|
351
|
+
## Example:
|
|
352
|
+
v = Vector2D(3, 4)
|
|
353
|
+
length = v.length
|
|
354
|
+
print(length) # Output: 5.0
|
|
355
|
+
|
|
356
|
+
## Explanation:
|
|
357
|
+
This property calculates the length (magnitude) of the vector using the Pythagorean theorem.
|
|
358
|
+
"""
|
|
247
359
|
...
|
|
248
360
|
|
|
249
361
|
@property
|
|
250
362
|
def length_sqrd(self:"Vector2D") -> float:
|
|
363
|
+
"""
|
|
364
|
+
# Vector Length Squared
|
|
365
|
+
|
|
366
|
+
## Returns:
|
|
367
|
+
float: The squared length (magnitude) of the vector.
|
|
368
|
+
|
|
369
|
+
## Example:
|
|
370
|
+
v = Vector2D(3, 4)
|
|
371
|
+
length_sqrd = v.length_sqrd
|
|
372
|
+
print(length_sqrd) # Output: 25
|
|
373
|
+
|
|
374
|
+
## Explanation:
|
|
375
|
+
This property calculates the squared length (magnitude) of the vector.
|
|
376
|
+
It is more efficient than calculating the actual length, as it avoids the
|
|
377
|
+
square root calculation.
|
|
378
|
+
"""
|
|
251
379
|
...
|
|
252
380
|
|
|
253
381
|
@property
|
|
254
382
|
def inverse(self:"Vector2D") -> "Vector2D":
|
|
383
|
+
"""
|
|
384
|
+
# Vector Inversion
|
|
385
|
+
|
|
386
|
+
## Returns:
|
|
387
|
+
Vector2D: A new vector with inverted components.
|
|
388
|
+
|
|
389
|
+
## Example:
|
|
390
|
+
v = Vector2D(3, 4)
|
|
391
|
+
inverted_v = v.inverse()
|
|
392
|
+
print(inverted_v) # Output: (-3, -4)
|
|
393
|
+
|
|
394
|
+
## Explanation:
|
|
395
|
+
This method calculates the inverted version of the current vector, which means a new vector with the same magnitude
|
|
396
|
+
but opposite direction.
|
|
397
|
+
|
|
398
|
+
The inverted vector is obtained by negating each component of the current vector.
|
|
399
|
+
|
|
400
|
+
The resulting inverted vector is returned.
|
|
401
|
+
"""
|
|
255
402
|
...
|
|
256
403
|
|
|
257
404
|
def floor(self:"Vector2D", n:"int|float|Vector2D"=1) -> "Vector2D":
|
|
405
|
+
"""
|
|
406
|
+
# Round the Vector2D components down to the nearest integer or specified decimal place.
|
|
407
|
+
|
|
408
|
+
## Parameters:
|
|
409
|
+
n (int|float|Vector2D, optional): The decimal place to round down to. Default is 1.
|
|
410
|
+
|
|
411
|
+
## Returns:
|
|
412
|
+
Vector2D: A new vector with rounded-down components.
|
|
413
|
+
|
|
414
|
+
## Example:
|
|
415
|
+
v = Vector2D(3.14159, 2.71828)
|
|
416
|
+
rounded_v = v.floor(2)
|
|
417
|
+
print(rounded_v) # Output: (3.14, 2.71)
|
|
418
|
+
|
|
419
|
+
## Explanation:
|
|
420
|
+
This method rounds each component of the vector down to the nearest integer or specified decimal place.
|
|
421
|
+
"""
|
|
258
422
|
...
|
|
259
423
|
|
|
260
424
|
def ceil(self:"Vector2D", n:"int|float|Vector2D"=1) -> "Vector2D":
|
|
425
|
+
"""
|
|
426
|
+
# Round the Vector2D components up to the nearest integer or specified decimal place.
|
|
427
|
+
|
|
428
|
+
## Parameters:
|
|
429
|
+
n (int|float|Vector2D, optional): The decimal place to round up to. Default is 1.
|
|
430
|
+
|
|
431
|
+
## Returns:
|
|
432
|
+
Vector2D: A new vector with rounded-up components.
|
|
433
|
+
|
|
434
|
+
## Example:
|
|
435
|
+
v = Vector2D(3.14159, 2.71828)
|
|
436
|
+
rounded_v = v.ceil(2)
|
|
437
|
+
print(rounded_v) # Output: (3.15, 2.72)
|
|
438
|
+
|
|
439
|
+
## Explanation:
|
|
440
|
+
This method rounds each component of the vector up to the nearest integer or specified decimal place.
|
|
441
|
+
"""
|
|
261
442
|
...
|
|
262
443
|
|
|
263
444
|
def round(self:"Vector2D", n:"int|float|Vector2D"=1) -> "Vector2D":
|
|
445
|
+
"""
|
|
446
|
+
# Round the Vector2D components to the nearest integer or specified decimal place.
|
|
447
|
+
|
|
448
|
+
## Parameters:
|
|
449
|
+
n (int|float|Vector2D, optional): The decimal place to round to. Default is 1.
|
|
450
|
+
|
|
451
|
+
## Returns:
|
|
452
|
+
Vector2D: A new vector with rounded components.
|
|
453
|
+
|
|
454
|
+
## Example:
|
|
455
|
+
v = Vector2D(3.14159, 2.71828)
|
|
456
|
+
rounded_v = v.round(2)
|
|
457
|
+
print(rounded_v) # Output: (3.14, 2.72)
|
|
458
|
+
|
|
459
|
+
## Explanation:
|
|
460
|
+
This method rounds each component of the vector to the nearest integer or specified decimal place.
|
|
461
|
+
"""
|
|
264
462
|
...
|
|
265
463
|
|
|
266
464
|
@classmethod
|
|
@@ -451,7 +649,65 @@ class Vector2D:
|
|
|
451
649
|
def cartesian_to_complex(self:"Vector2D") -> complex: ...
|
|
452
650
|
|
|
453
651
|
@classmethod
|
|
454
|
-
def complex_to_cartesian(cls, complex_n: complex) -> "Vector2D":
|
|
652
|
+
def complex_to_cartesian(cls, complex_n: complex) -> "Vector2D":
|
|
653
|
+
"""
|
|
654
|
+
# Convert a Complex Number to Cartesian Coordinates
|
|
655
|
+
|
|
656
|
+
## Parameters:
|
|
657
|
+
complex_n (complex): The complex number to convert.
|
|
658
|
+
|
|
659
|
+
## Returns:
|
|
660
|
+
Vector2D: The corresponding (x, y) coordinates as a Vector2D.
|
|
661
|
+
|
|
662
|
+
## Example:
|
|
663
|
+
v = Vector2D.complex_to_cartesian(3 + 4j) # v = Vector2D(3, 4)
|
|
664
|
+
|
|
665
|
+
## Explanation:
|
|
666
|
+
This class method converts a complex number (a + bi) to Cartesian coordinates (x, y).
|
|
667
|
+
The real part 'a' becomes the x-coordinate, and the imaginary part 'b' becomes the y-coordinate.
|
|
668
|
+
"""
|
|
669
|
+
...
|
|
670
|
+
|
|
671
|
+
def cartesian_to_linear(self:"Vector2D", size:int|float) -> int:
|
|
672
|
+
"""
|
|
673
|
+
# Convert 2D Cartesian coordinates to a linear index.
|
|
674
|
+
|
|
675
|
+
## Parameters:
|
|
676
|
+
size (int|float): The width of the grid (number of columns).
|
|
677
|
+
|
|
678
|
+
## Returns:
|
|
679
|
+
int: The linear index corresponding to the (x, y) coordinates.
|
|
680
|
+
|
|
681
|
+
## Example:
|
|
682
|
+
v = Vector2D(3, 2)
|
|
683
|
+
idx = v.cartesian_to_linear(5) # idx = 3 + 2*5 = 13
|
|
684
|
+
|
|
685
|
+
## Explanation:
|
|
686
|
+
This method converts the (x, y) coordinates of the vector to a single linear index,
|
|
687
|
+
assuming row-major order in a 2D grid of the given width.
|
|
688
|
+
"""
|
|
689
|
+
...
|
|
690
|
+
|
|
691
|
+
@classmethod
|
|
692
|
+
def linear_to_cartesian(cls, linear:int, size:int|float) -> "Vector2D":
|
|
693
|
+
"""
|
|
694
|
+
# Convert a linear index to 2D Cartesian coordinates.
|
|
695
|
+
|
|
696
|
+
## Parameters:
|
|
697
|
+
linear (int): The linear index.
|
|
698
|
+
size (int|float): The width of the grid (number of columns).
|
|
699
|
+
|
|
700
|
+
## Returns:
|
|
701
|
+
Vector2D: The corresponding (x, y) coordinates as a Vector2D.
|
|
702
|
+
|
|
703
|
+
## Example:
|
|
704
|
+
v = Vector2D.linear_to_cartesian(13, 5) # v = Vector2D(3, 2)
|
|
705
|
+
|
|
706
|
+
## Explanation:
|
|
707
|
+
This class method converts a linear index to (x, y) coordinates,
|
|
708
|
+
assuming row-major order in a 2D grid of the given width.
|
|
709
|
+
"""
|
|
710
|
+
...
|
|
455
711
|
|
|
456
712
|
def lerp(self:"Vector2D", other:"int|float|Vector2D|list|tuple", t:float=.1) -> "Vector2D":
|
|
457
713
|
"""
|
|
@@ -1046,4 +1302,37 @@ def distance_line_point(line_point_a:Vector2D, line_point_b:Vector2D, point_c:Ve
|
|
|
1046
1302
|
...
|
|
1047
1303
|
|
|
1048
1304
|
def optimize_value_string(value: int|float, precision: int) -> str:
|
|
1305
|
+
"""
|
|
1306
|
+
# Optimize the string representation of a numeric value based on its magnitude and the specified precision.
|
|
1307
|
+
|
|
1308
|
+
## Parameters:
|
|
1309
|
+
value (int | float): The numeric value to be formatted.
|
|
1310
|
+
precision (int): The number of decimal places or significant digits to use in the formatted string.
|
|
1311
|
+
|
|
1312
|
+
## Returns:
|
|
1313
|
+
str: The optimized string representation of the value.
|
|
1314
|
+
|
|
1315
|
+
## Example:
|
|
1316
|
+
value = 0.000012345
|
|
1317
|
+
precision = 3
|
|
1318
|
+
result = optimize_value_string(value, precision)
|
|
1319
|
+
print(result)
|
|
1320
|
+
# Output: '1.235e-05'
|
|
1321
|
+
|
|
1322
|
+
value = 123.456789
|
|
1323
|
+
precision = 2
|
|
1324
|
+
result = optimize_value_string(value, precision)
|
|
1325
|
+
print(result)
|
|
1326
|
+
# Output: '123.46'
|
|
1327
|
+
|
|
1328
|
+
## Explanation:
|
|
1329
|
+
The function formats the input value as a string, choosing between fixed-point and scientific notation
|
|
1330
|
+
based on the magnitude of the value relative to the specified precision:
|
|
1331
|
+
- If the absolute value is very small (less than 1 divided by 10 to the power of precision, but not zero),
|
|
1332
|
+
scientific notation is used.
|
|
1333
|
+
- If the absolute value is less than 10 to the power of precision, fixed-point notation is used,
|
|
1334
|
+
with trailing zeros and decimal points removed for brevity.
|
|
1335
|
+
- Otherwise, scientific notation is used.
|
|
1336
|
+
This ensures that the string representation is concise and readable, while maintaining the requested precision.
|
|
1337
|
+
"""
|
|
1049
1338
|
...
|