G. Классный прямоугольник 3.0

Необходимо ещё немного доработать предыдущую задачу.

Разработайте методы:

  • turn() — поворачивает прямоугольник на 90° по часовой стрелке вокруг его центра;
  • scale(factor) — изменяет размер в указанное количество раз, тоже относительно центра.

Все вычисления производить с округлением до сотых.

Примечание

Ваше решение должно содержать только классы и функции.
В решении не должно быть вызовов инициализации требуемых классов.
Все результаты вычислений нужно округлить до сотых.

Пример

Ввод

rect = Rectangle((3.14, 2.71), (-3.14, -2.71))
print(rect.get_pos(), rect.get_size(), sep='\n')
rect.turn()
print(rect.get_pos(), rect.get_size(), sep='\n')

Вывод

(-3.14, 2.71)
(6.28, 5.42)
(-2.71, 3.14)
(5.42, 6.28)

Ввод

rect = Rectangle((3.14, 2.71), (-3.14, -2.71))
print(rect.get_pos(), rect.get_size(), sep='\n')
rect.scale(2.0)
print(rect.get_pos(), rect.get_size(), sep='\n')

Вывод

(-3.14, 2.71)
(6.28, 5.42)
(-6.28, 5.42)
(12.56, 10.84)

Решение

Продолжение задач про прямоугольник. Приведу лишь решение для класса, описанного через точку и ширину/высоту. Если интересно, почему и как работают методы изменения размера и поворота, приглашаю попробовать нарисовать их на бумаге и на картинке прописать где какие данные используются. Это будет прекрасная тренировка на то, как можно решать задачи альтернативными от классических формул методами. Зачастую такой путь бывает более простым и коротким, но очень важно следить, чтобы он оставался математически и логически безупречным, иначе можно породить алгоритм, который будет будет содержать ошибку и который будет очень сложно отладить в силу его кажущейся очевидности.

Посмотреть код

Решение

Python
class Point:
    def __init__(self, x, y) -> None:
        self.x = round(x, 2)
        self.y = round(y, 2)

    def round(self):
        self.x = round(self.x, 2)
        self.y = round(self.y, 2)
        return self


class Rectangle:
    def __init__(self, corner1, corner2) -> None:
        self.corner = Point(min(corner1[0], corner2[0]), max(corner1[1], corner2[1]))  # noqa
        self.width = round(max(corner1[0], corner2[0]) - self.corner.x, 2)
        self.height = round(self.corner.y - min(corner1[1], corner2[1]), 2)

    def perimeter(self):
        return round((self.width + self.height) * 2, 2)

    def area(self):
        return round(self.width * self.height, 2)

    def get_pos(self):
        return self.corner.x, self.corner.y

    def get_size(self):
        return self.width, self.height

    def move(self, dx, dy):
        self.corner.x += dx
        self.corner.y += dy
        self.corner.round()

    def resize(self, width, height):
        self.width = round(width, 2)
        self.height = round(height, 2)

    def turn(self):
        delta = round((self.width - self.height) / 2, 2)
        self.move(delta, delta)
        self.height, self.width = self.width, self.height

    def scale(self, ratio):
        dx = round((self.width * (ratio - 1)), 2)
        dy = round((self.height * (ratio - 1)), 2)
        self.move(-dx / 2, dy / 2)
        self.resize(self.width * ratio, self.height * ratio)
Подписаться
Уведомить о
guest
7 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии