мета-данные страницы
  •  
Загрузка не удалась. Возможно, проблемы с правами доступа?

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слеваПредыдущая версия
Следующая версия
Предыдущая версия
python:week15 [26/04/2017 05:51] – [Картинки и анимация] ybezrukovpython:week15 [16/03/2018 11:39] (текущий) – [Сегмент] ybezrukov
Строка 3: Строка 3:
 На предыдущих занятиях мы разобрали библиотеку, которая позволяла работать с графиками. Однако, основная ее функциональность сосредоточена на разного вида диаграммах. Сегодня разберемся с модулем, который нам дает возможность рисовать как заблагорассудится. Для Питона есть множество библиотек для работы с графикой (как обычно), мы рассмотрим сегодня самую простую из них: ''graphics.py'' На предыдущих занятиях мы разобрали библиотеку, которая позволяла работать с графиками. Однако, основная ее функциональность сосредоточена на разного вида диаграммах. Сегодня разберемся с модулем, который нам дает возможность рисовать как заблагорассудится. Для Питона есть множество библиотек для работы с графикой (как обычно), мы рассмотрим сегодня самую простую из них: ''graphics.py''
  
-Начнем с простого примера. Если он вдруг не заработает сразу, то выполните у себя в терминале ''pip3 install --user graphics.py''+Начнем с простого примера. Если он вдруг не заработает сразу, то выполните у себя в терминале  
 + 
 +<code> 
 +pip3 install --user graphics.py 
 +</code>
  
 <code python> <code python>
 from graphics import * from graphics import *
 +import time
  
-def gr(): # наша рисующая функция+ 
 +# наша рисующая функция 
 +def gr():
     winWidth = 800     winWidth = 800
     winHeight = 600     winHeight = 600
-    win = GraphWin("Шарик", winWidth, winHeight) # Создадим окно с заголовком "Шарик" и размером 800 на 600 пикселей +    # Создадим окно с заголовком "Шарик" и размером 800 на 600 пикселей 
-    Circle(Point(50,50)10# В координаты 50, 50 поместим окружность радиусом 10+    win GraphWin("Шарик"winWidthwinHeight)
  
-    e = Text(Point(200, 100), "Не то, чтобы совсем не попал, но только не попал в шарик!"# В координаты 50, 50 напишем текст +    # В координаты 50, 50 поместим окружность радиусом 10 
-    c.draw(win) # нарисуем шарик в окне win +    c = Circle(Point(50, 50), 10) 
-    e.draw(win) # нарисуем текст в окне win + 
-     +    # В координаты 50, 50 напишем текст 
-    while (True# запустим цикл, который будет ждать нажатия мышью +    e = Text(Point(200, 100), 
-        clickPoint = win.getMouse() # подождем, пока кто-нибудь не кликнет мышкой в окне +             "Не то, чтобы совсем не попал, но только не попал в шарик!"
-        print(clickPoint) # напечатаем на экран координаты точки клика +    # нарисуем шарик в окне win 
-        if (clickPoint.getX() < winWidth / 2): +    c.draw(win) 
-            break и если кликнули в левой части экранато прервем выполнение цикла+    # нарисуем текст в окне 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()  
  
-    win.close() # и закроем графическое окно 
-     
-gr() # запустим функцию  
  
 </code> </code>
Строка 42: Строка 71:
   * ''getKey()'' - приостанавливает выполнение программы и ожидает пока нажмут кнопку на клавиатуре. Возвращает строчку, в которой хранится нажатая клавиша. Например: keyString = win.getKey()   * ''getKey()'' - приостанавливает выполнение программы и ожидает пока нажмут кнопку на клавиатуре. Возвращает строчку, в которой хранится нажатая клавиша. Например: keyString = win.getKey()
   * ''checkKey()''- аналогично checkMouse, но для клавиатуры. В отличие от checkMouse, если клавиша нажата не была, то возвращает пустую строку.   * ''checkKey()''- аналогично checkMouse, но для клавиатуры. В отличие от checkMouse, если клавиша нажата не была, то возвращает пустую строку.
 +  * ''getWidth()'' - возвращает значение ширины графического окна в пикселях 
 +  * ''getHeight()'' - возвращает значение высоты графического окна в пикселях
 ====== Графические элементы ====== ====== Графические элементы ======
  
Строка 85: Строка 115:
   * ''getP1(), getP2()'' - возвращает соответственно, координаты левого нижнего и правого верхнего углов прямоугольника, в который вписан овал.   * ''getP1(), getP2()'' - возвращает соответственно, координаты левого нижнего и правого верхнего углов прямоугольника, в который вписан овал.
  
 +
 +===== Сегмент =====
 +
 +К сожалению, библиотека не содержит в себе встроенной функции для отрисовки сегмента окружности или овала. Однако, это питон и никто не мешает нам дописать необходимую функциональность.
 +
 +Добавим в начало программы следующий код:
 +
 +<code python>
 +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)
 +</code>
 +
 +Теперь в нашей программе появилась возможность рисовать сегменты окружности, например:
 +
 +<code python>
 +arc = Arc(Point(50, 50), Point(100, 100), 45, 270)
 +arc.setFill("yellow")
 +arc.draw(win)
 +</code>
 +
 +  * Arc(point1, point2, start_angle, segemnt_angle) - создает сегмент овала, который вписан в прямоугольник с заданными левым нижним и правым верхним углами. start_angle - начальный угол с которого начинает рисоваться сегмент, segment_angle - угол закрашенного участка.
 +  * getCenter() - возвращает координаты центра овала.
 +  * getP1(), getP2() - возвращает соответственно, координаты левого нижнего и правого верхнего углов прямоугольника, в который вписан овал.
 ===== Многоугольник ===== ===== Многоугольник =====
   * ''Polygon(point1, point2, point3, ...)'' - создает замкнутый многоугольник по заданному набору вершин. В качестве аргумента может быть и список. Например: ''aPolygon = Polygon(Point(1,2), Point(3,4), Point(5,6))'' или ''aPolygon = Polygon([Point(1,2), Point(3,4), Point(5,6)])''   * ''Polygon(point1, point2, point3, ...)'' - создает замкнутый многоугольник по заданному набору вершин. В качестве аргумента может быть и список. Например: ''aPolygon = Polygon(Point(1,2), Point(3,4), Point(5,6))'' или ''aPolygon = Polygon([Point(1,2), Point(3,4), Point(5,6)])''
Строка 98: Строка 173:
   * ''setStyle(style)'' - задает стиль шрифта. Возможные значения параметра: "normal", "bold", "italic", "bold italic".   * ''setStyle(style)'' - задает стиль шрифта. Возможные значения параметра: "normal", "bold", "italic", "bold italic".
   * ''setTextColor(color)'' - Задает цвет текста   * ''setTextColor(color)'' - Задает цвет текста
-==== Работа с цветами ====+ 
 +===== Обновление экрана ===== 
 + 
 +По умолчанию, библиотека graphics.py обновляет экран при отрисовке каждого элемента. Обновление экрана операция дорогая по времени, поэтому иногда (например, когда на экране мнго объектов) нужно эту функцию автообновления отключить. 
 + 
 +Для этого: 
 +1. При инициализации графического окна нужно добавить параметр ''autoflush=False''.  
 +2. В цикле отрисовки нужно добавить явный вызов функции обновления окна, указав в качестве аргумента частоту кадров, с которой следует обновлять окно 
 + 
 +<code python> 
 +win = GraphWin("Update Example", 320, 200, autoflush=False) 
 +for i in range(1000): 
 +    # <Все что рисуется на экране> 
 +    update(30) 
 +</code>     
 + 
 +===== Работа с цветами =====
  
 В этой библиотеке цвет можно описать двумя способами: текстовым значением и прямым указанием цветовых компонент. В первом случае, цвет задается своим названием, например "red". Помимо этого, есть определенный выбор оттенков, например "red1", "red2","red3", "red4". По мере увеличения номера, оттенок становится более темным. На картинке перечислены все возможные значения цветов: В этой библиотеке цвет можно описать двумя способами: текстовым значением и прямым указанием цветовых компонент. В первом случае, цвет задается своим названием, например "red". Помимо этого, есть определенный выбор оттенков, например "red1", "red2","red3", "red4". По мере увеличения номера, оттенок становится более темным. На картинке перечислены все возможные значения цветов:
Строка 105: Строка 196:
  
 Во втором случае, цвета задаются с помощью функции color_rgb(r, g, b). Ее аргументами являются числовые значения цветовых компонент: красной, зеленой и синей. Значения каждой от 0 до 255. Например aCircle.setFill(color rgb(130, 0, 130)) задаст цвет заливки окружности чуть светлее, чем darkmagenta из предыдущей таблицы. Во втором случае, цвета задаются с помощью функции color_rgb(r, g, b). Ее аргументами являются числовые значения цветовых компонент: красной, зеленой и синей. Значения каждой от 0 до 255. Например aCircle.setFill(color rgb(130, 0, 130)) задаст цвет заливки окружности чуть светлее, чем darkmagenta из предыдущей таблицы.
 +
 +
 +===== Задачи =====
 ==== Задание 18 ==== ==== Задание 18 ====
  
-Воспроизвести на Питоне программу с вращающейся пирамидкой из прошлого семестра+Написать программу, которая рисует на экране точки, расположенные на окружности. Координаты точек требуется вычислять в полярной системе координат. 
 + 
 +https://nsunc.com/moodle/mod/assign/view.php?id=656 
 + 
 +==== Задание 19 ==== 
 + 
 +Модифицировать предыдущую программу так, чтобы точки располагались по спирали 
 + 
 +https://nsunc.com/moodle/mod/assign/view.php?id=657 
 + 
 +==== Задание 20 ==== 
 + 
 +Модифицировать прогрмму из задания 18 так, чтобы: 
 + 
 +  - Вместо точек рисовались окружности 
 +  - Когда рисуется следующая окружность, предыдущая должна удаляться 
 + 
 +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