Я готуюсь до курсу інформатики. Алгоритмізація та програмування



Сторінка8/9
Дата конвертації19.02.2016
Розмір1.47 Mb.
1   2   3   4   5   6   7   8   9

УРОК 30. Робота з графікою

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


Теоретичний матеріал
Режими роботи монітору було розглянуто в уроці 9.
Для роботи в графічному режимі використовується модуль Graph, який складається з більш ніж 90 графічних процедур і функцій. Усі стандартні засоби модуля Graph стають доступними після його підключення до програми в розділі Uses Uses Graph; Зверніть увагу що для того, щоб графічна бібліотека стала доступною, слід прописати до неї шлях доступу в пункті меню Options/Directories / Unit directories оболонки Паскаль. За замовчуванням цей шлях доступу наступний BPвідповідного диску. Екран у графічному режимі може адресуватися за допомогою системи координат, причому значення X(номера стовпчика) збільшується зліва направо, а значення У (номера рядка) збільшується зверху до низу. За замовчуванням координати екрана мають такий вигляд
(0,0) - лівий верхній кут;
(639,0) - правий верхній кут;
(319,239)-центр;
(0,479) - лівий нижній кут екрана;
(639,479) - правий нижній кут.
Графічна система підтримує поточний покажчик СР, який виконує ті ж функції, що і курсор, але не виводиться на екран. Для переміщення курсора використовуються процедури MoveTo, LineTo, InitGraph, LineRel, MoveRel і деякі інші. У графічному режимі можна виводити текст, причому є можливість масштабування і вибору типу шрифту, виконання вирівнювання виведеного тексту тощо. Наявні програми підтримують різні засоби малювання і заповнення фігур, зокрема, точку, лінії, окружності, еліпси, прямокутники, багатокутники. Для всіх команд виведення можна встановити графічне вікно (прямокутну область на екрані заданого розміру). Уся графічна інформація виводиться у поточне вікно, поки не активізується інше. При установці віконного режиму всі графічні зображення, якщо вони виходять за межі вікна, усікаються. При виконанні графічної операції може виникнути помилка, код якої можна одержати за допомогою функції GraphResult. Код помилки може приймати одне з наступних значень
0
Помилки немає
-1
Режим BGI не встановлений
-2
Графічні апаратні засоби не виявлені
-3
Файл драйвера пристрою не знайдений
-4
Неправильно визначений файл драйвера пристрою
-5
Не вистачає пам’яті для завантаження драйвера
-6
Вихід за межі пам’яті при заповненні
-7
Вихід за межі пам’яті при заливанні
-8
Файл із шрифтом не знайдений
-9
Не вистачає пам’яті для завантаження шрифту
-10
Неправильний графічний режим для обраного драйвера.
Для забезпечення переходу екрану монітора в графічний режим програма має починатися викликом процедури InitGraph, що автоматично виявляє апаратні засоби і завантажує відповідний графічний драйвер. Стандартний драйвер EGAVGA.BGI розміщується у каталозі BPM3GI відповідного диску. Якщо апаратні засоби не виявлені або в процесі ініціалізації відбулася помилка, то на екран виводиться повідомлення про помилку і програма зупиняється.
Нижче наведені деякі процедури та функції для роботи в графічному режимі, що містяться в бібліотеці Graph.
Arc(X,Yinteger; поч_кут, кін_кут, padiycword) - процедура, результатом роботи якої є дуга окружності з центром в точці (X, Y) і радіусом «радіус». Дуга креслиться від початкового кута («почкут») до кінцевого кута («кінкут») поточним кольором малювання.
Bar(Xl,YJ,X2,Y2) - процедура малює зафарбований прямокутник, використовуючи колір зафарбування, що встановлюється процедурою SetFillStyle. Контур прямокутника креслиться кольором і типом лінії, що встановлені процедурами SetColor і SetLineStyle. Точки з координатами (X1, Y1) та (Х2, Y2) задають дві діагональні вершини прямокутника.
Bar3D(Xl, Yipb, Y2integer; глибина word, вершина boolean) - процедура малює зафарбований тривимірний паралелепіпед. Контур паралелепіпеда креслиться кольором і типом лінії, що встановлені процедурами SetColor і SetLineStyle, тип і колір зафарбування встановлюється процедурою SetFillStyle. «Глибина» — число елементів зображення, що задають третій вимір тривимірного контуру. Якщо змінна, зазначена як параметр «вершина», приймає істинне значення (True), то для паралелепіпеда малюється тривимірна вершина, інакше — вершина не малюється.
Circle(X, Ydnteger;радіус word) - процедура малює окружність поточним кольором. Точка (X, Y) - центр окружності, а «радіус» — її радіус.
ClearDevise - процедура очищує поточний графічний екран і підго-товлює його для виведення даних.
ClearViewport - процедура очищує поточне вікно.
CloseGraph - процедура припиняє роботу графічної системи (закриття графіки) і повертає монітор до текстового режиму.
DetectGraph(Var драйвер, режим integer) - процедура перевіряє наявність відповідних апаратних засобів і визначає, який графічний режим і драйвер варто використовувати.
Ellipse(X,Yinteger; поч_кут, кін_кymword; paдX,paдYword) -процедура малює еліптичну дугу, використовуючи (X, Y), як точку центра і «радХ», «padY» - як радіуси на горизонтальній і вертикальній осях. Дуга еліпса малюється від початкового кута (параметр «почкут») до кінцевого кута (параметр «кін_кут») поточним кольором.
FillEllipse(X, Yinteger;Xpaдiyc, Ypaдiycword) - процедура вичерчує зафарбований еліпс, використовуючи точку з координатами (X, Y), як центр, а «Храдіус» і «Ypaдiyc» - у якості радіусів на горизонтальній та вертикальній осях. Контур еліпса креслиться кольором і типом лінії, що встановлені процедурами SetColor і SetLineStyle , тип і колір зафарбування встановлюється за допомогою процедури SetFillStyle.
FloodFill(X,Y,границяword) - процедура заповнює замкнену область, використовуючи поточний заповнювач, заданий процедурою SetFillStyle. Точка (X,Y) є внутрішньою точкою області, що зафарбовується. Заповнюється область, обмежена лінією, що має колір, визначений параметром «границя». Якщо точка (X,Y) знаходиться усередині замкненої області, то заповнюється внутрішня область. Якщо ця точка знаходиться поза замкненої області, то заповнюється зовнішня частина.
GetBkColor word - функція повертає поточне значення кольору тла (у діапазоні 0 - 15), встановлене процедурою SetBkColor.
GetCohr word - функція повертає поточне значення основного кольору малювання (у діапазоні 0-15), встановлене раніше процедурою SetColor.
GetPixel(X,Ymteger) word - функція повертає значення (колір) елемента зображення в точці (X, Y).
GetX integer - функція повертає Х-координату поточного СР.
GetY integer - функція повертає Y-координату поточного СР.
InitGraph - процедура ініціалізує графічну систему і переводить апаратну частину в графічний режим.
L4ne(Xl, Yl, X2, Y2 integer) - процедура вичерчує пряму лінію (товщина і тип якої встановлений процедурою SetLineStyle, колір - процедурою SetColor) із крапки (X1, Y1)y крапку (Х2, Y2).
LineRel(Dx,Dy) - процедура вичерчує пряму лінію з точки поточного СР в точку, задану відносною відстанню (Dx, Dy) від поточного покажчика.
UneTo(X,Y integer) - процедура малює пряму лінію з точки, у якій знаходиться поточний покажчик СР, у точку з координатами (X, Y).
MoveRel(Dx, Dy integer) - процедура переміщує покажчик СР з поточної точки у точку, задану відносною відстанню (Dx, Dy).
MoveTo(X, Y integer) - процедура переміщує поточний покажчик СР у точку з координатами (X, Y).
OutText (рядок string) - процедура виводить текст «рядка» на монітор, починаючи з точки розташування покажчика СР.
OutTextXY(X, Y integer; текст_рядок string) - процедура виводить текст, що міститься у «текст_рядок», починаючи з точки, заданої координатами (X, Y). Якщо рядок занадто довгий і виходить за межі екрана чи поточної області перегляду, то він усікається.
PieSlice (X, Y integer; нач_кут, кін_кут R word) - процедура викреслює і заповнює поточним кольором сектор кола радіусом R. Точка (X, Y) -центр кола, а сектор малюється від початкового до кінцевого кута. Тип і колір зафарбування попередньо задається процедурою SetFillStyle.
PutPixelfX, Y integer; ел_зображ word) - процедура зафарбовує точку з координатами (X, Y) у колір, що визначається параметром «ел_зображ».
RectanglefXl, Yl, Х2, Y2 integer) - процедура вичерчує прямокутник, використовуючи поточний колір і тип лінії. (X1, Y1) та (Х2, Y2) - координати діагонально протилежних вершин прямокутника.
Sector (X, У integer; поч_кут, кін_кут,Х_Радіус, Y_Padiyc word)— процедура вичерчує і заповнює еліптичний сектор. (X, У) - центр кола, «ХРадіус», «YPaдiyc» - горизонтальний і вертикальний радіуси. Сектор креслиться від початкового «поч_кут» до кінцевого кута «кін_кут». Сектор малюється поточним кольором і зафарбовується з використанням зразка зафарбування і кольорів, заданих за допомогою процедури SetFillStyle.
SetBkColor (колір word) - процедура встановлює поточний колір тла.
SelColor(Koлip word) - встановлює поточний колір малювання.
SetFillStyle( зразок word; колір р word) - процедура встановлює зразок і колір зафарбування для всіх типів зафарбування, виконуваних процедурами Bar, Bar3D, FillEllipse, FloodFill та PieSlice. Можна використовувати кілька типів зафарбування (наприклад, 1 - суцільне фарбування, 2 - штрихування лініями, 7 - штрихування символом «+», 11 - штрихування крапками тощо).
SetLineStyle(mun_pHdKa word; зразок word; товщина word) -процедура встановлює поточну товщину і тип лінії.
SetTextJustify(ropu3, верт word) - процедура встановлює значення вирівнювання тексту, що використовуються процедурами OutText і OutTextXY.
SetTextStyle (шрифт word; направл word; розм_символу CharSize-турі) - процедура встановлює поточний шрифт символу.
SetViewport(XI, Yl, XI, Х2 word, clip boolean) - процедура встановлює для графічного поточного виведення чи перегляду вікно, де (X1,Y1) -верхній лівий кут області перегляду, (Х2, Y2) - нижній правий кут. Процедура переміщує поточний покажчик у точку з координатами (0,0). Clip - булівська змінна.

УРОК 31. Побудова графічних зображень

Мета уроку показати можливості роботи в графічному режимі на прикладах розв’язання задач.


На цьому уроці пропонується розв ‘язати цікаві задачі із застосуванням графічного режиму роботи монітору.
ЗАДАЧА № 604
Умова Скласти програму, яка при натисканні клавіші Д (день) малює сонце, а при натисканні клавіші Н (ніч) малює місяць.
Розв’язування По-перше, для вибору малюнку (день чи ніч) введемо символьну змінну Ch, залежно від значення якої і будемо малювати сонце чи місяць. По-друге, малювання сонця складається з малювання зафарбованого кола процедурою FillEllipse (ця процедура малює зафарбований еліпс, але, якщо еліпс має однакові радіуси по осям, то він перетворюється на коло) та кількох прямих (променів), а місяць можна отримати, якщо накласти одне на одне два кола різних кольорів (жовтого та чорного) з деяким зміщенням. Програма має вигляд
Program Example_604;
Uses graph,crt; {Підключення бібліотек}
Var GraphDriver,GraphModeinteger;
Chchar;
Begin
Clrscr;
Writeln(‘Введіть Ваш вибір Д - день, Н - ніч.’);
Readln(ch);
GraphDriver=VGA; {Ініціалізація графічного режиму)
GraphMode=VGAHi;
InitGraph(GraphDriver,GraphMode,’’);
if (Сh=’Д’) or (Ch=’д’) then
begin
setfillstyle(l,yellow);
setcolor(yellow);
fillellipse(100,80,50,50); {Малювання сонця)
{Малювання променів)
line(100,80,250,80); line{100,80,240,30);
lіnе(100,80,200,250); line(100,80,230,180) ;
line(100,80,150,250); line(100,80,100,300);
line(100,80,50,380); line(100,80,20,280);
line(100,80,0,150); line(100,80,0,80) ;
line(100,80,0,30); line(100,80,10,0) ;
line(100,80,50,0); line(100,80,100,0) ;
line(100,80,150,0);
end
else
if (Ch=’H’) or (Ch=’H’) then
begin
setfillstyle(l,yellow); setcolor(yellow);
fillellipse(100,80,50,50); setfillstyle(1,black) ;
setcolor(black); fillellipse(130,80,50,50) ;
end
else writeln(‘Ви помилилися!’);
Readkey; Closegraph;
End.
ЗАДАЧА № 607
Умова «Зоряне небо». Заповнити екран монітора різнокольоровими точками, кількість яких, колір та координати визначаються випадково.
Розв’язок Для вибору випадковим чином вказаних величин скористуємось функцією Random, що вибирає числа із заданого діапазону, причому врахуємо, що, якщо в дужках після функції вказане ціле число, то будуть генеруватися цілі числа в діапазоні від 0 до вказаного числа. Зверніть увагу на те, що всього можливих кольорів 16 (від 0 до 15), але на чорному тлі чорний колір (з нульовим номером) не видимий, тому можна скористатися такою формулою для отримання ненульових цілих чисел в діапазоні від 1 до 15 random (14) + 1
Аналогічно можна вибрати координати та кількість «зірок» (точок) на екрані, причому відслідкувати, щоб кількість ніколи не була нульовою. Сама «зірка» (точка) на екрані може бути отримана процедурою Putpixel, що задає колір та координати точки виведення. Програма має вигляд
Program Example_607;
Uses graph;
Var GraphDriver,GraphModeinteger;
x,y,color,Ninteger; {x,y - координати точки - ‘Зірки’,
color - колір точки, N - кількість точок}
іinteger; {і - змінна циклу}
Begin
Randomize;
GraphDriver=VGA; GraphMode=VGAHi;
InitGraph(GraphDriver,GraphMode,’’);
{Генерується кількість точок в діапазоні від 200 до 1200}
N=random(1000)+200;
for i=1 to N do
begin
x=random(640); у=random(480); color=random(14)+l;
putpixel (x,y, color) ; {Виведення піксела заданого кольору color у задані координати екрану х та у}
end;
Readkey;
Closegraph;
End.
Домашнє завдання
• Повторити сторінки 221 - 229 запропонованого підручника;
• Задачі № 603 (26, 8), 605,606, 608.

УРОК 32. Ділова графіка

Мета уроку показати можливості роботи з діловою графікою засобами мови Паскаль на прикладах розв’язання задач.


На цьому уроці пропонується показати можливості мови Паскаль при побудові графіків функцій та різного виду діаграм.
ЗАДАЧА № 614
Умова Зобразити на екрані монітора декартову систему координат, початок якої збігається з центром екрана.
Розв’язування Для малювання осей х та у слід скористатися процедурою line, причому координати початку та кінця цих прямих обчислити неважко, тому що вони мають розміщуватись в центрі екрану. Градуювання осей робиться теж за допомогою коротких відрізків довжиною 8 пікселів, що розташовані з кроком step пікселів (крок в програмі заданий у вигляді константи, хоча можна його задавати і іншим методом). Підписи на осях можна зробити таким чином число, що треба написати, переводиться в рядок процедурою str, а потім виводиться на екран процедурою OutTextXy. Зверніть увагу на те, що на від’ємному проміжку вісі до числа ліворуч дописується знак «-» командою S = ‘-’ + S, де S — рядок, що містить підпис під поділкою. Для якісного оформлення малюнку використовується процедура settextjustify(1,1), що забезпечує відцентроване виведення тексту у вказану позицію. Програма, що реалізує алгоритм, має вигляд
Program Example_614;
Uses graph; {Підключення бібліотек}
Const
Step=25; {Крох між поділками на осях}
Var GraphDriver,GraphModeinteger;
x,уinteger; {x,y - координати центру декарт. сист. коорд.}
rinteger; {r - відстань від центру координат до чергової поділки}
Sstring; {S - рядок, де зберігається символьне значення підпису для поділки)
Begin
Randomize;
GraphDriver=VGA; {Ініціалізація графічного режиму}
GraphMode=VGAHi;
InitGraph(GraphDriver,GraphMode,’’); {Малювання осей}
line(0,240,640,240); line(320,0,320,480);
{Малювання стрілочок на кінцях осей}
line(630,235,640,240); line(630,245,640,240);
line(315,10,320,0); line(325,10,320,0);
{Підписи на осях}
outtextxy(330,5,’Y’); outtextxy(630,220,’X’) ;
x=320; y=240; r =0; {Малювання та підпис поділок на вісі X}
while x+r<640 do
begin
line(x+r,y-4,x+r,y+4); line(x-r,y-4,x-r,y+4);
r=r+step;
str(r div step, S);
settextjustify (1,1);
outtextxy(x+r,y+10,S);
s=’-’+S;
outtextxy(x-r,y+10,S) ;
end;
r=0; {Малювання та підпис поділок на вісі Y}
while y+r<4 80 do
begin
line(x+4,y+r,x-4,y+r); line(x+4,y-r,x-4,y-r);
r=r+step;
str(r div step, S);
settextjustify (1,1); outtextxy(x-10,y-r,S);
s=’-’+S; outtextxy(x-10,y+r,S);
end;
Readkey;
Closegraph; {Закриття графічного режиму}
End.
ЗАДАЧА № 616
Умова Стовпчаста діаграма - це послідовно зображені прямокутники однакової ширини, що розташовані на одному горизонтальному рівні. Висота прямокутників пропорційна значенням деякої числової послідовності. Побудувати стовпчасту діаграму за даними п цілими значеннями. Для наочності стовпчики зафарбувати різними кольорами.
Розв ‘язок Для побудови діаграми, по-перше, необхідно задати кількістьстовпчиків, тобто кількість числових значень, по яких буде будуватисядіаграма, а, по-друге, - самі значення. В даному алгоритмі всі ці величинивводяться з клавіатури, хоча можна передбачити і інші методи, наприклад,заповнення генератором випадкових чисел. Після введення числових данихслід розрахувати коефіцієнти пропорційності по осях Хта Y, щоб отриматималюнок на весь екран. Врахуємо, що максимальний розмір по осі X -640 пікселів, а по осі Y - 480 пікселів. Тоді коефіцієнт по осі X можнаобчислити за формулою

де SizeX—коефіцієнт пропорційності, N—кількість стовпчиків на діаграмі.


Константне значення 5 від дробу віднімається, щоб розділити стовпчики між собою хоча б на 5 пікселів (це значення можна змінити).
По осі Y знайти коефіцієнт пропорційності важче, тому що для цього слід спочатку визначити максимальне значення, що використовується для побудови діаграми. Для знаходження максимуму використовуємо стандартний алгоритм. Тут можна запропонувати дітям згадати цей алгоритм самостійно. Після знаходження максимуму знаходимо коефіцієнт пропорційності по осі Y за очевидною формулою

де SizeY- шуканий коефіцієнт, Мах - максимальне значення з масиву.


Обидва шукані коефіцієнти пропорційності округлюємо функцією round, тому що екранні координати не можуть бути дробовими, а після цього нормалізуємо значення масиву множенням на коефіцієнт SizeY.
Після підготовки даних можна побудувати стовпчасту діаграму. Кожен її елемент будується процедурою Ваг, що малює зафарбований прямокутник, колір якого задається процедурою SetFillStyle. Очевидно, що ширина кожного стовпчика буде дорівнювати SizeX - 5, тому початкова координата по осі А’дорівнює (і - l)*SizeX, а кінцева — i*SizeX - 5, де і - змінна циклу, що рахує номер чергового стовпчика. Початкова координата по осі Y буде максимальною, тобто 480, а кінцева координата дорівнювати різниці між 480 та елементом масиву.
Програма має наступний вигляд
Program Example_616;
Uses graph;
Var GraphDriver,GraphModeinteger;
N,i,Max integer;
Aarray [1. .100] of integer; {Масив значень побудови діаграми}
SizeX, SizeY integer;
{Коефіцієнти пропорційності no відповідних осях}
Begin
ClrScr;
Write (‘Введіть кількість стовпчиків у діаграмі ‘);
ReadLn (N); {Введення значень для побудови діаграми}
for i=l to N do
begin Write (‘Введіть A[‘,i,’]’); ReadLn (A[i]); end;
Randomize;
GraphDriver=VGA; {Ініціалізація графічного режиму}
GraphMode=VGAHi; InitGraph(GraphDriver,GraphMode,’’) ;
SizeX=round(640/N-5); {Пошук максимального значення в масиві для побудови діаграми на весь екран}
Мах=А[1];
for і=2 to N do
if A[i]>Max then Мах=А[і];
SizeY=round(480/Max); {Перетворення масиву значень у відповідності з коефіцієнтом пропорційності}
for i=l to N do A[i]=A[i]*SizeY;
for i=1 to N do
begin {Встановлення випадковим чином кольору зафарбування стовпчиків діаграми}
SetFillStyle (1,random(14)+1); Bar ((i-l)*SizeX,480,i*SizeX-5,480-A[i]);
end;
Readkey; {Затримка зображення на екрані}
CloseGraph; {Закриття графічного режиму}
end.
ЗАДАЧА № 618
Умова Секторною діаграмою називають круг, площі секторів якого пропорційні відповідним числовим величинам, узятим з деякої послідовності. Для заданої послідовності з п дійсних чисел побудувати секторну діаграму. Для наочності сектори діаграми зафарбувати різними кольорами.
Розв’язування Кількість елементів діаграми в цій задачі вводиться так само, як і в попередньому випадку, тобто з клавіатури, а заповнення масиву даними зробимо генератором випадкових чисел. Далі, як і в попередній задачі, необхідно промасштабувати початкові значення для виведення їх на екран у вигляді кругової діаграми. Для цього спочатку знаходимо суму всіх елементів масиву, а потім масштабуємо їх за формулою

де Sum - загальна сума елементів масиву, 360 - кількість градусів у повному колі.


Сама діаграма будується за допомогою процедури PieSlice, що виводить на екран зафарбований сектор круга. Колір зафарбування задається процедурою SetFillStyle, а початковий та кінцевий кути сектора обчислюються від поточного кута. Angle з урахуванням значення елементу масиву. Центр кола, на якому будується кругова діаграма, завжди константний (320; 240). Програма, що реалізує описаний алгоритм, має вигляд
Program Example_618;
Uses graph; (Підключення бібліотек}
Var GraphDriver,GraphModeinteger; N, і integer;
Sum,Ang real;
A array [1..100] of real; S string; Begin
ClrScr; Randomize;
Write (ЛВведіть кількість елементів діаграми *).;
ReadLn (N);
(Введення значень для побудови діаграми}
for i=l to N do A[i]=random*200;
GraphDriver=VGA;
GraphMode=VGAHi;
InitGraph(GraphDriver,GraphMode,»);
Sum=0;
for i=1 to N do Sum=Sum+A[i];
for i=1 to N do A[i]=A[i]*360/Sum;
Ang=0;
for i=1 to N do
begin
SetFillStyle (l,Random(14)+l);
PieSlice (320,240,round (Ang), round (Ang+A[i]),230);
(Виведення на діаграмі числових значень)
Str (A[i]*Sum/36030,S);
OutTextXY(round(320+120*coe((2*Ang+A[i]))*Pi/360),
round(240-120*ein((2*Ang+A[i])*Pi/360)),S);
Ang=Ang+A[i];
end;
Readkey; CloseGraph; {Закриття графічного режиму)
end.
Домашнє завдання
• повторити сторінки 221 - 229 запропонованого підручника;
• задачі №615,617,620.

УРОК 33. Методи створення мультфільмів

Мета уроку показати створення рухомих графічних об’єктів та простих мультиплікаційних зображень засобами мови Паскаль.


Теоретичний матеріал
Щоб розпочати роботу над створенням найпростішого «мультика» (зображення, що рухається), спочатку розберемося, як воно створюється в реальних умовах. Всі знають, що художник мультиплікатор малює серію зображень, у кожному з яких показується один і той же рух з ледь помітними змінами. Тепер, якщо зображення швидко змінювати одне за одним, ми не помічаємо зміну малюнків, а бачимо рух цього персонажу. Поміркуємо, як відтворити послідовність схожих об’єктів на екрані монітору. Перше, що спадає на думку, це намалювати зображення, затримати його трохи на екрані, витерти зображення (очистити екран) та вивести нове зображення з ледь помітними змінами. При достатньо великій швидкості малювання око людини не помітить зміни малюнків і їй буде здаватися, що об’єкт рухається. Розв’яжемо таким методом наступну задачу.
ЗАДАЧА № 629
Умова «Годинник». Змоделювати рух годинної та хвилинної стрілок.
Розв ‘язування Якщо змоделювати роботу годинника в реальному часі, то наочність програми буде невеликою, тому що рух стрілок буде ледь помітним. Тому зробимо імітацію роботи годинника, тобто хвилинна стрілка буде рухатися достатньо швидко, а рух годинникової стрілки буде залежати від хвилинної. На початку роботи з’ясуємо, з яких елементів складається годинник. По-перше, це круг з поділками, а, по-друге, два відрізка різної довжини, що імітують стрілки (стрілки можна зробити і більш складними). Круг являється нерухомим об’єктом, тому він малюється статично з абсолютними координатами центру та радіусом, а стрілки рухаються, причому переміщується тільки один кінець стрілки-відрізка, а другий теж являється статичним (центр круга).
Формули, за якими обчислюються координати рухомого кінця стрілки, відомі учням з курсу математики (поворот точки на заданий кут відносно нерухомого центру з координатами(x0,y0)
x = x0+L*cos
y = yo-L*sin
де L - відстань, на якій знаходиться точка від центру повороту, а — кут, на який повертається точка.
Зверніть увагу тільки на те, що в програмі друга формула замість знаку «-» буде містити знак «+», тому що екранні координати мають направленість осей, зворотну до реальних декартових координат (на екрані значення координати Y збільшується в напрямку зверху вниз).
Малювання поділок на циферблаті виконується теж за допомогою вище наведених формул
Програма, що реалізує запропонований алгоритм, наведена нижче. Зверніть увагу, що в цій програмі L_min, L_time - довжини хвилинної та годинникової стрілок відповідно; Color_min, Color_time - кольори хвилинної та годинникової стрілок відповідно; R - радіус циферблату годинника; x_centr, y_centr - координати центра екрану (визначаються у відповідності до поточної роздільної здатності за допомогою функцій getmaxx та getmaxy; x_min, y_min - координати рухомого кінця хвилинної стрілки; x_time, y_time - координати рухомого кінця годинникової стрілки; Ang_min, Ang_time - кути повороту хвилинної та годинникової стрілок. Рух стрілок по циферблату здійснюється за рахунок постійного їх перемальовування то активним кольором малювання стрілки, то кольором тла («затирання» зображення). Програма завершується після натискання будь-якої клавіші за рахунок використання циклу repeat until keypressed.
Program Example_629;
Uses crt,graph; {Підключення бібліотек}
const L_min=174;
L_time=145; Color_min=white; Color_time=white; R = 200;
var gd,gminteger;
Sstring[2];
x_centr, y_centrinteger;
і,x_min,y_mininteger;
x_time,y_timeinteger;
Ang_min,Ang_timereal;
begin
{Ініціалізація графічного режиму}
gd=VGA; gm=VGAHi;
InitGraph (gd,gm,’’);
{Визначення центра екрану}
x_centr = getmaxx div 2;
y_centr = getmaxy div 2;
{Малювання статичної частини малюнку}
SetColor(brown);
SetFillStyle(l,brown);
{Малювання циферблату коричневого кольору}
FillEllipse(x_centr,y_centr,R,R);
Ang_time=-90;
{Встановлення кольору малювання, стилю тексту}
SetColor(yellow);
SetTextJustify(CenterText, CenterText);
SetTextStyle(DeaultFont, HorizDir, 2);
{Малювання поділок жовтого кольору та цифр}
for i=1 to 12 do
begin
Ang_time=Ang_time+30;
x_time=round(x_centr+185*cos(Ang_txme*pi/180));
y_time=round(y_centr+185*sin(Ang_time*pi/180)) ;
str(i,S);
OutTextXy(x_time,y_time,S);
end;
{Малювання ходу годинника}
Ang_min=-90; Ang_time=-90;
repeat
x_time=round(x_centr+L_time*cos(Ang_time*pi/180));
y_time=round(y_centr+L_time*sin(Ang_time*pi/180)) ;
SetColor(Color_time);
Line(x_centr,y_centr,x_time,y_time);
x_min=round(x_centr+L_min*cos(Ang_min*pi/180)) ;
y_min=round(y_centr+L_min*sin(Ang_min*pi/180)) ;
SetColor(Color_min);
Line(x_centr,y_centr,x_min,y_min);
Delay(10000); {Затримка зображення на екрані)
SetColor(brown);
Line(x_centr,y_centr,x_time,y_time);
Line(x_centr,y_centr,x_min,y_min);
Ang_min=Ang_min+6;
Ang_time=Ang_time+0.5;
until keypressed;
readkey; CloseGraph;
end.
Запропонований метод побудови мультиплікаційних об’єктів являється найпростішим, але якщо об’єкт, що рухається, має більші лінійні розміри, ніж в запропонований задачі, він буде суттєво миготіти на екрані. Тому існує інший підхід до розв’язку цієї задачі. Пропонується алгоритм
а) намалювати бажаний об’єкт;
б) запам’ятати область екрана, з виведеним малюнком;
в) відновити екран в місці, де був малюнок (тобто стерти малюнок);
г) вивести малюнок на нове місце і т.д.
Цей підхід дуже схожий на попередній варіант, але має суттєві переваги в тому, що не потребує багаторазового перемалювання малюнку. Об’єкт створюється один раз, зберігається його копія, а потім виводиться в потрібному місці. Для зберігання намальованого фрагмента необхідно використовувати оперативну пам’ять, причому так як ми не знаємо розміри об’єкта на початку програми, пам’ять необхідно запрошувати у системи безпосередньо під час роботи програми. Це можна зробити тільки використовуючи динамічну пам’ять за допомогою наступних процедур
1) GetImage(x1,y1,x2,y2,BitMap) - зберігає образ вказаної прямокутної області екрана в динамічній області пам’яті. В цій процедурі х1, у1, х2, у2 — координати лівого верхнього та правого нижнього кутівпрямокутної області екрана, образ якої ми хочемо зберегти; ВitМар - адреса області пам’яті, в якій ми зберігаємо об’єкт.
2) Putlmage (x,y,BitMap,Mode) - відновлює збережений образ прямокутної області. Тут x, у - координати верхнього лівого кута області екрана,в яку ми хочемо помістити зображення; BitMap - адреса пам’яті, в якій було збережено зображення; Mode - режим накладання зображення на екран. Режимів накладання існує 5 (від 0 до 4), але самими цікавими для нас являються СоруРut(0) -заміщення новим об’єктом старого зображення та XOR (1) - «витирання» старого об’єкта. Крім цих основних процедур при використанні оперативної пам’яті для збереження об’єкта нам знадобляться ще дві. Перша допомагає визначити об’єм необхідної пам’яті в байтах для збереження прямокутного малюнку, а друга запрошує у системи відповідну область пам’яті. їх використовують разом наступним чином
{визначається необхідний розмір області пам’яті}
Size ImageSize(xl,yl,x2,y2);
{у системи запрошується оперативна пам’ять}
GetMem(BitMap,Size);
де x1,y1,x2,y2 - координати прямокутної області екрану, де знаходиться малюнок; Size - розмір необхідної пам’яті (змінна цілого типу); BitMap ~ адреса оперативної пам’яті, що виділяється системою (змінна типу вказівник для збереження адреси). Покажемо тепер, як за допомогою цих підпрограм можна побудувати об’єкт, що рухається, на прикладі задачі.
ЗАДАЧА № 638 (1)
Умова «Баскетбол». Зобразити на екрані відбивання від підлоги, стін та стелі м’яча, що зображається зафарбованим кругом. Для спрощення алгоритму траєкторію руху м’яча вважати ламаною лінією. Силою тертя повітря знехтувати.
Розв’язування У наведеній нижче програмі описані наступні константи R — радіус м’яча; Time - час затримки зображення на екрані (підбирається емпіричним шляхом залежно від типу комп’ютера).
Крім того використовуються наступні змінні х та у вказують на координати області екрана, куди виводиться, а потім звідки витирається зображення; Size та BitMap — використовуються для збереження зображення в оперативній пам’яті (дивись вище); Step_xта Step_y-задають крок, на який пересувається об’єкт при кожному наступному перемальовуванні (теж підбирається емпірично в залежності від типу ПЕОМ).
Перший раз м’яч малюється в лівому верхньому кутку екрану і напрямок його руху - зверху вниз, зліва направо, тому початкові координати області зображення х та у дорівнюють 0, а обидва кроки додатні. Далі, якщо об’єкт долітає до границі екрана, то крок змінюється на протилежний за знаком, і об’єкт починає рухатись у зворотному напрямку. Програма, що реалізує запропонований алгоритм, має наступний вигляд
Program Example_638_l;
uses crt,graph;
const R=20;
Time = 1000;
var gd,gminteger;
x,уinteger; Sizeinteger;
Step_x,Step_yinteger;
BitMappointer;
begin
x=0; y=0; Step_x=5; Step_y=5;
gd=VGA; gm=VGAHi;
XnitGraph (gd,gm,’’);
SetColor(brown);
SetFillStyle(1,brown);
FillEllipse(R,R,R,R);
Size - ImageSize(0,0,2*R,2*R);
GetMeM(BitMap,Size); GetImage(0,0,2*R,2*R,BitMap^);
repeat
delay(Time);
Putlmage(x,y,BitMap^,1);
x=x+Step_x; y=y+Step_y;
if (x+2*R >= getmaxx) or (x<=0) then Step_x=-Step_x;
if (y+2*R >= getmaxy) or (y<=0) then Step_y=-Step_y;
Putlmage(x,y,BitMap^,1);
until keypressed;
readkey;
CloseGraph;
end.
Третій метод, що дозволяє ще зменшити миготіння мультиплікаційного об’єкта на екрані, це використання графічних сторінок. Відомо, що при ініціалізації графічного режиму ми задаємо два параметри
Gd - тип графічного адаптера (CGA, EGA, VGA і т.д.);
Gm - режим роботи графічного адаптера.
Залежно від цих параметрів на екран можна виводити зображення з різною роздільною здатністю та палітрою. Крім того, існують деякі режими, що підтримують кілька графічних сторінок, кожна з яких може містити різні зображення. В один момент часу ми можемо бачити тільки одну сторінку, але в той самий момент можемо готувати складне зображення на інших сторінках і потім миттєво виводити їх на екран, зменшуючи таким чином миготіння (людина не бачить малювання окремих деталей пейзажу). Один з таких режимів Gm=VGAMed дозволяє програмісту виводити 16-кольорове зображення з роздільною здатністю 640 на 350 пікселів, при цьому він підтримує дві графічних сторінки.
Для того, щоб скористатися цими сторінками, ми можемо в програмі застосувати дві процедури
SetActivePage(Page) - задається номер активної сторінки (Page), тобто сторінки, на якій у даний момент буде будуватися зображення;
SetVisualPage(Page) - задається номер візуальної сторінки, тобто тієї сторінки, що являється видимою в даний момент.
У запропонованому режимі існує тільки дві сторінки, що мають номера 0 та 1, тому зміну сторінок можна виконувати змінною Page, що буде змінюватись за наступним законом Page = 1 - Page, причому активна сторінка стає видимою тільки після того, як на ній повністю побудовано нове зображення.
Покажемо застосування цього прийому на задачі.
ЗАДАЧА № 627
Умова Скласти програму, яка виводитиме на екран рух тіла, кинутого під кутом до горизонту. Опором повітря знехтувати.
Розв’язування Програма, що реалізує описаний алгоритм, наведена нижче. В ній використовуються наступні константи Color - колір тіла, що кинуто; Radius - радіус тіла; Time - затримка зображення на екрані (підбирається емпіричним шляхом в залежності від типу комп’ютера).
Program Example_627_m;
uses crt,graph;
const g=9.8;
Color = 2; Radius =20; Time = 500;
var gd,gminteger;
Pagebyte;
Vx,Vy,X,Yreal;
begin
gd=VGA; gm=VGAMed; InitGraph (gd,gm,”);
Vx=40; Vy=30; X=15; Y=160;
SetColor (Color); SetFillStyle(1,Color);
repeat
SetActivePage (Page);
ClearDevice;
Circle (round(X),round(Y),Radius);
FloodFill(round(X),round(Y),Color);
SetVisualPage (Page); Page=1-Page;
Delay (Time); X=X+Vx*0.1;
if Vy<>0 then Y=Y-Vy*0.1; Vy=Vy-g*0.1;
Until keypressed;
CloseGraph;
end.
Домашнє завдання
• сторінки 233-237 запропонованого підручника;
• задачі №630, №631, №640, 641.
1   2   3   4   5   6   7   8   9


База даних захищена авторським правом ©refs.in.ua 2016
звернутися до адміністрації

    Головна сторінка