МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”
кафедра
"Автоматика та телемеханіка"
Графічно-розрахункова робота
з курсу
"Програмування комп'ютерної графіки"
"Побудова графіка функції та рухомого зображення на екрані комп'ютера"
План:
Частина 1: Побудова графіка функції
1. Завдання
2. Розрахунок функціональних залежностей для побудови графіка
3. Список ідентифікаторів програми
4. Блок-схеми основної програми та окремих процедур і функцій
5. Текст програми
6. Висновок
Частина 2: Побудова рухомого зображення і графіка функції у одному вікні
1. Завдання.
2. Розрахунок матриці перетворень для рухомого зображення.
3. Список ідентифікаторів програми
4. Блок-схеми основної програми та окремих процедур та функцій.
5. Текст програми
6. Результат виконання програми
7. Висновок
Частина 1: Побудова графіка функції
1.ЗАВДАННЯ
Побудувати графік функції(таблиця 1), заданої таблично. Графік повинен відображати результати розрахунків, які записані у файлі на диску. Масштаб розмітки осей координат графіка повинен відповідати реальним результатам розрахунків. Параметри для побудови графіка визначені в таблиці 2. Варіант завдання визначає викладач.
Необхідно передбачити “плаваючий” центр координат – основну частину екрану мають займати чверті, в яких знаходиться графік функції.
Таблиця 1.
N% п/п
Функція
Інтервал
Крок
21
Y=x8+7*x4-3
x=[0;2]
h=0.01
Таблиця 2.
N% п/п
Тип лінії
Товщина лінії
(пік селів)
Колір лінії
Шрифт розмітки осей графіка
23
- - - - - - - - - - -
5
Yelllow
SansSerif
2.РОЗРАХУНОК ФУНКЦІОНАЛЬНИХ ЗАЛЕЖНОСТЕЙ ДЛЯ ПОБУДОВИ ГРАФІКА
Оскільки реальні координати графіка функції, що виводиться на екран можуть бути або значно більшими, або значно меншими за машинні координати екрану монітору, необхідно визначити значення масштабних коефіцієнтів стискання або розтягу для функції, що виводиться на екран.
Позначимо максимальні та мінімальні значення реальних координат по осях X та Y - b, a, ymax, ymin.
Відступи від країв екрану задаємо як skx*valuex та sky*valuey, де skx, sky – мінімальні відступи для розширення 320*200; valuex та valuey – коефіцієнти перетворення для даного розширення.
Приймаємо машинний робочий діапазон для графіка функції максимально можливий для даного адаптера по осі X та Y. Тоді масштабні коефіцієнти для графіка по осях X та Y дорівнюють, відповідно:
При виведенні графіка функції на екран монітору значення реальних координат заданої функції домножуємо на масштабні коефіцієнти і додаємо координати машинного центру координат (X0,Y0):
Центр координат визначаємо за формулами :
3. СПИСОК ІДЕНТИФІКАТОРІВ ПРОГРАМИ
СПИСОК :
Driver
Mode
ERROR
A
B
H
STDIMX
STDIMY
YMAX
YMIN
X
Y
KX
KY
MAXRX
MAXRY
X0
Y0
BUFMIN
POZ
POZX
POZY
STEP
GX
GY
MAXGX
MAXGY
SKY
SKX
ARROW
VALUEX
VALUEY
MAXGZONEX
MAXGZONEY
I
YCOUT
XCOUT
TEXT
f
Topval
ПОЯСНЕННЯ ІДЕНТИФІКАТОРІВ ЗМІННИХ :
Driver – характеризує тип графічного драйвера
Mode – визначає режим роботи графічного адаптера
Error – код помилки
A – ліва межа табулювання
B – права межа табулювання
H – крок табулювання
Stdimx – найменше розширення по х
Stdimy – найменше розширення по у
Ymax – максимальне значення функції
Ymin – мінімальне значення функції
X – координата по осі абсцис
Y – координата по осі ординат
Kx – коефіцієнт перетворення по осі абсцис
Ky – коефіцієнт перетворення по осі ординат
Maxrx – проміжок на якому графік лежить по осі абсцис
Maxry – проміжок на якому графік лежить по осі ординат
X0 – координата графічного центра по осі абсцис
Y0 – координата графічного центра по осі ординат
Bufmin – покрокове сумування значень по осі абсцис чи
ординат
Poz – положення тексту при виводі по осі абсцис чи ординат
Pozx – положення графічного центру по осі абсцис для
розмітки осі абсцис
Pozy – положення графічного центру по осі ординат для
розмітки осі ординат
Step – крок табулювання для розмітки осей абсцис та ординат
Gx – графічна координата по осі абсцис
Gy – графічна координата по осі ординат
Maxgx – максимальне горизонтальне розширення екрану
Maxgy – максимальне вертикальне розширення екрану
Sky – відступ по осі ординат для мінімального розширення
Skх – відступ по осі абсцис для мінімального розширення
Arrow – розмір стрілок
Valuex – коефіцієнт перетворення екрану по осі абсцис
відносно мінімального розширення
Valuey - коефіцієнт перетворення екрану по осі ординат
відносно мінімального розширення
Maxgzonex – область що займатиме графік по осі абсцис на
екрані
Maxgzoney – область що займатиме графік по осі ординат на
екрані
I – лічильник
Ycout – лічильник для розмітці осі ординат
Xcout – лічильник для розмітці осі абсцис
Text – змінна для виводу тексту розмітки
f – ідентифікатор файлу де записані точки проходження графіка функції
Topval – задає відстань між паралельними лініям для фіксованої товщини основної лінії графіка функції
ПОЯСНЕННЯ ПРОЦЕДУР ТА ФУНКЦІЙ :
INITGRAPH – ініціалізує графічний режим
GRAPHRESULT – тестує роботу графічного режиму
Chartstuff – функція, що задає графік
Coordinate – процедура розмітки осей
BuilderХ – процедура побудови осі абсцис
BuilderY – процедура побудови осі ординат
Str – процедура перетворення числового значення у текстове
Settextstyle – процедура, що задає тип шрифта та його положення
Setcolor – процедура ,що задає колір ліній
Outtextxy – процедура виводу тексту на екран у вказаній точці
ChartPoints – процедура розрахунку точок проходження графіка функції
ChartBuilder – процедура побудови графіка функції
Lineto – процедура побудови ліній від поточного положення вказівника до вказаної точки
Setlinestyle – процедура, що задає тип ліній
Moveto – процедура, що переміщає вказівник у вказане положення
Parameter – процедура для визначення коефіцієнтів перетворення графіку
Derivative – похідна функції, що задає графік
4. БЛОК-СХЕМИ ОСНОВНОЇ ПРОГРАМИ ТА ОКРЕМИХ ПРОЦЕДУР І ФУНКЦІЙ
Функція Chartstuff
Функція Derivative
Процедура BuilderX
Процедура BuilderY
Процедура Coordinate
1
2
3
так ні
4
5
так ні
6
7
так ні
8
9
так ні
10
11 12
13
15
14
16
17
ні
так 18 19
20
так ні
21
23
22
24
26
25
27
28
29
ні
так 30 31
32 38
так ні
33
34
35
36
37
Процедура Parameter
Процедура ChartPoints
ні
так
1 Процедура ChartBuider
4
2
5
3
6
7
8
ні
9
11 так
10
12
13
15
14
16
17
18
19
20
21
Головна програма
(Процедура Chart)
1 4
2
5
3
7 6
9
8
10 11
так ні
12
13
14
15 ні
так 16 так 17 ні
18
19 так ні
20
21
22 ні
так 24
23
так ні
26 25 27
так ні
28
29
31 30
32
5.ТЕКСТ ПРОГРАМИ
Program Rozrahunkova_Chart;
Uses Graph,crt;
var Driver,Mode,Error:integer;
f:text;
a,b,h,stdimx,stdimy,ymax,ymin,x,y,kx,ky,maxrx,maxry,x0,y0,bufmin,poz,pozx,pozy,step:real;
gx,gy,gxt1,gyt1,gxt2,gyt2:real;
maxgx,maxgy,sky,skx,arrow,valuex,valuey,maxgzonex,maxgzoney:integer;
i,ycout,xcout:integer;
topval:real;
text:string;
{Specified Function for chart building start}
function ChartStuff(x:real):real;
begin
ChartStuff:=x*x*x*x*x*x*x*x+7*x*x*x*x-3;
end;
{Specified Function for chart building start}
{Specified Derivative Function}
function Derivative(x:real):real;
begin
derivative:=8*x*x*x*x*x*x*x+28*x*x*x;
end;
{Specified Derivative Function}
{Building OX and OY and Writing Coordinates Start}
procedure Coordinate(x0,y0:real);
procedure BuilderX(x0,y0:real);
begin
moveto(trunc(x0),trunc(y0));
lineto(skx*valuex,trunc(y0));
moveto(trunc(x0),trunc(y0));
lineto(maxgx-skx*valuex,trunc(y0));
lineto(maxgx-trunc(skx*valuex/2),trunc(y0));
lineto(maxgx-trunc(skx*valuex/2)-arrow*valuex,trunc(y0)+arrow*valuey);
moveto(maxgx-trunc(skx*valuex/2),trunc(y0));
lineto(maxgx-trunc(skx*valuex/2)-arrow*valuex,trunc(y0)-arrow*valuey);
outtextxy(maxgx-trunc(skx*valuex/2)-arrow*valuex,trunc(y0)+arrow*arrow*valuey,'X');
end;
procedure BuilderY(x0,y0:real);
begin
moveto(trunc(x0),trunc(y0));
lineto(trunc(x0),maxgy-sky*valuey);
moveto(trunc(x0),trunc(y0));
lineto(trunc(x0),sky*valuey);
lineto(trunc(x0),trunc(sky*valuey/2));
lineto(trunc(x0)-arrow*valuex,trunc(sky*valuey/2)+arrow*valuey);
moveto(trunc(x0),trunc(sky*valuey/2));
lineto(trunc(x0)+arrow*valuex,trunc(sky*valuey/2)+arrow*valuey);
outtextxy(trunc(x0)+arrow*arrow*valuex,trunc(sky*valuey/2)+arrow*valuey,'Y');
end;
begin
x0:=trunc(skx*valuex-a*kx);
y0:=trunc(sky*valuey+ymax*ky);
if(x0<=skx*valuex)
then
x0:=skx*valuex
else
if(x0>=maxgx-skx*valuex)
then
x0:=maxgx-skx*valuex;
if(y0<=sky*valuey)
then
y0:=sky*valuey
else
if(y0>=maxgy-sky*valuey)
then
y0:=maxgy-sky*valuey;
builderX(x0,y0);
builderY(x0,y0);
pozx:=x0;
pozy:=y0;
{X Step Select}
step:=abs(b-a)/20;
{X Step Select}
{Writing Coordinates x Start}
x0:=trunc(skx*valuex-a*kx);
y0:=trunc(pozy);
BufMin:=a;
for xcout:=1 to 21
do
begin
Poz:=trunc(x0+BufMin*kx);
str(BufMin:2:2,text);
if((bufmin>=-step/(10*(b-a)))and(bufmin<=step/(10*(b-a))))
then
text:='0'
else
line(trunc(poz),trunc(y0+arrow*valuey),trunc(poz),trunc(y0-arrow*valuey));
settextstyle(SansSeriffont,1,0);
outtextxy(trunc(poz),trunc(y0+arrow*valuey),text);
bufMin:=BufMin+step;
end;
{Writing Coordinates x end}
{Y Step Select}
step:=abs(ymax-ymin)/20;
{Y Step Select}
{Writing Coordinates y}
y0:=trunc(sky*valuey+ymax*ky);
x0:=trunc(pozx);
BufMin:=ymin;
for ycout:=1 to 21
do
begin
Poz:=trunc(y0-BufMin*ky);
str(Bufmin:2:2,text);
if(not((bufmin>=-step/(10*(b-a)))and(bufmin<=step/(10*(b-a)))))
then
begin
settextstyle(SansSeriffont,0,0);
outtextxy(trunc(x0+arrow*valuex),trunc(poz),text);
line(trunc(x0)+arrow*valuex,trunc(poz),trunc(x0)-arrow*valuex,trunc(poz));
end;
bufMin:=BufMin+step;
end;
{Writing Coordinates y End}
end;
{Building OX and OY and Writing Coordinates End}
{Searching increase values Start}
procedure Parameter(a,b,ymax,ymin:real);
begin
maxgzonex:=maxgx-2*skx*valuex;
maxgzoney:=maxgy-2*sky*valuey;
maxrx:=abs(b-a);
maxry:=ymax-ymin;
kx:=maxgzonex/maxrx;
ky:=maxgzoney/maxry;
end;
{Searching increase values End}
procedure ChartPoints(x0,y0:real);
begin
assign(f,'Points.txt');
rewrite(f);
topval:=2;
x0:=trunc(skx*valuex-a*kx);
y0:=trunc(sky*valuey+ymax*ky);
x:=a;
gx:=x0+kx*(x);
gy:=y0-chartstuff(x)*ky;
write(f,gx,' ',gy);
gxt1:=gx+valuex/topval*sin(arctan(derivative(x)));
gyt1:=gy+valuey/topval*cos(arctan(derivative(x)));
write(f,gxt1,' ',gyt1);
gxt2:=gx-valuex/topval*sin(arctan(derivative(x)));
gyt2:=gy-valuey/topval*cos(arctan(derivative(x)));
write(f,gxt2,' ',gyt2);
while(x<=b) do
begin
x:=x+h;
gx:=x0+kx*x;
gy:=y0-ky*chartstuff(x);
write(f,gx,' ',gy);
gxt1:=gx+valuex/topval*sin(arctan(derivative(x)));
gyt1:=gy+valuey/topval*cos(arctan(derivative(x)));
write(f,gxt1,' ',gyt1);
gxt2:=gx-valuex/topval*sin(arctan(derivative(x)));
gyt2:=gy-valuey/topval*cos(arctan(derivative(x)));
write(f,gxt2,' ',gyt2);
end;
reset(f);
{Calculating Chart Points End}
end;
{Building of Chart Start}
procedure ChartBuilder(x0,y0:real);
begin
setlinestyle(3,0,3);
setcolor(yellow);
read(f,gx,gy);
read(f,gxt1,gyt1);
read(f,gxt2,gyt2);
moveto(trunc(gx),trunc(gy));
while(not(eof(f))) do
begin
read(f,gx,gy);
lineto(trunc(gx),trunc(gy));
setlinestyle(3,0,1);
moveto(trunc(gxt1),trunc(gyt1));
read(f,gxt1,gyt1);
lineto(trunc(gxt1),trunc(gyt1));
moveto(trunc(gxt2),trunc(gyt2));
read(f,gxt2,gyt2);
lineto(trunc(gxt2),trunc(gyt2));
setlinestyle(3,0,3);
moveto(trunc(gx),trunc(gy));
end;
setlinestyle(0,0,1);
setcolor(white);
{Building of Chart End}
end;
begin
clrscr;
{Starting Conditions Input Start}
Driver:=detect;
mode:=0;
Writeln('Enter left Tabulation Border a(variant 3 = 0) : ');
readln(a);
Writeln('Enter Right Tabulation Border b(variant 3 = 2) : ');
readln(b);
writeln('Enter Tabulation step h(variant 3 = 0.01) : ');
readln(h);
{Starting Conditions Input End}
{Graph Mode Initialization Start}
InitGraph(Driver,Mode,'');
{Graph Mode Initialization End}
{Error Self-Checking Procedure Start}
Error:=GraphResult;
if Error<>grOk then
begin
writeln(GraphErrorMsg(Error));
end;
{Error Self-Checking Procedure End}
maxgx:=trunc(getmaxx);
maxgy:=trunc(getmaxy);
{Standart Dimensions Start}
stdimx:=320;
stdimy:=200;
skx:=30;
sky:=25;
arrow:=3;
{Standart Dimensions End}
{Searching for Chart Machine Area Start}
for i:=1 to 20 do
begin
valuey:=trunc(maxgy/stdimy);
valuex:=trunc(maxgx/stdimx);
if(valuex=i) then skx:=trunc(valuex*skx/i);
if(valuey=i) then sky:=trunc(valuey*sky/i);
end;
{Searching for Chart Machine Area End}
{Searching Y max and Y min Value Start}
x:=a;
ymin:=chartstuff(x);
x:=b;
ymax:=chartstuff(x);
x:=a;
while(x<=b) do
begin
y:=chartstuff(x);
x:=x+h;
if(y>=ymax)
then ymax:=y
else
if(y<=ymin)
then ymin:=y;
end;
{Searching Y max and Y min Value End}
{Building Graph Start}
parameter(a,b,ymax,ymin);
chartpoints(x0,y0);
chartbuilder(x0,y0);
coordinate(x0,y0);
{Building Graph End}
readln;
end.
6.ВИСНОВОК
Беззаперечно, головною і найскладнішою частиною програми для побудови графіка є “плаваючий центр координат”, а також відповідність графічному зображенню реальних координат.
Для правильної реалізації, у даному випадку, є актуальним виведення формул для визначення положення центру координат для графічних побудов та коефіцієнтів перетворення, які б дозволяли відображати графік без значних спотворень.
Частина 2: Побудова рухомого зображення і графіка функції у одному вікні
1.ЗАВДАННЯ
Створити на крані комп’ютера графічне вікно і сформувати в ньому рухоме зображення. Вікно розмістити в верхньому правому куті екрану. Навести межі вікна. Параметри рухомого зображення визначені в таблиці 3. Параметри зображення задані в пік селях. Варіант завдання визначає викладач.
Графік і вікно з рухомим зображенням повинні бути присутні на екрані одночасно, причому вікно не має перекривати графік.
Таблиця 3.
№ варіанту
Структура зображення
Пояснення
16
Замальований правильний п’ятикутник зі стороною A2 котиться по поверхні замальованого правильного п’ятикутника зі стороною A1 за годинниковою стрілкою. Після повернення в початкове положення, п’ятикутник зі стороною A1 котиться по поверхні п’ятикутника зі стороною A2 проти годинникової стрілки і т.д. Кольори заповнення п’ятикутників різні.
Параметри : A1=80, A2=16
2.РОЗРАХУНОК МАТРИЦІ ПЕРЕТВОРЕНЬ ДЛЯ РУХОМОГО ЗОБРАЖЕННЯ
Розглянемо поворот об'єкту в площині екрану навколо довільної точки . Таке перетворення можна здійснити в результаті послідовності двох базових перетворень: перенесення поворот перенесення.
Перенесення т. в початок координат (рис.3).
Поворот об'єкту на кут (рис.4).
Перенесення, при якому т. повертається у початкове положення (рис.5).
Матриця результуючого перетворення буде такою:
рис.3. рис.4. рис.5.
3.СПИСОК ІДЕНТИФІКАТОРІВ
СПИСОК :
Q
R1
R1
N
FLOODPOINTX
FLOODPOINTY
X0
Y0
DX0
DY0
X
Y
F
FW
DQ
DDQ
XC
YC
XW
YW
X1
Y1
X2
Y2
X3
Y3
VIEWX
VIEWY
ПОЯСНЕННЯ ІДЕНТИФІКАТОРІВ ЗМІННИХ :
Q – Кут повороту п’ятикутника зі сторони на сторону навколо вершини
R1 – визначає режим роботи графічного адаптера
Error – код помилки
R2 – ліва межа табулювання
N – права межа табулювання
FLOODPOINTX – крок табулювання
FLOODPOINTY – найменше розширення по х
X0 – найменше розширення по у
Y0 – максимальне значення функції
DX0 – мінімальне значення функції
DY0 – координата по осі абсцис
X – координата по осі ординат
Y – коефіцієнт перетворення по осі абсцис
F – коефіцієнт перетворення по осі ординат
FW – проміжок на якому графік лежить по осі абсцис
DQ – проміжок на якому графік лежить по осі ординат
DDQ – координата графічного центра по осі абсцис
XC – координата графічного центра по осі ординат
YC – покрокове сумування значень по осі абсцис чи
ординат
XW – положення тексту при виводі по осі абсцис чи ординат
YW – положення графічного центру по осі абсцис для
розмітки осі абсцис
X1 – положення графічного центру по осі ординат для
розмітки осі ординат
Y1 – крок табулювання для розмітки осей абсцис та ординат
X2 – графічна координата по осі абсцис
Y2 – графічна координата по осі ординат
X3 – максимальне горизонтальне розширення екрану
Y3 – максимальне вертикальне розширення екрану
VIEWX – Абсциса правого нижнього кута графічного вікна
VIEWY – Ордината правого нижнього кута графічного вікна
ПОЯСНЕННЯ ПРОЦЕДУР ТА ФУНКЦІЙ :
Animation – процедура для відображення анімації кочення п’ятикутників
SetViewPort – задає нове графічне вікно
Rectangle – малює прямокутник
Chart – малює графік функції
Описи процедур та ідентифікаторів змінних процедури Chart на сторінці
4.БЛОК-СХЕМИ ОСНОВНОЇ ПРОГРАМИ ТА ОКРЕМИХ ПРОЦЕДУР І ФУНКЦІЙ
Процедура nCornerBuilder
ні
так
Процедура R2ShapeRotator
5
1
ні
ні 2
так
так 3
6
4
7 ні
10
ні
8 так
так
9 11
так ні
12
13
14
16 15
17
18
20
19
22
ні
21
так 23
24
25
26
28
27
так 29 ні
30 31
так ні
32
ні
ні
35 так
33
34 так
Процедура R1ShapeRotator
1 3
ні
2 4
так
5
6 ні
7
ні
так
8 так
9 10
так ні
11
13
15 14
16
17
19
18
21
ні
20
так 22
23
24
25
27
26
так 28 ні
29 30
так ні
31
ні
ні
34 так
32
33 так
Процедура Animation
1
4
2
3
5 ні
6 так
7
8
9 ні
так
10
11 13
12
14 15
16
17
18
20
ні
19
так
21
22
23
24
ні
так 25
26
27
28
Головна програма
5.ТЕКСТ ПРОГРАМИ
Program Rozrahunkova;
Uses Graph,crt;
var w,k,o,i,z,p,ycout,xcout,viewx,viewy:integer;
Procedure Chart;
var Driver,Mode,Error:integer;
f:text; a,b,h,stdimx,stdimy,ymax,ymin,x,y,kx,ky,maxrx,maxry,x0,y0,bufmin,poz,pozx,pozy,step:real;
gx,gy,gxt1,gyt1,gxt2,gyt2:real;
topval:real;
maxgx,maxgy,sky,skx,arrow,valuex,valuey,maxgzonex,maxgzoney:integer;
text:string;
{Specified Function for chart building start}
function ChartStuff(x:real):real;
begin
ChartStuff:=x*x*x*x*x*x*x*x+7*x*x*x*x-3;
end;
{Specified Function for chart building start}
{Specified Derivative Function}
function Derivative(x:real):real;
begin
derivative:=8*x*x*x*x*x*x*x+28*x*x*x;
end;
{Specified Derivative Function}
{Building OX and OY and Writing Coordinates Start}
procedure Coordinate(x0,y0:real);
procedure BuilderX(x0,y0:real);
begin
moveto(trunc(x0),trunc(y0));
lineto(skx*valuex,trunc(y0));
moveto(trunc(x0),trunc(y0));
lineto(maxgx-skx*valuex,trunc(y0));
lineto(maxgx-trunc(skx*valuex/2),trunc(y0));
lineto(maxgx-trunc(skx*valuex/2)-arrow*valuex,trunc(y0)+arrow*valuey);
moveto(maxgx-trunc(skx*valuex/2),trunc(y0));
lineto(maxgx-trunc(skx*valuex/2)-arrow*valuex,trunc(y0)-arrow*valuey);
outtextxy(maxgx-trunc(skx*valuex/2)-arrow*valuex,trunc(y0)+arrow*arrow*valuey,'X');
end;
procedure BuilderY(x0,y0:real);
begin
moveto(trunc(x0),trunc(y0));
lineto(trunc(x0),maxgy-sky*valuey);
moveto(trunc(x0),trunc(y0));
lineto(trunc(x0),sky*valuey);
lineto(trunc(x0),trunc(sky*valuey/2));
lineto(trunc(x0)-arrow*valuex,trunc(sky*valuey/2)+arrow*valuey);
moveto(trunc(x0),trunc(sky*valuey/2));
lineto(trunc(x0)+arrow*valuex,trunc(sky*valuey/2)+arrow*valuey);
outtextxy(trunc(x0)+arrow*arrow*valuex,trunc(sky*valuey/2)+arrow*valuey,'Y');
end;
begin
x0:=trunc(skx*valuex-a*kx);
y0:=trunc(sky*valuey+ymax*ky);
if(x0<=skx*valuex)
then
x0:=skx*valuex
else
if(x0>=maxgx-skx*valuex)
then
x0:=maxgx-skx*valuex;
if(y0<=sky*valuey)
then
y0:=sky*valuey
else
if(y0>=maxgy-sky*valuey)
then
y0:=maxgy-sky*valuey;
builderX(x0,y0);
builderY(x0,y0);
pozx:=x0;
pozy:=y0;
{X Step Select}
step:=abs(b-a)/20;
{X Step Select}
{Writing Coordinates x Start}
x0:=trunc(skx*valuex-a*kx);
y0:=trunc(pozy);
BufMin:=a;
for xcout:=1 to 21
do
begin
Poz:=trunc(x0+BufMin*kx);
str(BufMin:2:2,text);
if((bufmin>=-step/(10*(b-a)))and(bufmin<=step/(10*(b-a))))
then
text:='0'
else
line(trunc(poz),trunc(y0+arrow*valuey),trunc(poz),trunc(y0-arrow*valuey));
settextstyle(SansSeriffont,1,0);
outtextxy(trunc(poz),trunc(y0+arrow*valuey),text);
bufMin:=BufMin+step;
end;
{Writing Coordinates x end}
{Y Step Select}
step:=abs(ymax-ymin)/20;
{Y Step Select}
{Writing Coordinates y}
y0:=trunc(sky*valuey+ymax*ky);
x0:=trunc(pozx);
BufMin:=ymin;
for ycout:=1 to 21
do
begin
Poz:=trunc(y0-BufMin*ky);
str(Bufmin:2:2,text);
if(not((bufmin>=-step/(10*(b-a)))and(bufmin<=step/(10*(b-a)))))
then
begin
settextstyle(SansSeriffont,0,0);
outtextxy(trunc(x0+arrow*valuex),trunc(poz),text);
line(trunc(x0)+arrow*valuex,trunc(poz),trunc(x0)-arrow*valuex,trunc(poz));
end;
bufMin:=BufMin+step;
end;
{Writing Coordinates y End}
end;
{Building OX and OY and Writing Coordinates End}
{Searching increase values Start}
procedure Parameter(a,b,ymax,ymin:real);
begin
maxgzonex:=maxgx-2*skx*valuex;
maxgzoney:=maxgy-2*sky*valuey;
maxrx:=abs(b-a);
maxry:=ymax-ymin;
kx:=maxgzonex/maxrx;
ky:=maxgzoney/maxry;
end;
{Searching increase values End}
{Calculating Chart Points Start}
procedure ChartPoints(x0,y0:real);
begin
assign(f,'Points.txt');
rewrite(f);
topval:=2;
x0:=trunc(skx*valuex-a*kx);
y0:=trunc(sky*valuey+ymax*ky);
x:=a;
gx:=x0+kx*(x);
gy:=y0-chartstuff(x)*ky;
write(f,gx,' ',gy);
gxt1:=gx+valuex/topval*sin(arctan(derivative(x)));
gyt1:=gy+valuey/topval*cos(arctan(derivative(x)));
write(f,gxt1,' ',gyt1);
gxt2:=gx-valuex/topval*sin(arctan(derivative(x)));
gyt2:=gy-valuey/topval*cos(arctan(derivative(x)));
write(f,gxt2,' ',gyt2);
while(x<=b) do
begin
x:=x+h;
gx:=x0+kx*x;
gy:=y0-ky*chartstuff(x);
write(f,gx,' ',gy);
gxt1:=gx+valuex/topval*sin(arctan(derivative(x)));
gyt1:=gy+valuey/topval*cos(arctan(derivative(x)));
write(f,gxt1,' ',gyt1);
gxt2:=gx-valuex/topval*sin(arctan(derivative(x)));
gyt2:=gy-valuey/topval*cos(arctan(derivative(x)));
write(f,gxt2,' ',gyt2);
end;
reset(f);
{Calculating Chart Points End}
end;
{Building of Chart Start}
procedure ChartBuilder(x0,y0:real);
begin
topval:=2;
setlinestyle(3,0,3);
setcolor(yellow);
read(f,gx,gy);
read(f,gxt1,gyt1);
read(f,gxt2,gyt2);
moveto(trunc(gx),trunc(gy));
while(not(eof(f))) do
begin
read(f,gx,gy);
lineto(trunc(gx),trunc(gy));
setlinestyle(3,0,1);
moveto(trunc(gxt1),trunc(gyt1));
read(f,gxt1,gyt1);
lineto(trunc(gxt1),trunc(gyt1));
moveto(trunc(gxt2),trunc(gyt2));
read(f,gxt2,gyt2);
lineto(trunc(gxt2),trunc(gyt2));
setlinestyle(3,0,3);
moveto(trunc(gx),trunc(gy));
end;
setlinestyle(0,0,1);
setcolor(white);
{Building of Chart End}
end;
begin
clrscr;
{Starting Conditions Input Start}
driver:=detect;
mode:=0;
Writeln('Enter left Tabulation Border a(variant 3 = 0) : ');
readln(a);
Writeln('Enter Right Tabulation Border b(variant 3 = 2) : ');
readln(b);
writeln('Enter Tabulation step h(variant 3 = 0.01) : ');
readln(h);
{Starting Conditions Input End}
{Graph Mode Initialization Start}
InitGraph(Driver,Mode,'');
{Graph Mode Initialization End}
{Error Self-Checking Procedure Start}
Error:=GraphResult;
if Error<>grOk then
begin
writeln(GraphErrorMsg(Error));
end;
{Error Self-Checking Procedure End}
maxgx:=trunc(getmaxx);
maxgy:=trunc(getmaxy);
{Standart Dimensions Start}
stdimx:=320;
stdimy:=200;
skx:=30;
sky:=25;
arrow:=3;
{Standart Dimensions End}
{Searching for Chart Machine Area Start}
for i:=1 to 20 do
begin
valuey:=trunc(maxgy/stdimy);
valuex:=trunc(maxgx/stdimx);
if(valuex=i) then skx:=trunc(valuex*skx/i);
if(valuey=i) then sky:=trunc(valuey*sky/i);
end;
{Searching for Chart Machine Area End}
{Searching Y max and Y min Value Start}
x:=a;
ymin:=chartstuff(x);
x:=b;
ymax:=chartstuff(x);
x:=a;
while(x<=b) do
begin
y:=chartstuff(x);
x:=x+h;
if(y>=ymax)
then ymax:=y
else
if(y<=ymin)
then ymin:=y;
end;
{Searching Y max and Y min Value End}
{Building Graph Start}
parameter(a,b,ymax,ymin);
chartpoints(x0,y0);
chartbuilder(x0,y0);
coordinate(x0,y0);
{Building Graph End}
end;
Procedure Animation;
const Q=pi/2.5;
R1=(40/sin(31/180*pi));
R2=(8/sin(31/180*pi));
N=5;
type massiv=array [1..5] of real;
var
floodpointx,floodpointy:integer;
x0,y0,dx0,dy0,x,y,f,fw,dq,ddq,xc,yc:real;
xw,yw,x1,y1,x2,y2,x3,y3:massiv;
procedure nCornerBuilder(n:integer;R:real;fw:real;x0:real;y0:real);
begin
f:=fw;
y:=sin(f)*R+y0;
x:=cos(f)*R+x0;
moveto(round(x),round(y));
f:=2*pi/n+fw;
i:=1;
while(f<=2*pi+fw)
do
begin
y:=sin(f)*R+y0;
x:=cos(f)*R+x0;
xw[i]:=(x);
yw[i]:=(y);
lineto(round(x),round(y));
f:=f+2*pi/n;
i:=i+1;
end;
end;
procedure R2ShapeRotator(x1:massiv;x2:massiv;y1:massiv;y2:massiv);
begin
for o:=1 to n
do
begin
dq:=q/8;
for z:=n downto 1
do
begin
xc:=x2[z];
yc:=y2[z];
ddq:=0;
for p:=1 to 8
do
begin
ddq:=ddq+dq;
clearviewport;
for k:=1 to n
do
begin
if(not(frac(z/n)=0))
then
begin
xw[k]:=round(x2[k]*cos(ddq)-y2[k]*sin(ddq)+xc*(1-cos(ddq))+yc*sin(ddq));
yw[k]:=round(x2[k]*sin(ddq)+y2[k]*cos(ddq)+yc*(1-cos(ddq))-xc*sin(ddq));
x3[k]:=xw[k];
y3[k]:=yw[k];
end
else
begin
xw[k]:=round(x2[k]*cos(2*ddq)-y2[k]*sin(2*ddq)+xc*(1-cos(2*ddq))+yc*sin(2*ddq));
yw[k]:=round(x2[k]*sin(2*ddq)+y2[k]*cos(2*ddq)+yc*(1-cos(2*ddq))-xc*sin(2*ddq));
x3[k]:=xw[k];
y3[k]:=yw[k];
end;
end;
x0:=(viewx-300)/2.5;
y0:=(viewy-100)/2;
fw:=pi/3.335;
ncornerbuilder(n,R1,fw,x0,y0);
setfillstyle(solidfill,blue);
floodfill(round(x0),round(y0),white);
delay(100);
moveto(round(x3[1]),round(y3[1]));
for w:=1 to n
do
lineto(round(x3[w]),round(y3[w]));
lineto(round(x3[1]),round(y3[1]));
setfillstyle(solidfill,green);
floodpointx:=round((x3[2]+x3[4])/2);
floodpointy:=round((y3[2]+y3[4])/2);
floodfill(floodpointx,floodpointy,white);
delay(250);
end;
if(p=8)
then
begin
xc:=x2[z];
yc:=y2[z];
if(not(frac(z/n)=0))
then
for k:=1 to n
do
begin
xw[k]:=(x2[k]*cos(q)-y2[k]*sin(q)+xc*(1-cos(q))+yc*sin(q));
yw[k]:=(x2[k]*sin(q)+y2[k]*cos(q)+yc*(1-cos(q))-xc*sin(q));
x2[k]:=xw[k];
y2[k]:=yw[k];
end
else
for k:=1 to n
do
begin
xw[k]:=(x2[k]*cos(2*q)-y2[k]*sin(2*q)+xc*(1-cos(2*q))+yc*sin(2*q));
yw[k]:=(x2[k]*sin(2*q)+y2[k]*cos(2*q)+yc*(1-cos(2*q))-xc*sin(2*q));
x2[k]:=xw[k];
y2[k]:=yw[k];
end;
end;
end;
end;
end;
procedure R1ShapeRotator(x1:massiv;x2:massiv;y1:massiv;y2:massiv);
begin
dq:=q/10;
for z:=n downto 1
do
begin
xc:=x2[z];
yc:=y2[z];
ddq:=0;
for p:=1 to 10
do
begin
ddq:=ddq+dq;
clearviewport;
for k:=1 to n
do
begin
if(not(z=n))
then
begin
xw[k]:=round(x1[k]*cos(-ddq)-y1[k]*sin(-ddq)+xc*(1-cos(-ddq))+yc*sin(-ddq));
yw[k]:=round(x1[k]*sin(-ddq)+y1[k]*cos(-ddq)+yc*(1-cos(-ddq))-xc*sin(-ddq));
x3[k]:=xw[k];
y3[k]:=yw[k];
end
else
begin
xw[k]:=round(x1[k]*cos(-2*ddq)-y1[k]*sin(-2*ddq)+xc*(1-cos(-2*ddq))+yc*sin(-2*ddq));
yw[k]:=round(x1[k]*sin(-2*ddq)+y1[k]*cos(-2*ddq)+yc*(1-cos(-2*ddq))-xc*sin(-2*ddq));
x3[k]:=xw[k];
y3[k]:=yw[k];
end;
end;
x0:=(viewx-300)/2.5;
y0:=(viewy-100)/2;
x0:=x0+dx0;
y0:=y0+dy0;
fw:=0.5*pi;
Ncornerbuilder(n,R2,fw,x0,y0);
setfillstyle(solidfill,green);
floodfill(round(x0),round(y0),white);
delay(200);
moveto(round(x3[1]),round(y3[1]));
for w:=1 to n
do
lineto(round(x3[w]),round(y3[w]));
lineto(round(x3[1]),round(y3[1]));
setfillstyle(solidfill,blue);
floodpointx:=round((x3[3]+x3[5])/2);
floodpointy:=round((y3[3]+y3[5])/2);
floodfill(floodpointx,floodpointy,white);
delay(100);
end;
if(p=10)
then
begin
xc:=x2[z];
yc:=y2[z];
if(not(frac(z/n)=0))
then
for k:=1 to n
do
begin
xw[k]:=(x1[k]*cos(-q)-y1[k]*sin(-q)+xc*(1-cos(-q))+yc*sin(-q));
yw[k]:=(x1[k]*sin(-q)+y1[k]*cos(-q)+yc*(1-cos(-q))-xc*sin(-q));
x1[k]:=xw[k];
y1[k]:=yw[k];
end
else
for k:=1 to n
do
begin
xw[k]:=(x1[k]*cos(-2*q)-y1[k]*sin(-2*q)+xc*(1-cos(-2*q))+yc*sin(-2*q));
yw[k]:=(x1[k]*sin(-2*q)+y1[k]*cos(-2*q)+yc*(1-cos(-2*q))-xc*sin(-2*q));
x1[k]:=xw[k];
y1[k]:=yw[k];
end;
end;
end;
end;
begin
clrscr;
x0:=(viewx-300)/2.5;
y0:=(viewy-100)/2;
fw:=pi/3.335;
Ncornerbuilder(n,R1,fw,x0,y0);
for i:=1 to n do
begin
x1[i]:=xw[i];
y1[i]:=yw[i];
end;
fw:=0.5*pi;
ncornerbuilder(n,R2,fw,x0,y0);
for i:=1 to n do
begin
x2[i]:=xw[i];
y2[i]:=yw[i];
end;
{Moving parameters}
dx0:=x1[4]-x2[5];
dy0:=y1[4]-y2[5];
{Moving parameters}
{Moving to start pozition}
clearviewport;
x0:=(viewx-300)/2.5;
y0:=(viewy-100)/2;
fw:=pi/3.335;
Ncornerbuilder(n,R1,fw,x0,y0);
setfillstyle(solidfill,blue);
floodfill(round(x0),round(y0),white);
x0:=(x0+dx0);
y0:=(y0+dy0);
fw:=0.5*pi;
Ncornerbuilder(n,R2,fw,x0,y0);
setfillstyle(solidfill,green);
floodfill(round(x0),round(y0),white);
{Moving to starting pozition}
{Writing coordinates to massive}
for i:=1 to n do
begin
x2[i]:=xw[i];
y2[i]:=yw[i];
end;
{Writing coordinates to massive}
{Shape R1 rotating}
delay(1400);
while(not(keypressed))
do
begin
R2shaperotator(x1,x2,y1,y2);
R1ShapeRotator(x1,x2,y1,y2);
end;
readln;
closegraph;
end;
begin
Chart;
viewx:=round(getmaxx/1.4);
viewy:=round(getmaxy/1.5);
setcolor(white);
rectangle(299,99,viewx+1,viewy+1);
setviewport(300,100,viewx,viewy,false);
Animation;
readln;
end.
6.РЕЗУЛЬТАТ ВИКОНАННЯ ПРОГРАМИ
7.ВИСНОВОК
Ключовим моментом у програмуванні анімації є точне визначення матриць руху чи обертання реперних точок фігури та максимально точне обчислення координат подальшого положення фігури з метою уникнення похибок, які можуть суттєво погіршити результат. Суть анімації – зміна положення предмета з “затиранням” попереднього положення. Працюючи з графічним екраном у середовищі PASCAL найпростішим способом “затерти” попереднє положення об’єкту є використання процедури повного очищення графічного екрану. Суміщення 2 графічних побудов зручно здійснювати процедурою setviewport.