Содержание

Картинки и анимация

На предыдущих занятиях мы разобрали библиотеку, которая позволяла работать с графиками. Однако, основная ее функциональность сосредоточена на разного вида диаграммах. Сегодня разберемся с модулем, который нам дает возможность рисовать как заблагорассудится. Для Питона есть множество библиотек для работы с графикой (как обычно), мы рассмотрим сегодня самую простую из них: graphics.py.

Начнем с простого примера. Если он вдруг не заработает сразу, то выполните у себя в терминале

pip3 install --user graphics.py
from graphics import *
import time
 
 
# наша рисующая функция
def gr():
    winWidth = 800
    winHeight = 600
    # Создадим окно с заголовком "Шарик" и размером 800 на 600 пикселей
    win = GraphWin("Шарик", winWidth, winHeight)
 
    # В координаты 50, 50 поместим окружность радиусом 10
    c = Circle(Point(50, 50), 10)
 
    # В координаты 50, 50 напишем текст
    e = Text(Point(200, 100),
             "Не то, чтобы совсем не попал, но только не попал в шарик!")
    # нарисуем шарик в окне win
    c.draw(win)
    # нарисуем текст в окне win
    e.draw(win)
 
    # запустим цикл, который будет ждать нажатия мышью
    while (True):
        # подождем, пока кто-нибудь не кликнет мышкой в окне
        clickPoint = win.getMouse()
 
        # напечатаем на экран координаты точки клика
        print(clickPoint)
 
        # если лопнули шарик
        if c.getP1().getX() < clickPoint.getX() < c.getP2().getX() and c.getP1().getY() < clickPoint.getY() < c.getP2().getY():
            # то удалим шарик с экрана
            c.undraw()
            # изменим текст
            e.setText("Пух!")
            # подождем 2 секунды
            time.sleep(2)
            # и прервем выполнение цикла
            break
    # и закроем графическое окно
    win.close()
 
# запустим функцию
gr()

Функции GraphWin

GraphWin это графическое окно, которое умеет следующее:

Графические элементы

graphics.py хранит в себе реализацию стандартных графических примитивов (точка, линия, окружность и т.д.) в виде типов данных Point, Line, Circle, Oval, Rectangle, Polygon, Text. Для каждого типа данных можно установить следующие свойства:

Точка

Самый простой тип данных. Хранит в себе просто две координаты на экране.

Линия

Окружность

Прямоугольник

Овал

Сегмент

К сожалению, библиотека не содержит в себе встроенной функции для отрисовки сегмента окружности или овала. Однако, это питон и никто не мешает нам дописать необходимую функциональность.

Добавим в начало программы следующий код:

class Arc(Oval):        
 
    def __init__(self, p1, p2,start, extent):
        self.extent = extent
        self.start = start
        super().__init__(p1, p2)
 
    def __repr__(self):
        return "Arc({}, {}, {})".format(str(self.p1), str(self.p2), self.extent)
 
    def clone(self):
        other = Arc(self.p1, self.p2, self.start, self.extent)
        other.config = self.config.copy()
        return other
 
    def _draw(self, canvas, options):
        p1 = self.p1
        p2 = self.p2
        x1, y1 = canvas.toScreen(p1.x, p1.y)
        x2, y2 = canvas.toScreen(p2.x, p2.y)
        options['style'] = tk.PIESLICE
        options['extent'] = self.extent
        options['start'] = self.start
        return canvas.create_arc(x1, y1, x2, y2, options)

Теперь в нашей программе появилась возможность рисовать сегменты окружности, например:

arc = Arc(Point(50, 50), Point(100, 100), 45, 270)
arc.setFill("yellow")
arc.draw(win)

Многоугольник

Текст

Обновление экрана

По умолчанию, библиотека graphics.py обновляет экран при отрисовке каждого элемента. Обновление экрана операция дорогая по времени, поэтому иногда (например, когда на экране мнго объектов) нужно эту функцию автообновления отключить.

Для этого: 1. При инициализации графического окна нужно добавить параметр autoflush=False. 2. В цикле отрисовки нужно добавить явный вызов функции обновления окна, указав в качестве аргумента частоту кадров, с которой следует обновлять окно

win = GraphWin("Update Example", 320, 200, autoflush=False)
for i in range(1000):
    # <Все что рисуется на экране>
    update(30)

Работа с цветами

В этой библиотеке цвет можно описать двумя способами: текстовым значением и прямым указанием цветовых компонент. В первом случае, цвет задается своим названием, например «red». Помимо этого, есть определенный выбор оттенков, например «red1», «red2»,«red3», «red4». По мере увеличения номера, оттенок становится более темным. На картинке перечислены все возможные значения цветов:

Во втором случае, цвета задаются с помощью функции color_rgb(r, g, b). Ее аргументами являются числовые значения цветовых компонент: красной, зеленой и синей. Значения каждой от 0 до 255. Например aCircle.setFill(color rgb(130, 0, 130)) задаст цвет заливки окружности чуть светлее, чем darkmagenta из предыдущей таблицы.

Задачи

Задание 18

Написать программу, которая рисует на экране точки, расположенные на окружности. Координаты точек требуется вычислять в полярной системе координат.

https://nsunc.com/moodle/mod/assign/view.php?id=656

Задание 19

Модифицировать предыдущую программу так, чтобы точки располагались по спирали

https://nsunc.com/moodle/mod/assign/view.php?id=657

Задание 20

Модифицировать прогрмму из задания 18 так, чтобы:

  1. Вместо точек рисовались окружности
  2. Когда рисуется следующая окружность, предыдущая должна удаляться

https://nsunc.com/moodle/mod/assign/view.php?id=658

Задание 21 (планеты со спутниками)

Добавить еще одну точку для вращения, которая будет двигаться вместе с окружностью. Запустить вокруг нее еще одну окружность. В центре разместить Солнце

https://nsunc.com/moodle/mod/assign/view.php?id=659

Задание 22

Написать программу, в которой N точек двигались бы по одной окружности

https://nsunc.com/moodle/mod/assign/view.php?id=660

Задание 23

Модифицировать программу так, чтобы точки были соединены линиями

https://nsunc.com/moodle/mod/assign/view.php?id=661

Задание 24

Модифицировать предыдущую программу так, чтобы вышла иллюзия вращающейся пирамидки

https://nsunc.com/moodle/mod/assign/view.php?id=662