Методи створення графічних об'єктів 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Методи створення графічних об'єктів



Лабораторна робота №7

МЕТОДИ СТВОРЕННЯ ГРАФІЧНИХ ОБ'ЄКТІВ

ЗАСОБАМИ МОВИ ПРОГРАМУВАННЯ PASCAL.

 


Зміст

1. Теоретичні відомості - 3 -

1.1. Ініціалізація графічного режиму. - 3 -

1.2. Базові процедури і функції. - 3 -

1.3. Екран і вікно в графічному режимі. - 5 -

1.4. Виведення найпростіших фігур. - 5 -

1.4.1. Виведення точки. - 5 -

1.4.2. Виведення лінії. - 6 -

1.5. Побудова багатокутників. - 7 -

1.5.1. Побудова прямокутників. - 7 -

1.5.2. Побудова багатокутників. - 7 -

1.6. Побудова дуг і кіл. - 9 -

1.7. Робота з текстом. - 10 -

1.7.1. Виведення тексту. - 10 -

1.7.2. Виведення чисельних значень. - 11 -

1.7.3. Шрифти. - 11 -

1.7.4. Вирівнювання тексту. - 12 -

1.8. Побудова графіків функцій. - 12 -

1.9. Цикли в графіці. Побудова випадкових процесів. - 14 -

1.10. Створення ілюзії руху. - 15 -

2. Приклад виконання лабораторного завдання. - 18 -

3. Завдання до виконання лабораторної роботи. - 24 -

4. Контрольні запитання. - 25 -

5. Варіанти завдань. - 25 -


МЕТОДИ СТВОРЕННЯ ГРАФІЧНИХ ОБ'ЄКТІВ ЗАСОБАМИ МОВИ ПРОГРАМУВАННЯ PASCAL.

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

Теоретичні відомості

Ініціалізація графічного режиму

Екран дисплея ПК є прямокутним полем, що складається з великої кількості точок. Дисплей може працювати в текстовому і графічному режимах. Але на відміну від текстового режиму в графічному режимі є можливість змінювати колір кожної точки.

Щоб зробити процес графічного програмування більш ефективним, фірма Borland International розробила спеціалізовану бібліотеку Graph (в цьому бібліотечному модулі міститься 79 графічних процедур, функцій, різних стандартних констант і типів даних), набір драйверів, що дозволяють працювати з різними типами моніторів, і набір шрифтів для виведення на графічний екран текстів різної величини і форми.

Апаратна підтримка графіки ПК забезпечується двома основними модулями: відеомонітором і відеоадаптером. Який би адаптер не був установлений на комп'ютері, ми можемо використовувати один і той же набір графічних процедур і функцій Турбо Паскаля завдяки тому, що їх кінцева настройка на конкретний адаптер здійснюється автоматично. Цю настройку виконують графічні драйвери.

Запуск і завершення роботи в графічній системі здійснюється таким чином:

1. Підключити модуль Graph (бібліотеку графічних процедур): uses Graph;

2. Встановити графічний режим:

- описуємо змінні, які визначають графічний драйвер і монітор:

var gd, gm: integer;

- задаємо команду ПК для самовибору значень змінних:

gd:=Detect;

( значення gm після команди gd:=detect; визначається автоматично)

- ініціалізували графічний режим:

InitGraph(gd, gm, ’вказується шлях до драйвера, чим докладніше, тим краще’ )

З цієї миті всі графічні засоби доступні користувачу.

3. Завершити роботу в графічній системі: CloseGraph.

 

Базові процедури і функції.

Для побудови зображень на екрані використовується система координат. Відлік починається від верхнього лівого кута екрану, який має координати (0,0). Значення Х (стовпець) збільшується зліва направо, значення У (рядок) збільшується зверху вниз.

Щоб будувати зображення, необхідно вказувати точку початку виведення. В текстових режимах цю точку вказує курсор, який присутній на екрані. В графічних режимах видимого курсора немає, але є невидимий поточний покажчик CP (Current Pointer). Фактично це той же курсор, але він невидимий.


Таблиця 7.1

Процедури модуля Graph.

Процедура Формат Дія
Setcolor Setcolor (а: word); Встановлює колір, яким здійснюватиметься малювання
Setbkcolor Setbkcolor (а: word); Встановлює колір фону
Setfillstyle Setfillstyle (a,b: word); a–стиль зафарбовування, b – колір Встановлює стиль і колір зафарбовування
Setlinestyle Setlinestyle (а,b,c:word); А – стиль лінії, b- зразок побудови лінії (може встановлюватися користувачем), С-товщина лінії Встановлює стиль і товщину лінії
Settextstyle Settextstyle (а,b,c:word); Встановлює шрифт, стиль і розмір тексту
Setfillpattern Setfillpattern (pattern:fillpatterntype;color:word); Pattern - маска Вибирає шаблон заповнення, визначений користувачем
Cleardivice Cleardivice Очищає екран і встановлює поточний покажчик в початок
Setviewport Setviewport(x1,y1,x2,y2:integer,clip:boolean); Встановлює попточне вікно для графічного виведення
Clearviewport Clearviewport Очищає вікно
Putpixel Putpixel (а,b,c:integer); Малює точку кольором с в (x,y)
Line Line(x1, y1, x2,y2:integer); Малює лінію від (x1, y1) до (x2,y2)
Rectangle Rectangle (x1, y1, x2, y2:integer); Малює прямокутник з діагоналлю від (x1, y1) до (x2, y2)
Bar Bar (x1, y1, x2, y2:integer); Малює зафарбований прямокутник
Bar3d Bar3d(x1,y1,x2,y2,d:integer,а:boolean); Малює тривимірну смугу (паралелепіпед)
Circle Circle (x,y,r: word); Малює коло радіусу r з центром в точці (x, у)
Arc Arc(x, у, а, b, r:integer); А, b- початковий і кінцевий кути в градусах   Малює дугу з початкового кута до кінцевого, використовуючи (x,y) як центр
Ellipse Ellipse (x, у, а, b, rx, ry: integer); А, b- початковий і кінцевий кути в градусах Малює еліптичну дугу від початкового кута до кінцевого, використовуючи (x, у) як центр
Fillellipse Fillellipse (x, у, rx, ry:integer); Rx, ry – вертикальна і горизонтальна вісі Малює зафарбований еліпс
Moveto Moveto (x, у:integer); Пересуває поточний покажчик в (x, у)
Moverel Moverel(x, у: integer); Пересуває поточний покажчик на задану відстань від поточної позиції, на x по горизонталі і на у по вертикалі
Outtext Outtext (text: string); Виводить текст від поточного покажчика
Outtextxy Outtextxy(x, у: integer, text: string); Виводить текст з (x, у)
Sector Sector(x, у, а, b, rx, ry: integer); а, b- початковий і кінцевий кути в градусах Малює і заповнює сектор еліпса

Таблиця 7.2

Функції модуля Graph

Getbkcolor Повертає поточний фоновий колір
Getcolor Повертає поточний колір
Getx Повертає координату x поточної позиції
Gety Повертає координату у поточної позиції
Getpixel Повертає колір крапки в (x, у)

Екран і вікно в графічному режимі.

По аналогії з текстовими режимами графічний екран може розглядатися як одне велике або дещо менших за розміром вікон. Після установки вікна вся решта площі екрану як би не існує, і все введення-виведення здійснюється тільки через вікно. В кожний окремий момент може бути активним тільки одне вікно. Якщо вікон декілька, за перемикання введення-виведення в потрібне вікно відповідає програміст.

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

Якщо вимагається створити вікно, слід скористатися процедурою

SetViewPort (x1, y1, x2, y2:integer, Clip:boolean);

де x1, y1 – координати лівого верхнього кута, x2, y2 – координати правого нижнього кута вікна. Параметр Clip визначає, чи малюнок відсікатиметься при виході за межі вікна (Clip:=True) чи ні (Clip:=False). Після створення вікна за точку відліку приймається верхній лівий кут вікна, що має координати (0,0).

Координатну систему повного екрану можна відновити, зокрема, за допомогою ClearDevice або задавши в процедурі установки вікна максимально можливі значення:

SetViewPort(0, 0, GetMaxX, GetMaxY, true);

Необхідно пам'ятати, що на відміну від текстових вікон графічні вікна після команди установки фону SetBkColor і очищення за допомогою ClearViewPort міняють фон разом із загальним фоном екрану. Тому фон (точніше «зафарбовування») графічного вікна слід встановлювати за допомогою процедур SetFillStyle і SetFillPattern.

Виведення найпростіших фігур.

Виведення точки.

Які б зображення не виводилися на екран, всі вони побудовані з точок, теоретично можна створити будь-яке зображення шляхом побудови точок певного кольору в потрібному місці екрану. В бібліотеці Graph виведення точки здійснюється процедурою

PutPixel (x, у: integer, color:word);

де x, у: координати розташування точки, color – колір.

Можливі значення Color приведені в таблиці:

Таблиця 7.3

Шкала кольорів

Колір Код Колір Код
Black – чорний   Darkgray – темно-сірий  
Blue – синій   Lightblue – голубий  
Green - зелений   Lightgreen – яскраво-зелений  
Gyan – бірюзовий   Lightgyan – яскраво-бірюзовий  
Red – червоний   Lightred – яскраво-червоний  
Magenta – малиновий   Lightmagenta – яскраво-малиновий  
Brown – коричневий   Yellow – жовтий  
Lightgray – світло-сірий   White – білий  

Приклад.

PutPixel(320, 240, 4);

PutPixel(320,240, Red); виводить в центрі екрану точку червоного кольору.

 

Виведення лінії.

З точок будуються лінії (відрізки прямих). Це можна зробити за допомогою процедури

Line (x1, y1, x2,y2:integer);

де x1, y1 – координати початку, x2,y2 - координати кінця лінії, наприклад Line(1,1,600,1).

В процедурі Line немає параметра для установки кольору. В цьому випадку колір задається процедурою SetColor (колір: word); де колір з таблиці 7.3.

Приклад.

SetColor(Gyan);

Line(1,1,600,1);

Для креслення ліній застосовуються ще дві процедури: LineTo і LineRel. Процедура LineTo (x,y: integer) будує лінію з точки поточного положення покажчика в точку з координатами x,y. Процедура LineRel (dx,dy: integer) проводить лінію від точки поточного розташування покажчика (x, у) в точку (x+dx, y+dy).

Турбо Паскаль дозволяє креслення лінії самого різного стилю: тонкі, широкі, штрихові, пунктирні і т.д. Установка стилю проводиться процедурою SetLineStyle(а,b,c: word), де а встановлює тип рядка можливі значення якого приведені в таблиці 7.4; b – зразок, с – товщина лінії, визначувана константами, вказаними в таблиці 7.5. Якщо застосовується один із стандартних стилів, то значення b рівне 0. Якщо користувач хоче активізувати власний стиль, то значення b =4. В цьому випадку користувач сам вказує примітив (зразок), з якого будується лінія.

Наприклад:

SetLineStyle(1,0,1);

Line(15,15, 150,130);

або

SetLineStyle(UserBitLn,$5555,ThickWidth);

Line(15,15, 150,130);

Таблиця 7.4

Константа Значення Опис
Solidln   Безперервна лінія
Dottedln   Лінія з крапок
Centerln   Лінія з крапок і тире
Dashedln   Штрихова лінія
Userbitln   Тип користувача

Таблиця 7.5

Константа Значення Опис
Normwidth   Нормальна товщина (1піксель)
Thickwidth   Жирна лінія (3 пікселі)

Приклад: Написати програму, яка креслить трикутник червоною лінією в центрі екрану.

Program treug;

uses graph; { підключення бібліотеки графічних процедур}

var gd,gm: integer; {опис змінних, визначаючих графічний драйвер і монітор}

Begin

gd:=detect; {визначення значень змінних по вибору ПК}

initgraph(gd, gm, ‘ с/bp’); {ініціалізація графічного режиму}

SetColor(4); {задання кольору лінії}

SetLineStyle(1,0,3); {задання стилю лінії}

Line(320, 240, 320, 180);

Line(320, 240, 390, 240);

Line(390, 240, 320, 180);

End.

 

Побудова багатокутників.

Побудова прямокутників.

Для побудови прямокутних фігур є декілька процедур.

Перша з них – викреслювання одновимірного прямокутника:

Bar (x1, y1, x2, y2:integer),

яка малює зафарбований прямокутник. Колір зафарбовування встановлюється за допомогою SetFillStyle. Ще одна ефектна процедура:

Побудова багатокутників.

Багатокутники можна малювати самими різними способами, наприклад за допомогою процедури Line. Проте в Турбо Паскалі є процедура DrawPoly, яка дозволяє будувати будь-які багатокутники лінією поточного кольору, стилю і товщини. Вона має формат

Begin

gd:= detect;

Initgraph(gd, gm, ‘ с/bp’);

xm:=GetmaxX;

ym:=GetmaxY;

xmaxD4:=xm div 4;

ymaxD4:= ym div 4;

{визначення координат вершин}

pp[1].x:= xmaxD4;

pp[1].y:= ymaxD4;

pp[2].x:= xm - xmaxD4;

pp[2].y:= ymaxD4;

pp[3].x:= xm div 2;

pp[3].y:= ym - ymaxD4;

pp[4]:=pp[1];

SetColor(4); {колір для креслення}

DrawPoly(4,pp); {4 – кількість перетинів +1}

readln;

CloseGraph

End.

В результаті роботи програми на екрані з'явиться червоний трикутник на чорному фоні. Змінити фон усередині трикутника можна за допомогою процедури

Const

Star:array[1..18]integer=(75,0,100,50,150,75,100,100,75,150,50,100,0,75,50,50,75,0);

Var

gd, gm: integer;

Begin

gd:= detect;

initgraph(gd, gm, ‘ с/bp’);

SetFillStyle(1,2);

FillPoly(9,Star); {9 – кількість перетинів + 1}

CloseGraph;

End.

Побудова дуг і кіл.

Процедура креслення кола поточним кольором має наступний формат:

Cicrle(x, у, r: word),

де x, у – координати центру кола, r – її радіус.

Наприклад, фрагмент програми забезпечить виведення яскраво-зеленого кола з радіусом 50 пікселів і центром в точці (450,100):

SetColor(LightGreen);

Circle(450, 100, 50);

Дуги можна креслити за допомогою процедури

Робота з текстом.

Виведення тексту.

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

Процедура OutText(Textst: string) виводить рядок тексту, починаючи з поточного положенням покажчика. Наприклад,

OutText(‘натисніть будь-яку клавішу”);

Недолік цієї процедури – не можна вказати довільну точку початку виведення.

В цьому випадку зручніше користуватися процедурою

Begin

Str(Int, Buf);

IntSt:= Buf;

end;

2) function RealSt(R: real, Dig, Dec: integer): string;

var Buf: string[20];

Begin

Str(R: Dig: Dec, Buf);

RealSt:= Buf;

end;

Ці функції вказуються як параметри в процедурах OutText і OutTextXY. Наприклад:

x:= 5.295643871;

OutTextXY(20, 20, ‘x=’+RealSt(x,11,9));

В результаті на екрані з'явиться x=5.29564443871

 

Шрифти.

Виведення тексту в графічному режимі може здійснюватися різними стандартними (таб. 7.6) і призначеними для користувача шрифтами.

Розрізняють два типи шрифтів: растрові і векторні. Растровий шрифт задається матрицею точок, а векторний – рядом векторів, що становлять символ.

За замовчуванням після ініціалізації графічного режиму встановлюється растровий шрифт DefaultFont, який, як правило, є шрифтом, драйвером клавіатури, що використовується.

Більшість стандартних шрифтів не містить російських символів. Розробка ж власних шрифтів – досить складний і трудомісткий процес. Він може бути прискорений, якщо скористатися спеціалізованими пакетами TurboFont, BgiToolKit.

Встановити потрібний шрифт можна процедурою

SetTextStyle(Font,d,c:word),

де Font – вибраний шрифт, d – напрям (горизонтальне або вертикальне), с – розмір символів, що виводяться. Можливі значення двох перших параметрів представлені в Таблиці 7.6.

Таблиця 7.6

Стандартні шрифти

Шрифт Файл
Triplexfont Trip.chr
Smallfont Litt.chr
Sansseriffont Sans.chr
Gothicfont Goth.ch

 

При організації вертикального виведення необхідно враховувати, що якщо не встановити точку початку виведення за допомогою MoveTo, то текст починається з нижнього рядка екрану і продовжується вгору. Величина символів встановлюється коефіцієнтом с. Якщо с=1, то символ будується в матриці 8х8, якщо с= 2, то матриця 16х16 і т.д. до 10-кратного збільшення.

Наприклад виведемо 2 рядки (вертикальний і горизонтальний) шрифтом DefaultFont різної величини:

SetTextStyle(0,11); {букви стандартної величини}

OutTextXY(200,200, ‘Вертикальний рядок’);

SetTextStyle(0,0,2); {розмір букв збільшений}

OutTextXY(200,220, ‘Горизонтальний рядок’);

Вирівнювання тексту.

В деяких випадках потрібно в межах одного рядка виводити символи вище або нижче один за одного. Вирівнювання тексту виконується за допомогою процедури

SetTextJustify(Horiz, Vert: word)

як по вертикалі, так і по горизонталі за допомогою задання параметрів Horiz і Vert (можливі значення в таб.і 7.7.

Таблиця 7.7

Параметри вирівнювання.

Параметр Значення Коментарі
Горизонтальне вирівнювання
Lefttext   Вирівняти вліво
Centertext   Центрувати
Righttext   Вирівнятивуправо
Вертикальне вирівнювання
Bottomtext   Перемістити вниз
Centertext   Центрувати
Toptext   Перемістити вгору

Як приклад виведемо x2:

SetTextJustify(1, 1);

OutTextXY(100,100, ‘X’);

SetTextJustify(1, 0);

OutTextXY(108,100, ‘2’);

Побудова графіків функцій.

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

Дотепер при створенні малюнків використовували тільки перший квадрант системи координат. Для побудови більшості функцій в необхідному інтервалі зміни необхідно працювати хоча б в двох квадрантах. В загальному випадку корисно зображати систему координат в будь-якій частині площини, але найбільш наочно розташовувати її в центрі екрану. В таких випадках, встановивши початок координат в точці (x0, y0) на екрані, можна координати (x, у) довільної точки кривої визначати різницею (x-x0, y-y0). Після цього в програмі можна вживати не тільки позитивні, але і від’ємні значення.

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

Вибрати масштаб збільшення можна таким чином:

- визначити горизонтальний і вертикальний розміри графіка (для цього вводяться межі області значень і визначаються максимальне і мінімальне значення функції на заданій області визначення, потім обчислюються різниці максимального і мінімального значень аргументів і функції, які і є горизонтальними і вертикальними розмірами графіка відповідно);

- визначити масштаб (спочатку визначаються масштаби зображення по горизонталі і вертикалі з врахуванням розмірів вибраного екрану по формулі:

масштаб(г/в)= розмір екрану (по г/в) / розмір графіка (по г/в),

потім з них вибирається менший, який і приймається за необхідний масштаб. В нашому випадку графічний екран має розміри 640 на 480.

У будь-якому випадку, щоб висвітити на екрані точку, треба узяти x, обчислити по даній абсцисі у і виконати малювання точки.

Оскільки на екрані можна одержати лише обмежену кількість значень х, то їх перебираємо за допомогою циклу.

Приклад. Побудувати графік функції y=x2

Варіант 1

program f;

uses graph;

var gd, gm: integer;

x, у: real;

Begin

gd:= detect;

initgraph(gd, gm, ‘c/ bp’);

SetColor(5);

Line(0, 240, 640, 240);

Line(320, 0, 320, 480);

x:= -20;

While x<=20 do

Begin

у:= -Sqr(x);

PutPixel(x *5 + 320, y*5 +240, 15);

x:=x + 0.01; end; end.

Варіант 2

program f;

uses graph, crt;

var gd, gm: integer;

x, у, mx, my, m,x1, x2, y1, y2,h: real;

function f(x:real): real;

Begin

f:= Sqr(x);

end;

clrscr;

Write(‘ Введіть межі відрізка’ ); Read(x1, x2);

y1:=f(x1);

y2:=f(x2);

mx:=640 /(x2 –x1);

my:=480 / (y2 – y1);

If mx< my Then m:=mx else m:= my;

h:= 1/m; x:=x1;

gd:= detect;

initgraph(gd, gm, ‘c/ bp’);

SetColor (5);

Line(0, 240, 640, 240);

Line(320, 0, 320, 480);

While x<= x2 do

Begin

у:= -f(x);

PutPixel(x *m +320, y*m +240, 15);

x:= x+ h;

end;

End.

Розглянемо побудову графіка функції, заданої параметрично. На відміну від функції, заданої в явному виді y=f(x), параметр х в цьому випадку також є функцією, залежною від деякого значення.

Приклад. Побудувати графік функції (кардіоїда).

x = а cos t (1+ cost), у = а sin t(1+cost), а > 0, t I [0, 2p)

Приведемо фрагмент програми:

SetColor (5);

Line(0, 240, 640, 240);

Line(320, 0, 320, 480);

t:=0;

а:=3;

While t<= 3.1415 do

Begin

x:=a*cos(t)*(1+cos(t));

у:= - а sin(t)*(1+cos(t));

PutPixel(x*5 +320, y*5 +240, 15);

x:= x+ 0.01;

end;

 

Randomize

x:=random(640);

у:=Random(480);

с:=Random(15);

PutPixel(x, у, с);

Приклад. Намалювати 5000 точок випадкового кольору у випадковому місці.

Фрагмент програми:

For i:=1 to 5000 do

Begin

x:=Random(640);

у:=Random(480);

с:=Random(15);

PutPixel(x, у, с);

end;

 

Створення ілюзії руху.

Створити видимість руху зображення на екрані можна декількома способами. Розглянемо два з них.

I спосіб. Імітація руху об'єкту на екрані за рахунок багатократного виконання програмою набору дій: намалювати – пауза – стерти (намалювати в тому ж місці кольором фону) – змінити координати положення малюнка.

Перед початком складання програми треба продумати опис об'єкту, що «рухається», характер зміни координат, що визначають поточне положення об'єкту, діапазон зміни і крок.

Вправа 1. Вивчити текст програми, яка малює модель атома. Перевірити її дію.

program Model_At;

uses Crt, Graph;

Const

Ra=100 ;{радіус атома}

Rc=10; {радіус ядра}

Re=4; {радіус електрона}

k=0.5; {коефіцієнт стиснення орбіт електронів}

Dr=30; {параметр зміни координат електрона}

Step1=0.2; {крок зміни положення електрона}

Step=100; {час затримки – швидкість руху електронів}

Var

cx, су, у, y1, y2, x, x1, x2, x3, y3:integer;

I, I1, I2, I3: real; gd, gm: integer;

Begin

clrscr;

gd:=detect; initgraph(gd, gm, ‘ шлях до драйвера’ );

SetTextStyle(0, 0, 2);

OutTextXY(200, 30, ‘ Модель атома’ );

cx:= GetMaxX div 2; {визначити центр экрана- положення ядра}

су:= GetMaxY div 2;

PieSlice(cx, су, 0, 360, Rc); {намалювати ядро атома}

SetColor(Red);

SetLineStyle(0, 0, 3);

Line(cx-7, су, cx+7, су);

Line(cx, cy-5, cx, cy+5);

SetLineStyle(0,0,1);

SetFillStyle(1, 1);

I:=Pi/4; {задати початкове положення 4 електронів}

I1:= - Pi/4;

I2:= - Pi/2;

I3:= Pi/2;

SetTextStyle(0, 0, 1);

SetColor(jellow);

OutTextXY(180, 420, ’Для відміни натискуйте будь-кого клавишу’ );

While not KeyPressed do {повторювати, поки не натискує будь-яка клавіша }

Begin

{ визначити координати електронів}

x:=Round (Ra*cos(I)) +cx;

у:= Round (k+Ra*sin(I)) +cy;

x1:= Round((Ra+Dr)*cos(I1))+cx;

y1:= Round (k*(Ra+Dr)*sin(I1)) +cy;

x2:= Round((Ra-Dr)*cos(I2))+cx;

y2:= Round (k*(Ra-Dr)*sin(I2)) +cy;

x3:= Round((Ra-Dr)*cos(I3)*2.3)+cx;

y3:= Round (k*(Ra-Dr)*sin(I3)*2.3) +cy;

{встановити синій колір і намалювати електрони}

SetColor(1);

Circle (x, у, Re);

PutPixel(x, у, 2);

Circle (x1, y1, Re);

PutPixel(x1, y1, 2);

Circle (x2, y2, Re);

PutPixel(x2, y2, 2);

Circle (x3, y3, Re);

PutPixel(x3, y3, 2);

Delay(Step);

{намалювати електрони кольором фону}

SetColor(0);

Circle (x, у, Re);

PutPixel(x, у, 2);

Circle (x1, y1, Re);

PutPixel(x1, y1, 2);

Circle (x2, y2, Re);

PutPixel(x2, y2, 2);

Circle (x3, y3, Re);

PutPixel(x3, y3, 2);

{задати зміну положення електронів}

I:=I + Step1;

I1:=I1 – Step1;

I2:=I2 + Step1;

I3:=I3 + Step1;

end; {кінець циклу}

CloseGraph;

End.

II спосіб. Ілюзія руху створюється за допомогою спеціальних процедур і функцій.

Функція ImageSize(x1, y1, x2, y2: integer):word повертає розмір пам'яті в байтах, необхідний для розміщення прямокутного фрагмента зображення, де x1,y1 – координати лівого верхнього і x2, y2 – правого нижнього кутів фрагмента зображення.

Процедура GetImage(x1, y1, x2, y2:integer, var Buf) поміщає в пам'ять копію прямокутного фрагмента зображення, де x1,y2 – координати кутів фрагмента зображення, Buf – спеціальна змінна куди буде поміщена копія відеопам'яті з фрагментом зображення. Buf повинна бути не менше значення, що повертається функцією ImageSize з тими ж координатами.

Процедура PutImage(x1, y1, x2, y2:integer, var Buf, Mode:word) виводить в задане місце екрану копію фрагмента зображення, раніше поміщену в пам'ять процедурою GetImage. X, У – координати лівого верхнього кута того місця на екрані, куди буде скопійований фрагмент зображення; Buf – спеціальна змінна, звідки береться зображення, Mode – спосіб копіювання. Координати правого нижнього кута не вказуються, оскільки вони повністю визначаються розмірами копії зображення, що виводиться на екран. Координати лівого верхнього кута можуть бути будь-ким, лише б тільки копія уміщалася в межах екрану (якщо копія не розміщується на екрані, то вона не виводиться, і екран залишається без змін). Параметр Mode визначає спосіб взаємодії розміщуваної із зображенням, що вже є на екрані (таб. 7.8).

Таблиця 7.8

Константа Значення Операція Пояснення
Normalput   Заміна існуючого на копію Стирає частину екрану і на це місце поміщає копію
Xorput   Виняткове або Малює збережений образ або стирає раніше намальований, зберігаючи фон
Orput   Об'єднувальне або Накладає збережений образ на існуючий
Andput   Логічне і Об'єднує збережений образ і вже існуючий на екрані
Notput   Інверсія зображення Те ж саме, що і 0, тільки копія виводиться в інверсному вигляді

Вправа 2. Вивчити програму, яка малює зоряне небо і переміщає на його фоні малюнок НЛО. Перевірити дію програми.

program NLO;

uses crt, graph;

Const

k=20;

Pause=50;

Var

gd,gm,xmin,xm,ymin,ym,x,у,tx,ty,rx,ry,size,i,dx,dy,width,height:integer;

sauser:Pointer;

Begin

Randomize;

gd:= detect; initgraph(gd, gm, ‘ шлях до драйвера ”);

SetTextStyle(0, 0, 2);

OutTextXY(50, 10, ‘ Демонстрація руху НЛО’ );

{Малюємо НЛО}

x:=R*5;

у:=R*2;

xm:=GetmaxX- 5;

ym:=GetmaxY-25;

Ellipse(x, у, 0, 360, R, R div 3+2);

Ellipse(x, y-4, 190, 357, R, R div 3);

Line(x + 7, у - 6, x + 10, у - 12);

Line(x -7, у - 6, x + 10, у - 12);

Circle(x + 10, у - 10, 2);

Circle(x -10, у - 10, 2);

FloodFill(x+1, y+4, White);

{визначаємо габарити НЛО і поміщаємо в спеціальну динамічну змінну}

Tx:= x-R;

Ty:=y-14;

Rx:;=x+R;

Ry:=y+R div3 +3;

Width:=Rx-Tx+1;

Size:=ImageSize(Tx, Ty, Rx, Ry);

GetMem(sauser, Size);

GetImage(Tx, Ty, Rx, Ry, sauser^);

{стираємо побудоване зображення}

PutImage(Tx, Ty, sauser^, XorPut);

{малюємо зоряне небо}

SetStyle(1, blue); {встановити стиль і колір зафарбовування голубе небо}

SetColor(White);

{накреслити прямокутник і відкрити вікно}

Rectangle(xmin, ymin, GetmaxX, GetmaxY);

SetViewPort(xmin, ymin, GetmaxX, GetmaxY, ClipOn);

FloodFill(xmin+1, ymin+1, White);

For i:=1 to 500 do {намалювати 500 зірок білого кольору}

PutPixel(Random(GetmaxX),

Random(GetmaxY- ymin), 15);

{задаємо початкове положення НЛО}

x:=xm div 3 – xmin;

у:=ym div 3 – ymin;

dx:=6;

dy:=6;

Repeat {цикл: повторювати, поки не натискує будь-яка клавіша}

PutImage(x, у, sauser^, XorPut); {зображаємо об'єкт}

Delay (Pause); { затримка}

PutImage(x, у, sauser^, XorPut); {після паузи стираємо об'єкт}

{переміщаємо об'єкт}

If (x<xmin) Or (y<ymin) Or (x+Width +1> xm) Or (y+Height +1> ym) Then

begin {якщо об'єкт зміщується вліво-вверх за межі вікна, змінити координати так, щоб він залишався у вікні}

If (x- Dx< xmin) then x:= xmin else x:= x- Dx;

If (y- Dy< ymin) then у:= ymin else у:= y- Dy;

Dx:= GetmaxX div 10 - Random(GetmaxX div 4);

Dy:= GetmaxY div 10 - Random(GetmaxY div 4);

End

Else

begin { якщо об'єкт зміщується вправо-вниз за межі вікна, змінити координати так, щоб він залишався у вікні}

If (x+Dx<xm) then x:=x+Dx else x:=Random(GetmaxX)-Random(GetmaxXdiv4);

If (у+Dy<ym) then у:=у+Dy else у:=Random(GetmaxY)-Random(GetmaxYdiv3);

end;

until KeyPressed; {завершити, як тільки натискуватиме клавіша }

FreeMem (sauser, Size);

Closegraph; end; end.

Begin

{Ініціалізація графічного режиму}

gd:=VGA; gm:=VGAHi;

InitGraph (gd,gm,'egavga.bgi');

{Визначення центра екрану}

x_centr:= getmaxx div 2;

y_centr:= getmaxy div 2;

{Малювання статичної частини малюнку}

SetColor(brown);

SetFillStyle(1,brown);

{Малювання циферблату коричневого кольору}

FillEllipse(x_centr,y_centr,R,R);

Ang_time:=-90;

{Встановлення кольору малювання, стилю та вирівнювання тексту}

SetColor(yellow);

SetTextJustify(CenterText, CenterText);

SetTextStyle(DefaultFont, HorizDir, 2);

{Малювання поділок жовтого кольору та цифр}

for i:=1 to 12 do

Begin

Ang_time:=Ang_time+30;

x_time:=round(x_centr+185*cos(Ang_time*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_min);

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, y1, x2, y2 - координати лівого верхнього та правого нижнього кутів прямокутної області екрана, образ якої ми хочемо зберегти;

-BitMap - адреса області пам'яті, в якій ми зберігаємо об'єкт.

2. PutImage (x,y,BitMap,Mode) - відновлює збережений образ прямокутної області.

Тут:

- x, y - координати верхнього лівого кута області екрана, в яку ми хочемо помістити зображення;

-BitMap - адреса пам'яті, в якій було збережено зображення;

-Mode - режим накладання зображення на екран. Режимів накладання існує 5 (від 0 до 4), але самими цікавими для нас являються CopyPut (0) - заміщення новим об'єктом старого зображення та XOR (1) - "витирання" старого об'єкта.

Крім цих основних підпрограм при використанні оперативної пам'яті для збереження об'єкта нам знадобляться ще дві. Перша допомагає визначити об'єм необхідної пам'яті в байтах для збереження прямокутного малюнку, а друга запрошує у системи відповідну області пам'яті. Їх використовують разом наступним чином:

{визначається необхідний розмір області пам'яті}

Size:= ImageSize(x1,y1,x2,y2);

{у системи запрошується оперативна пам'ять }

GetMem(BitMap,Size);

де x1, y1, x2, y2 - координати прямокутної області екрану, де знаходиться малюнок;

Size - розмір необхідної пам'яті (змінна цілого типу);

BitMap - адреса оперативної пам'яті, що виділяється системою (змінна типу вказівник для збереження адреси).

Покажемо тепер, як за допомогою цих підпрограм можна побудувати об'єкт, що рухається, на прикладі наступної задачі.

 

Задача 2."Баскетбол". Зобразити на екрані відбивання від підлоги, стін та стелі м'яча, що зображається зафарбованим кругом. Для спрощення алгоритму траєкторію руху м'яча вважати ламаною лінією. Силою тертя повітря знехтувати.



Поделиться:


Последнее изменение этой страницы: 2016-04-26; просмотров: 89; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.140.198.43 (0.413 с.)