Почему появляется разрыв между начальной и конечной точкой круга?
Есть функция:
import simple_draw as sd
sd.set_screen_size(width=1600, height=800)
def polygon(x, y, angle_of_rotation, length, facets):
point = sd.get_point(x, y)
for _ in range(facets):
angle = 360 / facets
vektor = sd.get_vector(start_point=point, angle=angle_of_rotation, length=length, width=3)
vektor.draw()
angle_of_rotation += angle
point = vektor.end_point
polygon(400, 150, 0, 50, 20)
sd.pause()
Почему существует разрыв, между конечной точкой и начальной?

Ответы (1 шт):
Автор решения: insolor
→ Ссылка
Если посмотреть на класс Point из simple_draw, то можно увидеть там кучу ненужных приведений к целому, из-за которых при сложении нескольких векторов накапливается ошибка округления:
# Point support
class Point:
"""
Класс точки экрана
"""
def __init__(self, x=None, y=None):
self._x = random_number(1, resolution[0]) if x is None else int(x) # <--
self._y = random_number(1, resolution[1]) if y is None else int(y) # <--
def to_screen(self):
return int(self._x), resolution[1] - int(self._y)
@property
def x(self):
return self._x
@x.setter
def x(self, value):
self._x = int(value) # <--
@property
def y(self):
return self._y
@y.setter
def y(self, value):
self._y = int(value) # <--
def __str__(self):
return 'Point(x={}, y={})'.format(self.x, self.y)
Большая часть их не нужна, округление нужно только при приведении к экранным координатам (метод to_screen). Исправленный вариант:
# Point support
class Point:
"""
Класс точки экрана
"""
def __init__(self, x=None, y=None):
self._x = random_number(1, resolution[0]) if x is None else x
self._y = random_number(1, resolution[1]) if y is None else y
def to_screen(self):
return int(self._x), resolution[1] - int(self._y)
@property
def x(self):
return self._x
@x.setter
def x(self, value):
self._x = value
@property
def y(self):
return self._y
@y.setter
def y(self, value):
self._y = value
def __str__(self):
return 'Point(x={}, y={})'.format(self.x, self.y)
После исправления окружность почти замыкается:
Если еще заменить оставшиеся int на round (округление к ближайшему целому, а не к меньшему целому), то окружность замкнется практически идеально:
Пулл-реквест: https://github.com/suguby/simple_draw/pull/11

