Up

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

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

Пример 18.1. 

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

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

I. Исходные данные: a и b (длины катетов), x и y (координаты вершины прямого угла).
II. Результат: изображение прямоугольного треугольника.
III. Алгоритм решения задачи.
   1. Ввод исходных данных.
   2. Чтобы изобразить треугольник, нужно выполнить следующие действия:
     1) построить линии из точки с координатой (x; y) в точки с координатами (x + a; y) и (x; y + b);
     2) соединить линией точки (x + a; y) и (x; y + b);
     3) закрасить треугольник. Для закрашивания треугольника нужно знать координаты какой-либо точки внутри треугольника. Такой точкой в данном случае может быть точка с координатами (x + 2; y + 2)1 .

IV. Описание переменных: все переменные имеют тип integer.
#include<graphics.h>
#include <bits/stdc++.h>

using namespace std;
int main()  {   
int x,y,a,b,i;
cout << "x = "; cin >> x; 
cout << "y = "; cin >> y; 
cout << "a = "; cin >> a;
cout << "b = "; cin >> b;  
srand( time( 0 ) );   // автоматическая рандомизация
i = 1 + rand()%15;  // интервал от 1 до 15
cout << i;   //для интереса выводим номер цвета

int gd=DETECT,gm;
initgraph(&gd,&gm,"");

line(x,y,x+a,y); line(x,y,x,y+b); line(x+a,y,x,y+b); //треугольник
setfillstyle(SOLID_FILL,i); // заливка сплошная цветом i
floodfill(x+2, y+2, 15);  //заливка, контур фигуры был белый
getch();
closegraph();
}

Тестирование.
Запустить программу и ввести значения: координаты (100; 100), длины катетов 70 и 120. Результат:

В C++ для получения случайного числа используют функцию rand (#include <ctime>)
  srandtime( 0 ) ); // автоматическая рандомизация
// формула генерации случайных чисел по заданному диапазону
 random_number = firs_value + rand() % last_value;
// где firs_value - минимальное число из желаемого диапазона
// last_value - ширина выборки

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

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

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


Пример 18.2*

Многие графические построения можно обобщить, если предположить, что фигура должна быть вписана в квадрат. В этом случае для построения фигуры достаточно задать координаты (x; y) верхнего левого угла квадрата и длину его стороны — d. Используя эти величины, можно получить координаты других вершин квадрата: (x + d; y), (x; y + d), (x + d; y + d). Можно получить координаты середины стороны (x + d / 2; y) или центра квадрата (x + d / 2; y + d / 2).

Нарисовать в графическом окне гриб. Задать координаты верхнего левого угла квадрата и длину его стороны для определения местоположения и размеров гриба.

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

I. Исходные данные: x и y — координаты верхнего левого угла квадрата, в который вписан гриб, d — длина его стороны.
II. Результат: изображение гриба.
III. Алгоритм решения задачи.
   1. Ввод исходных данных.
   2. Для того чтобы построить гриб, нужно выполнить следующие действия:
       1) построить овал для изображения ножки гриба. Параметры команды для изображения эллипса определим следующим образом: ellipse(x + d % 3, y, x + 2*d % 3, y + d);
       2) нарисовать шляпку гриба. Для этого можно использовать команду Pie (построение сектора круга). Координаты центра (x + d/2; y + d/3), радиус d/3. Углы равны 0° и 180° соответственно.
IV. Описание переменных: все переменные имеют тип int.

Функция fillellipse() рисует эллипс и закрашивает его, используя текущий цвет заполнения и образец заполнения. Внешний контур эллипса рисуется с использованием текущего цвета рисова­ния. Центр эллипса располагается в точке х,у. Длина радиусов по координатам х и у задается параметрами xr и yr. Нужна будет для ножки гриба.
Функция sector() рисует эллиптический сектор. Используется текущий цвет рисования. Фигура заливается текущим цветом заливки в соответствии с шаблоном заливки. Сектор покрывает угол, равный end-start. Начальные и конечные точки задаются в градусах с использованием декартовой координатной плоскости. Центр «эллипса», которому принадлежит сек­тор, располагается в точке х,у. Он имеет горизонтальный и вертикальный радиусы, равные xr и yr. Нужна будет для шляпки гриба.
Выполним необходимые расчёты:
(x,y) - координаты верхнего левого угла, d - сторона квадрата. Тогда центр квадрата мы получим, сделав отступы по обеим осям на половину стороны квадрата. Ножка гриба задаётся эллипсом, где первые два параметра - центр эллипса (x + d/2, y + d/2). Ещё нужно указать радиус эллипса по х и по у. Так как ножка гриба по х занимает треть длины стороны квадрата (d/3), а радиус по х будет равен половине этого размера, то (d/3)/2 = d/6. Радиус по у равен половине стороны квадрата  (d/2). Ножка гриба будет жёлтой - это цвет 14, и сплошная заливка - 1. Значит, setfillstyle (1, 14);
Теперь расчёты для шляпки гриба:
Шляпка гриба будет нарисована с помощью команды sector, которая рисует сектор эллипса. Центр этого эллипса будет в точке (x + d/2, y + d/4). Начинается сектор с 0 градусов, заканчивается в 180 градусах. Радиусы rx = d/2,   ry = d/4.
Программа:
#include<graphics.h>
#include <bits/stdc++.h>
#include <conio.h> 
using namespace std;

int main() {   
int x,y,d;
cout << "x = "; cin >> x; 
cout << "y = "; cin >> y;
cout << "d = "; cin >> d;

int gd=DETECT,gm;
initgraph(&gd,&gm,"");

setfillstyle (1, 14);  //цвет для ножки гриба
fillellipse (x + d/2, y + d/2, d/6, d/2);   //ножка гриба
setcolor(6); //устанавливаем новый цвет - коричневый - для шляпки гриба
setfillstyle (1, 6); // заливка шляпки гриба
sector (x + d/2, y + d/4, 0, 180, d/2, d/4);  // сектор эллипса - шляпка гриба

getch();
closegraph();
}

Тестирование.
Запустить программу и ввести значения: координаты (100; 100), сторона 150. Результат:
 

* Гриб можно вписывать не в квадрат, а в прямоугольник. В этом случае нужно задавать две величины, определяющие размеры прямоугольника: длину (d1) и ширину (d2).

Пример 18.2*. Продолжение.

В программу рисования гриба нужно внести изменения, позволяющие рассчитать положение ножки и шляпки гриба относительно координат (x; y) и величин d1 и d2.

Для рисования шляпки приходится выбирать большую из двух размерностей прямоугольника, в который вписывается гриб, иначе шляпка может оказаться очень сплюснутая. Для этого используем функцию max(d1, d2).

#include<graphics.h>
#include <bits/stdc++.h>
#include <conio.h> 
using namespace std;
int main() {   
int x,y,d1,d2;
cout << "x = "; cin >> x;
cout << "y = "; cin >> y;
cout << "d1 = "; cin >> d1;
cout << "d2 = "; cin >> d2;

int gd=DETECT,gm;
initgraph(&gd,&gm,"");

setfillstyle (1, 14);
fillellipse (x + d1/2, y + d2/2, d1/6, d2/2);
setcolor(6);
setfillstyle (1, 6);
sector (x + d1/2, y + d2/4, 0, 180, d1/2, max(d1,d2)/4);

getch();
closegraph();
}


Пример 18.3. 

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

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

I—II. Результатом работы программы, не зависящей от исходных данных, будет изображение 10 окружностей.
III. Алгоритм решения задачи.
1. Установим толщину линий в 3 пикселя.
2. Значения координат центра окружности и ее радиуса определяются функцией rand. Значение цвета для границы круга — случайный цвет.
3. Так как количество повторений известно, будем использовать цикл for.
IV. Описание переменных: x, y (координаты центра), r (радиус) имеют тип int.

Программа:

#include<graphics.h>
#include <bits/stdc++.h>
#include <conio.h> 
using namespace std;
int main() {   
int gd=DETECT,gm;
initgraph(&gd,&gm,"");
int x,y,R;
srand( time( 0 ) );
setlinestyle(1, 0, 3);
for (int i = 0; i < 10; i++) {
x = rand()%600;
y = rand()%400;
R = rand()%150;
setcolor(1+rand()%15); //минуя чёрный цвет (значение 0)
circle(x,y,R);
}
getch();
closegraph();
}

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


18.2. Использование вспомогательных алгоритмов

Построение фигур можно оформлять в виде вспомогательных алгоритмов. Это позволит использовать такие алгоритмы для решения других задач.

Все графические процедуры, которые использовались ранее, имели параметры. Они позволяли определять местоположение и размер фигур. Пользователь также может составить свой вспомогательный алгоритм с параметрами.

Общий вид вспомогательной функции с параметрами:

void <имя> (<список параметров> с их типами) {

<команды>;
}

При вызове вспомогательной функции важно помнить, что количество параметров, их порядок и тип должны соответствовать тому, как процедура описана.

Пример 18.4. 

Написать программу для построения n равнобедренных прямоугольных треугольников с длиной катета а. Расположение треугольников определяется случайным образом.

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

I. Исходные данные: n (количество треугольников), а (длина катета).
II. Результат: изображение n треугольников.
III. Алгоритм решения задачи.
    1. В примере 18.3 изображали окружности, расположенные случайным образом, а в примере 18.1 — прямоугольные треугольники. Воспользуемся программами этих примеров.
    2. Ввод значений переменных n и а.
    3. Так как количество повторений известно, будем использовать цикл for.
    4. Изменим программу из примера 18.3. Для этого команду cirle (построение окружности) заменим на команду построения треугольника:
        1) местоположение треугольника задается координатами прямого угла, которые определим случайным образом;
        2) катеты прямоугольного треугольника имеют одинаковую длину — значение a.
    5. Построение одного прямоугольного треугольника опишем во вспомогательном алгоритме pr_treug. Параметры процедуры построения треугольника — координаты вершины прямого угла и длины катетов. Алгоритм описан в примере 18.2.
IV. Описание переменных: все переменные имеют тип int.
Программа:
#include<graphics.h>
#include <bits/stdc++.h>

using namespace std;

void treug(int x, int y, int a, int b) {  //функция для рисования 1 треугольника
int c = 1 + rand()%15; //случайный цвет
setlinestyle(1, 0, 3); //толщина линии 3 сплошная
setcolor(c); //назначаем цвет линии
line(x, y, x + a,y);
line(x, y, x, y + b);
line(x + a, y, x, y + b);
}
int main()  {   
int n,x,y,a,b,i;
cout << "n = "; cin >> n;  
cout << "a = "; cin >> a;

int gd=DETECT,gm;
initgraph(&gd,&gm,"");

srand( time( 0 ) );
for (i = 0; i < 10; i++) {
x = rand()%500;  
y = rand()%400;
treug(x,y,a,a);
}
getch();
closegraph();
}
Тестирование.
Запустить программу. Результат:

Пример 18.5*. 

Нарисовать 10 грибов.

Расположение и их размеры определяются случайным образом.

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

I—II. Результатом работы программы, не зависящим от исходных данных, будет изображение 10 грибов.
III. Алгоритм решения задачи.
1. Построение одного гриба опишем во вспомогательном алгоритме. Алгоритм описан в примере 18.2.
2. Значения координат верхнего левого угла и размер гриба определяются функцией rand.
3. Так как количество повторений известно, будем использовать цикл for.
IV. Описание переменных: x, y (координаты верхнего левого угла), d (размер) — int.
Программа:
#include<graphics.h>
#include <bits/stdc++.h>

using namespace std;

void grib(int x, int y, int d) {
setfillstyle (1, 14);
fillellipse (x + d/2, y + d/2, d/6, d/2);
setcolor(6);
setfillstyle (1, 6);
sector (x + d/2, y + d/4, 0, 180, d/2, d/4);
}
int main()  {   
int x,y,d,i;

int gd=DETECT,gm;
initgraph(&gd,&gm,"");

srand( time( 0 ) );
for (i = 0; i < 10; i++) {
x = rand()%400;
y = rand()%200;
d = rand()%150;
grib(x,y,d);
}
getch();
closegraph();
}
Результат работы программы:

Пример 18.6. 

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

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

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

Программа:
#include<graphics.h>
#include <bits/stdc++.h>
using namespace std;
int x, y, r;    //глобальные переменные - и для вспомогательной программы, и для основной
void row(int y) {
x = 10;
r = 10;
while (x < 640) {
circle(x,y,r); 
x += 20;
}
}

int main()  {   
int gd=DETECT,gm;
initgraph(&gd,&gm,"");

y = 10;
while (y < 480) {
row(y); 
y += 20;
}

getch();
closegraph();
}

Результат:

В примере 18.6 показано, как заполнить графическое окно окружностями.

Внеся небольшие изменения в эту программу, можно заполнять графическое окно любыми другими фигурками.

Для этого достаточно заменить команду circle(x,y,r) в процедуре row на другую команду. Можно выбрать графический примитив из библиотеки graph.h или самостоятельно написать процедуру рисования фигурки (например, использовать процедуру рисования гриба из примера 18.5).

Вопросы.

1. Как задать случайное число?

2. Как задать случайный цвет?

3. Как описать функцию с параметрами?

Упражнения.

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

    1. Поэкспериментируйте с программой, вводя различные значения исходных данных.

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

    3. Что произойдет, если ввести отрицательные значения координат?

    Объясните результат.

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

    1. Выполните программу несколько раз. 

    2. Внесите в программу такие изменения, чтобы можно было изобразить 20 кругов; 100 кругов.

    3. Какой максимальный размер может иметь радиус круга в программе? Внесите в программу изменения так, чтобы рисовались круги с радиусом не более 20. Количество кругов установите равным 10 000.

    4. Внесите изменения в программу так, чтобы пользователь мог вводить количество отображаемых на экране кругов.

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

    1. Запустите программу несколько раз.  Измените программу так, чтобы треугольники рисовались ниже текста (ближе к середине экрана).

    2. Добавьте в программу возможность ввода длины второго катета.

    3. Измените программу так, чтобы длины катетов задавались случайным образом.

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

    1. Сравните две программы решения задачи. Какой вариант решения данной задачи представляется вам лучшим? Почему?

    2. Задайте в программе толщину отрезка в 3 пикселя.

    3. Какие изменения нужны в программе, чтобы толщина отрезка была случайным числом из промежутка [2; 8]? Используйте формулу a + rand() % b;

    4. Внесите изменения в программу так, чтобы пользователь мог вводить количество отображаемых на экране отрезков.

    5. Какие изменения нужно внести в программу, чтобы вместо горизонтальных отрезков изображались вертикальные? Диагональные?

№ 5. Используя процедуру рисования треугольника из примера 18.4, нарисуйте ряд треугольников вдоль верхнего (левого) края графического окна.

№ 6. Напишите программу для рисования одной из фигурок. Задаются координаты верхнего левого угла и длина стороны квадрата (длины сторон прямоугольника):

№ 7*. Напишите программу, которая нарисует ряд фигурок вдоль края графического окна. Используйте фигурки, которые рисовали в задании 6.
№ 8. Выполните задания для примера 18.6.
    1. Измените в программе значение r = 10 на r = 20. Почему получился такой рисунок? Поэкспериментируйте со значениями радиуса.
    2. Какие изменения нужно внести в программу, чтобы экран заполнялся кругами с радиусом 20 без пересечений?
    3. Внесите изменения в программу так, чтобы все круги были красными или разноцветными.
    4. Внесите в программу изменения так, чтобы графическое окно можно было заполнять кругами введенного радиуса.
№ 9. Напишите программу, которая заполнит все графическое окно:
    1. Грибами (пример 18.2).
    2. Фигурками из задания 6.


Комментариев нет:

Отправить комментарий