-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.py
77 lines (62 loc) · 2.24 KB
/
utils.py
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
"""
Utilitaire commun pour diverses opérations
"""
from math import cos, sin, pi
from CONSTS import coordinate
def get_circle(density: int, center: coordinate, radius: float) -> list[coordinate]:
"""
Renvoie une liste de coordonée en forme de cercle,
en renvoie selon la densité demandée
:param density: Nombre de points renvoyé
:param center: Centre du cercle (coordonnée)
:param radius: Rayon du cercle
:return: Liste de coordonnée
"""
angles = [(2 * k * pi) / density for k in range(density)]
return list(zip([round(center[0] + int(radius * cos(angle)), 4) for angle in angles],
[round(center[1] + int(radius * sin(angle)), 4) for angle in angles]))
def get_full_line(ptA: coordinate, ptB: coordinate, strict_order: bool = False) -> list[coordinate]:
"""
Get a full line with all coordinates between ptA and ptB
:param ptA: Point A
:param ptB: Point B
:return: List of all points between
"""
# Use the bresenham algorithm
# Reference : https://fr.wikipedia.org/wiki/Algorithme_de_trac%C3%A9_de_segment_de_Bresenham
# Reference : https://babavoss.pythonanywhere.com/python/bresenham-line-drawing-algorithm-implemented-in-py
# Fit the input into the algorithm:
if (invert_points := ptA[0] > ptB[0]):
ptA, ptB = ptB, ptA
# print(ptA, ptB)
dx = ptB[0] - ptA[0]
dy = abs(ptB[1] - ptA[1])
if dx < dy:
dy, dx = dx, dy
invert_x_y = True
ptA = (ptA[1], ptA[0])
ptB = (ptB[1], ptB[0])
else:
invert_x_y = False
# Bresenham algorithm
x, y = ptA
pente = 2 * dy - dx
line = [(x, y)]
for k in range(2, dx + 2):
if pente > 0:
y = y + 1 if y < ptB[1] else y - 1
pente = pente + 2 * (dy - dx)
else:
pente = pente + 2 * dy
x = x + 1 if x < ptB[0] else x - 1
line.append((x, y))
# Correct inversion
if invert_x_y:
for i in range(len(line)):
line[i] = (line[i][1], line[i][0])
if strict_order and invert_points:
anti = []
for coo in line:
anti.insert(0, coo)
return anti
return line