§ 6. Составление алгоритмов для работы с графикой

6.1. Расчёты в графических построениях

Пример 6.1. Нарисовать прямоугольный треугольник, соответствующий рисунку (катеты параллельны осям координат). Длины катетов и координаты прямого угла вводятся.

Этапы выполнения задания.

I. Исходные данные: a и b (длины катетов), x и y (координаты вершины прямого угла).
II. Результат: изображение прямоугольного треугольника.
III. Алгоритм решения задачи:
1. Ввод исходных данных.
2. Рисование треугольника оформим в виде функции pr_tr. Параметрами функции будут координаты прямого угла, длины катетов и цвет заливки.
Чтобы изобразить треугольник, нужно выполнить следующие действия:
1) установить Черепаху в точку с координатами (x – a, y);
2) установить начало заливки;
3) нарисовать катет длиной а, повернуть Черепаху на 90° вправо и нарисовать катет длиной b;
4) установить конец заливки. При заливке конечная точка будет соединена с начальной.
IV. Описание переменных: все переменные — int.

Многие графические построения можно обобщить, если предположить, что для фигуры будет задаваться её местоположение и размер. При описании соответствующей функции рисования фигуры эти значения будут параметрами функции. Дополнительно можно использовать параметры для цвета фигуры (контур и/или заливка).

Пример 6.2. Нарисовать в графическом окне звезду. Описать функцию star, параметрами которой являются количество лучей, координаты одного из лучей (начало рисования звезды) и длина отрезка, являющегося стороной звезды.

Этапы выполнения задания.

I. Исходные данные: n — количество вершин, x и y — координаты начальной вершины, d — длина стороны.
II. Результат: изображение звезды.
III. Алгоритм решения задачи:
1. Ввод исходных данных.
2. Для того чтобы построить звезду, нужно выполнить следующие действия:
1) установить Черепаху в начальную точку;
2) нарисовать линию и повернуть Черепаху;
3) пункт 2) выполнять n раз. Так как количество повторений известно, воспользуемся циклом for;
4) для звезды с нечётным количеством лучей (классическая звезда) угол поворота рассчитывается по формуле 180 – 180 : n.
IV. Описание переменных: все переменные — int.

Если добавить заливку для нарисованной звезды, то заливаться может не вся нарисованная область, а отдельные части. Это связано с особенностью реализации алгоритма заливки.

Пример 6.3. Нарисовать в графическом окне правильный звёздчатый многоугольник без самопересечений. Описать функцию poly_star, параметрами которой являются количество лучей, координаты одного из лучей (начало рисования звезды) и длина отрезка, являющегося стороной звезды.

Этапы выполнения задания.

I. Исходные данные: x и y — координаты вершины, d — длина стороны.
II. Результат: изображение звёздчатого многоугольника.
III. Алгоритм решения задачи:
1. Ввод исходных данных.
2. Для того чтобы построить фигуру, нужно выполнить следующие действия:
1) установить Черепаху в начальную точку;
2) в примере 6.2 Черепаха всегда поворачивалась на один и тот же угол. Здесь потребуются два разных поворота: один определяет величину внутреннего угла луча звёздчатого многоугольника, а другой — внешнего;
3) величина поворота Черепахи для рисования внутреннего угла многоугольника: 180 – 360 // n, для рисования внешнего: 180 – 720 / n;
4) так как количество повторений известно, воспользуемся циклом for.
IV. Описание переменных: все переменные — int.

6.2. Использование случайных чисел

Случайные числа имеют широкое применение в программировании. Они используются в шифровании и моделировании. Многие компьютерные игры используют случайные числа. На основе случайных чисел генерируются капчи и пароли, реализуются различные лотереи.

В Python для работы со случайными числами нужно подключить библиотеку random. Функции библиотеки, которые генерируют случайные числа:

randint(a, b) — целое число, удовлетворяющее условию a ≤ x ≤ b;
randrange(a) — целое число, удовлетворяющее условию 0 ≤ x < a;
random() — рациональное число, удовлетворяющее условию 0 ≤ x < 1;
uniform(a, b) — рациональное число, удовлетворяющее условию a ≤ x ≤ b.

Пример 6.4. Написать программу для рисования на экране 10 разноцветных окружностей. Расположение окружностей, их радиусы определяются случайным образом.

Этапы выполнения задания.

I.  Исходные данные: результат работы программы не зависит от исходных данных.
II.  Результат: изображение десяти окружностей.
III.  Алгоритм решения задачи:
1.  Значения координат центра окружности определяются функцией randint в диапазоне от –100 до 100.
2.  Значение радиуса окружности определяется функцией randint в диапазоне от 5 до 70.
3.  Так как количество повторений известно, будем использовать цикл for.

IV.  Описание переменных: x, y (координаты центра), r (радиус) — имеют тип int.
*  Функция randrange может иметь один, два или три аргумента. Если указан только один аргумент, то она возвращает случайное число от 0 до указанного аргумента (не включая его).

Если указаны два аргумента, то функция работает аналогично randint за исключением того, что значение второго аргумента не входит в генерируемый диапазон. Если функции передают три аргумента, то первые два — это границы диапазона, как в случае с двумя аргументами, а третий — шаг. Если, например, функция вызывается как randrange(10, 20, 2), то случайное число будет выбираться из чётных чисел от 10 до 20: 10, 12, 14, 16, 18 (значение 20 не входит в генерируемый диапазон).

Пример 6.5. Нарисовать звёздное небо. Расположение, размеры и количество лучей у звёзд определяются случайным образом.

Этапы выполнения задания.

I.  Исходные данные отсутствуют.
II.  Результатом работы программы будет изображение 100 звёзд.
III.  Алгоритм решения задачи:
1.  Закрасим фон тёмным цветом.
2.  Для рисования одной звезды воспользуемся функцией star, описанной в примере 6.2.
3.  Значения параметров функции задаются случайным образом. Для того чтобы количество лучей у звезды было нечётным, воспользуемся функцией randrange с тремя параметрами: n = randrange(5, 12, 2). Число n принимает значения от 5 до 12 с шагом 2 и может быть одним из 5, 7, 9, 11.
4. Так как количество повторений известно, будем использовать цикл for.
IV. Описание переменных: все переменные — int.

6.3*. Построение сложных изображений

Пример 6.6. Заполнить графическое окно окружностями радиуса 10 пикселей.

Этапы выполнения задания.

I. Исходные данные отсутствуют.
II. Окружности должны заполнить всё графическое окно.
III. Алгоритм решения задачи:
1. Задача является обобщением примера 5.1. Команды нужно повторить для нескольких рядов окружностей. Количество рядов определяется высотой окна. Рисование одного ряда оформим как вспомогательный алгоритм row.
2. Положение любого ряда окружностей определяется координатой y. Для каждого значения y, пока он не станет меньше минимального значения, выполняем в цикле следующее:
1) рисуем ряд окружностей;
2) изменяем y.
IV. Описание переменных: x, y, r — int.

Многие красивые фигуры, которые может построить Черепаха, состоят из окружностей или правильных многоугольников. Ниже разберём принципы рисования следующих фигур (названия условные):

Пример 6.7. Написать программу для построения фигуры «Георгин».

Этапы выполнения задания.

I. Исходные данные отсутствуют.
II. Результат — построенное изображение.
III. Алгоритм решения задачи.
1. Рисунок состоит из окружностей, которые Черепаха рисует из одной точки.
2. Опишем функцию georgin(n, x, y, r, c1, c2). Параметры функции: n — количество окружностей, (x, y) — координаты центра, r — радиус, c1 и c2 — цвета контура и заливки.
3. Так как количество повторений известно, будем использовать цикл for. В цикле будем рисовать окружность и поворачивать Черепаху. Угол поворота 360 // n.
IV. Описание переменных: все переменные — int.

Пример 6.8. Написать программу для построения фигуры «Ромашка».

Этапы выполнения задания.

I. Исходные данные отсутствуют.
II. Результат — построенное изображение.
III. Алгоритм решения задачи:
1. Рисунок состоит из дуг окружности, которые Черепаха рисует в одной точке. 2. Функция romashka(n, x, y, r, c1, c2) имеет параметры: n — количество лепестков, (x, y) — координаты центра цветка, r — радиус, c1 и c2 — цвета контура и заливки.
3. Так как количество повторений известно, будем использовать цикл for. В цикле будем рисовать лепесток и поворачивать Черепаху. Угол поворота 360 // n.
4. Лепесток состоит из двух дуг окружности.
IV. Описание переменных: все переменные — int.

Пример 6.9. Написать программу для построения фигуры «Розан».

Этапы выполнения задания.

I. Исходные данные отсутствуют.
II. Результат — построенное изображение.
III. Алгоритм решения задачи:
1. Рисунок состоит из квадратов, которые Черепаха рисует из одной точки.
2. Опишем функцию rozan(n, x, y, r, c1, c2). Параметры функции: n — количество лепестков, (x, y) — координаты центра цветка, r — радиус, c1 и c2 — цвета контура и заливки.
3. Так как количество повторений известно, будем использовать цикл for. В цикле будем рисовать квадрат и поворачивать Черепаху. Угол поворота 360 // n.
4. Лепесток является квадратом, который рисуется с помощью функции circle.
IV. Описание переменных: все переменные — int.

Пример 6.1. 

V. Программа:

from turtle import *

setup(250, 250)
speed(0); hideturtle()

def p(x, y):
      penup(); setpos(x, y)
      pendown(); seth(0)
# функция рисования треугольника
def pr_tr(x, y, a, b, c):
      p(x — a, y)
      color(c, c)
      begin_fill()
      fd(a); rt(90); fd(b)
      end_fill()
x = int(input(«x = «))
y = int(input(«y = «))
a = int(input(«a = «))
b = int(input(«b = «))
pr_tr(x, y, a, b, «blue»)
done()

VI. Тестирование программы.
Запустить программу и ввести значения: координаты 50, 50, длины катетов 130, 100. Результат — синий треугольник.
В программе цвет рисования линий совпадает с цветом заливки. Если сделать их разными (граница — чёрная, заливка — красная), то будет видно, что линия, соответствующая гипотенузе, не рисуется.

Пример 6.2. 

V. Программа:

from turtle import *

setup(250, 200)
speed(0); hideturtle()

def p(x, y):
      penup(); setpos(x, y)
      pendown(); seth(0)
def star(n, x, y, d):
      p(x, y)
      u = 180 — 180 / n
      for _ in range (n):
            fd(d); rt(u)
n = int(input(«n = «))
x = int(input(«x = «))
y = int(input(«y = «))
d = int(input(«d = «))
star(n, x, y, d)
done()

VI. Тестирование программы.
Запустить программу и ввести значения: n = 5, координаты –50, 30, сторона 120. Результат:

Добавим заливку в функцию рисования звезды:

def star(n, x, y, d):
      p(x, y)
      color(«red», «yellow»)
      begin_fill()
      u = 180 — 180 / n
      for _ in range (n):
            fd(d); rt(u)
      end_fill()

Результат (n = 7):

Нарисовать звезду с чётным числом лучей аналогичным образом невозможно. При попытке соединить вершины через одну она распадётся на фигуры: два треугольника для шести лучей, два квадрата для восьми. Однако существует другой способ: задаём число k (не большее n/2), где каждая вершина соединяется с k-й по часовой стрелке. Числа n и k должны быть взаимно простыми. Угол между лучами вычисляется по формуле: 360 * k / n. Для пятиконечной звезды n = 5, k = 2.

Пример 6.3. 

V. Программа:

from turtle import *

setup(300, 320)
speed(0); hideturtle()

def p(x, y):
      penup(); setpos(x, y)
      pendown(); seth(0)
def poly_star(n, x, y, d):
      p(x, y)
      color(«red», «yellow»)
      begin_fill()
      u1 = 180 — 360 / n
      u2 = 180 — 720 / n
      for _ in range (n):
            fd(d); rt(u1)
            fd(d); lt(u2)
      end_fill()
poly_star(5, -60, 110, 30)
poly_star(6, -60, -30, 30)
poly_star(7, 60, -30, 30)
poly_star(10, 60, 100, 30)
done()

VI. Тестирование программы.
Результат рисования 4 звёздчатых многоугольников для n = 5, 6, 7 и 10.

Случайные числа — это последовательность значений, которые невозможно предсказать. В программировании используются псевдослучайные числа, генерируемые специальными алгоритмами — генераторами случайных чисел. Эти числа почти не связаны и равномерно распределены в заданном интервале.

Пример 6.4. 

V. Программа:

from turtle import *
from random import *setup(300, 300)
speed(0); hideturtle()def p(x, y):
      penup(); setpos(x, y)
      pendown(); seth(0)
for _ in range(10):
      x = randint(-100, 100)
      y = randint(-100, 100)
      r = randint(5, 70)
      p(x, y — r)
      circle(r)
done()

VI. Тестирование программы.
Запустить программу. Должно быть нарисовано 10 окружностей.

Для того чтобы рисовать окружности разными цветами, установим числовой режим ввода цвета и опишем функцию rand_color, которая будет случайным образом генерировать составляющие цвета RGB. Ключевое слово return передаёт полученное значение из вспомогательного алгоритма в основной.

def rand_color():
      r = randrange(256)
      g = randrange(256)
      b = randrange(256)
      color (r, g, b)

Цвет задаём командой color (rand_color()).

Пример 6.5. 

V. Программа:

from turtle import *
from random import *
setup(250, 250)
bgcolor(«darkblue»)
speed(0), hideturtle()
def p(x, y):
    penup(), setpos(x, y)
    pendown(), seth(0)
def star(n, x, y, d):
    p(x, y)
    color(«white», «yellow»)
    begin_fill()
    u = 180 — 180 / n
    for _ in range(n):
        fd(d), rt(u), end_fill()
for _ in range(30):
    # только нечетные числа
    n = randrange(5, 12, 2)
    x = randint(-100, 100)
    y = randint(-100, 100)
    d = randint(7, 15)
    star(n, x, y, d)
done()

VI. Тестирование программы. Результат может быть следующим:

Пример 6.6. 

V. Программа:

from turtle import *
setup(240, 240)
speed(0)
hideturtle()
def p(x, y):
    penup()
    setpos(x, y)
    pendown()
    seth(0)
def fill_circle(x, y, r, c=«»):
    p(x, y — r)
    color(«black», c)
    begin_fill()
    circle(r)
    end_fill()
def row(y):
    x = -100
    r = 10
    while x < 100:
        fill_circle(x, y, r)
        x += 20
y = 100
while y > -100:
    row(y)
    y -= 20
done()

VI. Тестирование программы.

Пример 6.7.
V. Функция для рисования георгина:

def georgin(n, x, y, r,  c1 = «black»,  c2 = «»):
    p(x, y)
    color(c1, c2)
    begin_fill()
    for _ in range (n):
        circle(r)
        lt(360 // n)
    end_fill()

Результат для разных значений аргументов функции:

Пример 6.8.

V. Функция для рисования ромашки:

def romashka(n, x, y, r, c1 = «black», c2 = «»):
    p(x, y)
    color(c1, c2)
    begin_fill()
    for _ in range(n):
        circle(r, 90)
        lt(90)
        circle(r, 90)
        rt(-90)
        lt(360 // n)
    end_fill()

Результат для разных значений аргументов функции:

Пример 6.9.

V. Функция для рисования розана:

def rozan(n, x, y, r, c1 = «black», c2 = «»):
    p(x, y)
    color(c1, c2)
    begin_fill()
    for _ in range(n):
        circle(r, 360, 4)
        lt(360 // n)
    end_fill()

Результат для разных значений аргументов функции:

1.  Как задать случайное число?
2.  Как задать случайный цвет?
3.  Какую библиотеку следует подключить для работы со случайными числами?

Упражнения

1. Выполните задания для примера 6.1.

  1. Введите различные значения исходных данных. Поясните результат.
  2. Объясните, что происходит при вводе отрицательных значений длин катетов.

2. Выполните задания для примера 6.4.

  1. Выполните программу несколько раз. Добавьте заливку. Объясните, почему некоторые окружности не видны.
  2. Внесите в программу такие изменения, чтобы можно было изобразить 20 кругов, 100 кругов.
  3. Какой максимальный размер может иметь радиус круга в программе? Внесите в программу изменения так, чтобы рисовались круги радиуса не более 8. Количество кругов установите равным 10 000.
  4. Внесите изменения в программу так, чтобы пользователь мог вводить количество отображаемых на экране кругов.

3. Выполните задания для примера 6.4.

  1. Замените рисование окружностей на рисование равносторонних треугольников;
  2. * Замените рисование окружностей на рисование прямоугольных треугольников.

.

4. Напишите программу, которая строит случайным образом изображения 20 горизонтальных отрезков длиной 30 пикселей. Разработайте два варианта решения задачи. Один с использованием цикла while, а другой — цикла for.

  1. Сравните две программы решения задачи. Какой вариант решения данной задачи представляется вам лучшим? Почему?
  2. Задайте в программе толщину отрезка в 3 пикселя.
  3. Какие изменения нужны в программе, чтобы толщина отрезка была случайным числом от 2 до 8?
  4. Внесите изменения в программу так, чтобы пользователь мог вводить количество отображаемых на экране отрезков.
  5. Какие изменения нужно внести в программу, чтобы вместо горизонтальных отрезков изображались вертикальные? Диагональные?

5. Используя функцию для рисования треугольника из примера 6.1, нарисуйте ряд треугольников вдоль верхнего (левого) края графического окна.
6.
Напишите программу, которая нарисует ряд фигурок вдоль края графического окна. Фигурками являются правильные многоугольники, которые можно построить с помощью команды circle.

  1. Все фигурки в ряду являются квадратами.
  2. Все фигурки в ряду являются пятиугольниками.
  3. Ряд состоит из фигурок количество сторон у которых определяется случайным числом от 3 до 8.


7.
В программу из примера 6.5 добавьте функцию poly_star(). Добавьте на звёздное небо звёздчатые многоугольники. Цвет и размер подберите самостоятельно.

8. Выполните задания для примера 6.6.

  1. Измените в программе значение r = 10 на r = 12. Почему получился такой рисунок? Поэкспериментируйте со значениями радиуса.
  2. Какие изменения нужно внести в программу, чтобы экран заполнялся кругами радиуса 20 без пересечений?
  3. Измените программу так, чтобы все круги были красными или разноцветными.
  4. Внесите в программу изменения так, чтобы графическое окно можно было заполнять кругами введённого радиуса.

.
9. Нарисуйте букет цветов (пример 6.7, пример 6.8, пример 6.9).

10*. Напишите программу, которая заполнит весь экран (значения аргументов соответствующих функций подберите самостоятельно):

  1. Георгинами (пример 6.8).
  2. Ромашками (пример 6.9).
  3. Чередующимися цветами.

.

Проверь себя