You are on page 1of 11

Іван Хвищун. Кафедра РФтаКТ. Курс “ООП”. Лаб. роб. № 1.

Розкладення періодичних функцій в ряд Фур’є 1


Мета роботи: Розробити 2 програмних проекти, опанування яких дозволить закріпити знання стосовно
можливостей мови Delphi, які отримано у І-му семестрі при вивченні таких розділів курсу “Алгоритмізація та
програмування”:
1. Програмування складних логічних виразів.
2. Оголошення та використання масивів.
3. Опис процедур та функцій.
4. Табулювання функцій із занесенням результатів у масиви.
5. Пошук екстремальних значень серед елементів масиву.
6. Програмна реалізація алгоритмів на основі блок-схем.
7. Оголошення та використання структурованого типу даних Record (запис).
8. Оголошення та використання типізованих файлів.
9. Побудова універсальних власних графіків функцій.
10. Обчислення визначених інтегралів.
11. Робота у віконному режимі середовища Delphi.
і підготувати базу для подальшого створення цього проекту по об’єктно-орієнтованій технології.
Теоретичні відомості
Спектральний аналіз періодичних сигналів. Ряд Фур’є
Ряд Фур’є дає змогу представити періодичний процес f(t) сумою гармонічних коливань, частоти яких є кратні
a0  a 
основній частоті ν. f(t)= + (ak cos (2π ν k t)+bk sin (2π ν k t))= 0 + (ak cos (k wt)+bk sin (k wt)), (1)
2 k=1 2 k=1
де ω = 2πν – кругова частота.
З погляду фізики ряд (1) можна інтерпретувати, як заміну складного руху фізичної системи сумою простих
гармонічних рухів, які відбуваються одночасно. У фізиці коливань і хвиль для означення простих рухів, поряд із
терміном гармоніка, використовують термін мода.
Для визначення коефіцієнтів ряду помножимо вираз (1) на cos(kwt) ( k – ціле число) та інтегруємо його на
відрізку [0, TP]. Враховуючи ортогональність системи функцій { cos (kwt), sin (kwt) }, одержимо:
TP
2
a0 
TP  f (t )dt (2)
0
TP
2
a k=
TP  f(t) cos (kwt)dt (3)
0
Помножимо (1) на sin(kwt) та інтегруємо добуток на відрізку [0, TP]. Одержимо:
TP
2
b k=
TP  f(t) sin (kwt)dt , де k = 1,2,3... (4)
0
a0  b
Ряд (1) можна записати по іншому: f(t)= +  ck cos (kwt-ψk ) , де ck = a 2k+b 2k , ψk = arctg ( k ) .
2 k=1 ak
Набори величин { ck } i { ψ k } залежать від ω. Їх називають, відповідно, амплітудним і фазовим спектром
функції f(t). У фізиці спектри функцій широко застосовують. Наприклад, на основі комбінації амплітудного і
фазового спектрів можна дослідити стійкість динамічних процесів. При моделюванні динамічних режимів фізичних
систем, на основі амплітудного спектру вихідного сигналу можна оцінити коефіцієнт його нелінійних спотворень.
Графіки залежності ck i ψ k від ω є дискретними. Їх зображають на площині (ω,C) відрізками ліній, які
розташовані перпендикулярно до осі абсцис у точках, кратних w. Наприклад, для функції
0, TP / 2  t  TP / 4

f(t)= a, TP / 4  t  TP / 4 , (5)
0, TP / 4  t  TP / 2

графік якої зображено на Рис. 1, амплітудний спектр набуде вигляду такого, як на Рис. 2.
`
f C
a
2a/
2a/3
2a/5
t 
           
-TP/2 - TP/4 0 TP/4 TP/2 3TP/4 0  3 5
Рис. 1. Графік функції Рис. 2. Амплітудний спектр цієї функції
Іван Хвищун. Кафедра РФтаКТ. Курс “ООП”. Лаб. роб. № 1. Розкладення періодичних функцій в ряд Фур’є 2
Примітки.
1. Якщо значення періоду ТР збільшувати, то частота ω зменшується і густина ліній зростає. При TP  
дискретний спектр стає неперервним і ряд Фур’є переходить в інтеграл Фур’є.
2. У спектрі функції (5) відсутні парні гармоніки (їхні амплітуди дорівнюють 0, оскільки функція (5) є
парною).
Виходячи з поняття визначеного інтеграла і властивості парності чи непарності функції, можна довести, що
для парних функцій (f(t)=f(-t)) ряд (1) містить тільки косинусові гармоніки, а для непарних (f(t)=-f(-t)) – тільки
синусні. Інтеграли (2), (3) і (4) обчислимо, застосовуючи формулу правих прямокутників.
bl - al TP
Позначимо через h   – крок дискретизації функції f(t) на періоді TP . Дискретизацію виконаємо
Ne Ne
шляхом табулювання заданої функції. Тоді в масив Xe будуть записані дискретні значення аргументу ti =al+i  h,
(тобто Xei =al+i  h ), а в масив Ye – дискретні значення функції f(i  h ) (i=0,1,...,Ne-1) . Враховуючи сказане, із
виразу (2) одержимо:
2 Ne-1 2 Ne-1 2 Ne-1
a0 = 
TP i=1
f(i  h)  h= 
Ne i=1
f(i  h)=  Yei .
Ne i=1
(6)

Відповідно
2 Ne-1 2 Ne-1
ak = 
Ne i=1
f(i  h) cos (kw  i  h)=  Yei cos (kw  Xei ) ;
Ne i=1
(7)

2 Ne-1 2 Ne-1
bk = 
Ne i=1
f(i×h) sin (kw  i  h)=  Yei sin (kw  Xei ) .
Ne i=1
(8)

Частинна сума Ng членів ряду (1) (гармонік) набуде вигляду:


a0 NG
Ygi = + (ak Cos(kw  Xei )+bk Sin(kw  Xei )) , i=0, 1,...,Ne-1 . (9)
2 k=1
Блок-схему алгоритму розкладання періодичної функції в ряд Фур’є наведено на Рис. 4. У ній позначені
ідентифікаторами S, G i D – проміжні змінні дійсного типу. Для оптимізації обчислень в алгоритмі введено змінну
КОМ дійсного типу, у якій, за обчислення виразів (7) і (8) (блоки 5–8), поза цикл винесено значення k  w , а за
обчислення виразу (9) (блоки 20–28) у циклі по k послідовно формуються значення k  D , де D=Xei  w .
Результатом роботи алгоритму є обчислення та виведення на дисплей коефіцієнтів a0 , ak ,bk , амплітудного спектра
c k , і формування Nе значень масиву Yg , які обчислені відповідно до виразу (9) для точок Xei , i=0, 1, 2,..,Ne-1.
Завдання для самостійної роботи
1. Отримати функцію для дослідження і запрограмувати її як функцію мовою Delphi (зразок функцій є на Рис. 3).
2. Згідно з алгоритмом (Рис. 4.) запрограмувати процедуру обчислення коефіцієнтів, побудову і табулювання ряду
Фур’є, вхідними параметрами якої слугують масиви Xe , Ye і число Ne , а вихідним параметром – масив Yg . Щодо
цього, масиви A, B значень коефіцієнтів виразу (9) і масив C значень амплітудного спектру доцільно оголосити як
локальні масиви дійсного типу розмірністю [1..20] цієї процедури.
3. Для різних значень Ng з діапазону [3..50] і Ngr з діапазону [300..1000] побудувати графіки залежності Ye( Xe) і
Yg ( Xe) (Рис. 5.).
5. Додатково до п. 1, 2, 3 і 4 побудувати графік залежності спектру Ck від кругової частоти w (Рис. 6).
w

Рис. 3. Тестові функції


Іван Хвищун. Кафедра РФтаКТ. Курс “ООП”. Лаб. роб. № 1. Розкладення періодичних функцій в ряд Фур’є 3
Вхід
XE ,YE ,NE
1
Вв. к-cть
гармо-
нiк NG
2 13 20
TP = bl - al ; i=0
a0 = 0
w = 2* Pi / TP
21
3 14
S=0;
k=1 i=1
D = XEi * w
4 15 22
KOM = k* w ;
G = 0; a0 = a0 +YEi k=1
D=0 23
5 16 KOM= k*D ;
i=1 i i+1 S=S+bksin(KOM)
+ akcos(KOM)
6 17 24
s=KOM *XEi ; ні
i > NE-1 k k+1
G=G+YEi cos(s)
D=D+YEi sin(s) 18
7
25 ні
i i+1 a0 = a0 /NE k > NG

ні 8 26
i > NE - 1
YGi = a0 + S
9
ak = 2*G/NE ; 27
bk = 2*D/NE ; i i+1
ck = (ak2 +bk2)1/2
11 28
ні
k k+1 i > NE-1

ні
12 Вихід
K > NG YG

Рис. 4. Алгоритм побудови і табулювання ряду Фур’є

Рис 5. Розкладення функції у ряд Фур’є Рис. 6. Амплітудний спектр цієї функції
Опис періодичної функції, яку використано на Рис 5:
Function f(x: Real): Real;
Begin
Tp := bl - al;
if x < TP / 2 then f:= 2
else
if(x >= TP / 2) and (x < 3 * TP / 4) then
f := 4 * (TP - 2 * x) / TP
else
f := 8 * (x - TP) / TP;
end;
Іван Хвищун. Кафедра РФтаКТ. Курс “ООП”. Лаб. роб. № 1. Розкладення періодичних функцій в ряд Фур’є 4
Частина 1.1 Методика розробки проекту “Розкладення періодичних функцій у ряд Фур’є” в
середовищі Embarcadero Delphi без використання файлів.
1. Створимо папку My_Furje_Delphi, запускаємо Embarcadero Delphi у віконному режимі і записуємо
порожній проект у цю папку.
2. Формуємо інтерфейс проекту. Один із його можливих варіантів наведено нижче (Рис. 7.).

Рис. 7. Інтерфейс проекту “Ряд Фур’є”


3. Послідовність його створення:
 Активізуємо форму і в Object Inspector встановлюємо значення її властивості Caption:
Розкладання періодичної функції у ряд Фур'є.
 У верхню частину форми ставимо компоненту TImage (Additional).
 У нижню частину форми ставимо компоненту TGroupBox (Standard). На ній розташуємо решту
компонентів інтерфейсу. Активізувавши TGroupBox, її властивість Caption встановимо: Параметри
графіків, і обираємо бажаний нам колір поля компоненти TgroupBox, використавши властивість
Color.
 Поставимо на поле TGroupBox 11 компонент TLabel (Standard). Їхнім властивостям Caption
надаємо такі значення:
o Введіть межі зміни аргументу
o al=
o bl=
o Введіть к-ть експеримент. точок
o Товщ. лінії графіка ф-ції=
o Товщ. осей координат=
o Товщ. ліній гратки=
o Товщ. лінії графіка суми ряду=
o Введіть к-ть гармонік Ng=
o Ne=
o Оберіть, при потребі, інші значення.
Розташування цих компонент видно на Рис. 7.
 Поставимо на поле TGroupBox 4 компоненти TEdit(Standard):
1. TEdit1 біля підпису Ne=.
2. TEdit2 біля підпису Введіть к-ть гармонік Ng=.
3. TEdit3 біля підпису al=.
4. TEdit4 біля підпису bl=.
 В Object Inspector встановлюємо такі значення кожної із їхніх властивостей Text, як на Рис. 7.
 Поставимо на поле TGroupBox 4 компоненти TSpinEdit(Samples):
1. TSpinEdit1 біля підпису Товщ. лінії графіка ф-ції=.
2. TSpinEdit2 біля підпису Товщ. осей координат=.
3. TSpinEdit3 біля підпису Товщ. ліній гратки=.
4. TSpinEdit4 біля підпису Товщ. лінії графіка суми ряду=.
 В Object Inspector встановлюємо такі значення кожної із їхніх властивостей Value, як на Рис. 5. Для
кожної з цих компонент встановимо значення властивості MinValue - 1, а MaxValue - 5.
Іван Хвищун. Кафедра РФтаКТ. Курс “ООП”. Лаб. роб. № 1. Розкладення періодичних функцій в ряд Фур’є 5
Послідовність написання програмної частини проекту.
 Переходимо до програмного редактора середовища, натиснувши функціональну клавішу F12.
Побачимо вікно із модулем unit Unit1;.
 Після ключового слова type оголошуємо 2 власних типи даних для створення масивів:
Vector = array [0..1000] of Real; // для створення масивів із координатами графіків
Vec = array [0..50] of Real; // для створення масивів із коефіцієнтами ряду Фур’є
 Після ключового слова var і рядка: Form1 : TForm1; вставляємо описи глобальних змінних:
Xe, Ye : Vector; // масиви для зберігання координат нашої періодичної функції
Xg, Yg : Vector; // масиви для зберігання координат табульованого ряду Фур'є
a, b, c: Vec; // масиви для зберігання коефіцієнтів ряду Фур'є
Ne, Ngr, Ng: Integer; // Ne = Ngr кількість точок обох графіків
al, bl, Tp : Real; // область визначення функції та її період: Tp = bl – al
 Після рядка {$R *.dfm} додаємо описи необхідних підпрограм:
Function f(x: Real): Real; // опис заданої викладачем періодичної функції
Begin
// тут необхідно розмістити опис заданої Вам періодичної функції
end;
Procedure TabF(var Xe: Vector; var Ye: Vector);// процедура табулювання періодичної функції
Var h: Real;
i: Integer;
Begin
h := (bl - al) / Ne;
Xe[0]:= al;
For i := 0 to Ne - 1 do
Begin
Ye[i] := f(Xe[i]);
Xe[i+1] := Xe[i] + h;
End;
End;
// Процедура побудови і табулювання ряду Фур’є згідно з алгоритмом, що є на рис. 4.
Procedure Furje(Xe, Ye: Vector; Ne: Integer; var Yg: Vector);
Var i, k: Integer;
w, KOM, S, G, D: Real;
Begin
Ng := StrToInt(Form1.Edit2.text); // вводимо кількість гармонік
TP := bl - al; // TP – період нашої функції
// Обчислення коефіцієнтів ряду Фур'є
w := 2 * Pi / TP;
For k := 1 to Ng do
Begin
KOM := k * w;
G := 0.0; D := 0.0;
For i :=1 to Ne do
Begin
S := KOM * Xe[i];
G := G + Ye[i] * Cos(S);
D := D + Ye[i] * Sin(S);
End;
a[k] := 2 * G / Ne;
b[k] := 2 * D / Ne;
c[k] := Sqrt(Sqr(a[k]) + Sqr(b[k]));
End;
a[0] := 0.0;
For i := 1 to Ne do
a[0] := a[0] + Ye[i];
a[0] := a[0] / Ne;
For i := 0 to Ne - 1 do // побудова і табулювання суми ряду Фур’є
Begin
S := 0; D := Xe[i] * w;
For k:=1 to Ng do
Begin
KOM := k * D;
S := S + b[k] * Sin(KOM) + a[k] * Cos(KOM);
End;
Yg[i] := a[0] + S;
End;
End;
 Перейшовши по F12 до вікна форми з інтерфейсом проекту, двічі клацнемо мишкою на кнопку:
Побудувати графіки. Одержимо заготовку процедури TForm1.Button1Click, у яку заносимо
необхідні оператори для роботи нашого проекту:
Іван Хвищун. Кафедра РФтаКТ. Курс “ООП”. Лаб. роб. № 1. Розкладення періодичних функцій в ряд Фур’є 6
Procedure TForm1.Button1Click(Sender: TObject);
Var p,zx,zy,ay,bx,krx,kry,xx,yy,Gx,Gy : Real;
i,j,krokx,kroky,drv,drm,visx,visy,L : Integer;
minYg,maxYg,maxx,maxy,minx,miny,kx,ky:real;
// Процедура візуалізації гармонік
Procedure Garm(Ng: Integer; c: Vec);
Var i, Krokx, x: Integer;
MaxC, Ky, W: Real;
Begin
Krokx := (Image1.ClientWidth - 2 * L) div Ng;
MaxC := c[1];
For I := 2 to Ng do
If c[i] > MaxC then MaxC := c[i];
Ky := (Image1.ClientHeight div 2) / MaxC;
With Image1.Canvas do
Begin
Pen.Color := clHighLight;
Pen.Width := 2;
MoveTo(L, L + 20 );
LineTo(L + 10, L + 10);
LineTo(L + 20, L + 20);
MoveTo(L + 10, L + 10);
LineTo(L + 10, Image1.ClientHeight - 50);
LineTo(Image1.ClientWidth-20, Image1.ClientHeight-50);
MoveTo(Image1.ClientWidth-40, Image1.ClientHeight-60);
LineTo(Image1.ClientWidth-20, Image1.ClientHeight-50);
LineTo(Image1.ClientWidth-40, Image1.ClientHeight-40);
TextOut(L - 2, L ,'C');
TextOut(ClientWidth - 50, ClientHeight - 25 ,'W');
Pen.Color := clFuchsia;
Pen.Width := 2; x := KrokX + 20;
w := 2 * Pi /(bl - al);
For i:= 1 to Ng do
Begin
MoveTo(Round(x)+3,Image1.ClientHeight-50);
LineTo(Round(x)+3,Image1.ClientHeight-50-Round(ky*c[i]));
TextOut(round(x),Image1.ClientHeight - Round(ky*c[i])-65,
FloatToStrF(c[i],ffGeneral,0,0));
Ellipse(round(x),Image1.ClientHeight-53,round(x)+5,Image1.ClientHeight-48);
Ellipse(Round(x)+1,Image1.ClientHeight-50-Round(ky*c[i]),Round(x) + 7,
Image1.ClientHeight-50-Round(ky*c[i]) + 5);
x := x + KrokX;
End;
x := KrokX + 19;
TextOut(round(x), Image1.ClientHeight - 30,'W='+ FloatToStrF(w,ffGeneral,0,0));
End;
End;
// Початок виконуваної частини процедури TForm1.Button1Click
Begin
Ne := StrToInt(Edit1.Text);
Ngr:= Ne;
al := StrToFloat(Form1.Edit3.Text);
bl := StrToFloat(Form1.Edit4.Text);
TabF( Xe, Ye); // табуляція заданої періодичної функції
Furje(Xe,Ye,Ne,Yg); // обчислення коефіцієнтів ряду Фур'є і табуляція суми ряду
// Будуємо графіки обох функцій Ye(Xe) та Yg(Xe)
L := 40; // відступ від країв компоненти TImage
With Form1.Image1 do
Begin
Canvas.Pen.Width := 2;
Canvas.Pen.Color := clBlue;
Canvas.Pen.Style := psSolid;
Canvas.Rectangle(1, 1, Width - 1, Height - 1);
MinYg:=Yg[0]; MaxYg:=Yg[0];
For i := 1 to Ngr - 1 do
Begin
If MaxYg < Yg[i] then MaxYg := Yg[i];
If MinYg > Yg[i] then MinYg := Yg[i];
End;
MinX := Xe[0]; MaxX := Xe[Ne-1];
MinY := Ye[0]; MaxY := Ye[0];
For i := 1 to Ne - 1 do
Begin
If MaxY< Ye[i] then MaxY := Ye[i];
If MinY> Ye[i] then MinY := Ye[i];
Іван Хвищун. Кафедра РФтаКТ. Курс “ООП”. Лаб. роб. № 1. Розкладення періодичних функцій в ряд Фур’є 7
End;
If MaxY < MaxYg then MaxY := MaxYg;
If MinY > MinYg then MinY := MinYg;
// Обчислюємо значення коефіцієнтів масштабування
Kx := (Width - 2 * L) /(MaxX - MinX);
Ky := (Height - 2 * L) /(MinY - MaxY);
Zx := (Width * MinX - L * (MinX + MaxX)) / (MinX - MaxX);
Zy := (Height * MaxY - L * (MinY + MaxY)) / (MaxY - MinY);
End;
// Обчислюємо розташування плаваючих осей
If MinX * MaxX <= 0.0 then Gx := 0.0;
If (MinX * MaxX > 0.0) then Gx := MinX;
If (MinX * MaxX > 0.0) then Gx := MinX;
If (MinX * MaxX > 0.0) and (MinX < 0.0) then Gx := MaxX;
If MinY * MaxY <= 0.0 then Gy := 0.0;
If (MinY * MaxY > 0.0) and (MinY > 0.0) then Gy := MinY;
If (MinY * MaxY > 0.0) and (MinY < 0.0) then Gy := MaxY;
With Form1.Image1.Canvas do // ------------------------
Begin
Pen.Color := clSilver;
Pen.Width := SpinEdit3.Value;
KrokX := (Width - 2 * L) div 10;
KrokY := (Height - 2 * L) div 10;
For i := 0 to 10 do
Begin
MoveTo(L, Round(Ky * Gy + Zy) + i * KrokY);
LineTo(Width - L, Round(Ky * Gy + Zy) + i * KrokY);
MoveTo(L, Round(Ky * Gy + Zy) - i * KrokY);
LineTo(Width - L, Round(Ky * Gy + Zy) - i * KrokY);
MoveTo(Round(Kx * Gx + Zx) + i * KrokX,L);
LineTo(Round(Kx * Gx + Zx) + i * KrokX, Height - L);
MoveTo(Round(Kx * Gx + Zx) - i * KrokX, L);
LineTo(Round(Kx * Gx + Zx) - i * KrokX, Height - L);
End;
// Виведення підписів осей координат---------------------------------
xx := MinX; yy := MaxY;
KrX := (MaxX - MinX) / 10.0; KrY := (MaxY - MinY) / 10.0;
For i:=0 to 9 do
Begin
TextOut(L + 4 + i * KrokX,
Round(Ky * Gy + Zy) - L + 43, FloatToStrF(XX, ffGeneral, 2, 5));
TextOut(Round(Kx*Gx+Zx)-L+10,
L + i * KrokY - 5,
FloatToStrF(YY, ffGeneral, 2, 5));
Pen.Color:=clFuchsia;
XX := XX + KrX;
yy := yy - KrY;
End;
Pen.Style := psSolid; // малюємо плаваючі осі----------
Pen.Color := clGreen;
Pen.Width := SpinEdit2.Value;
MoveTo(L, Round(Ky * Gy + Zy));
LineTo(Round(Width - L), Round(Ky * Gy + Zy));
MoveTo(Round(Kx * Gx + Zx), L);
LineTo(Round(Kx * Gx + Zx), Round( Height - L));
Pen.Width := SpinEdit1.Value;
Pen.Color := clFuchsia;
MoveTo(Round(Kx * Xe[0]+Zx), Round(Ky * Ye[0] + Zy));
For i := 0 to Ne - 1 do
LineTo(Round(Kx * Xe[i]+Zx), Round(Ky * Ye[i] + zy));
Pen.Width:=SpinEdit4.Value;
Pen.Color:=clGreen;
MoveTo(Round (Kx*Xe[0]+Zx), Round(Ky * Yg[0] + Zy));
For i:=0 to Ne-1 do
LineTo(Round (Kx*Xe[i]+Zx), Round(Ky * Yg[i] + Zy));
end;
ShowMessage('Показати гармоніки ?');
Image1.Picture:= nil;
Garm(Ng, c);
end;
Після запуску програми переходимо від Рис. 5. до Рис. 6, натиснувши Ок діалогового вікна, яке
з’явиться.
Іван Хвищун. Кафедра РФтаКТ. Курс “ООП”. Лаб. роб. № 1. Розкладення періодичних функцій в ряд Фур’є 8

Частина 1.2. Розкладення періодичних функцій у ряд Фур’є із використанням записів та файлів.
Удосконалимо проект “Розкладення періодичних функцій у ряд Фур’є” шляхом додавання можливості
записування у типізований файл результатів, які обчислювались для виконання побудови графіків
функцій і візуалізації амплітудного спектру періодичної функції у першій частині роботи. Для цього:
1. Створимо нову папку My_Furje_Delphi_File, запускаємо Embarcadero Delphi у віконному режимі і
записуємо порожній проект у цю папку.
2. Копіюємо у цю папку проект з першої частини цієї роботи.
3. Модифікуємо інтерфейс проекту шляхом заміни кнопки “Побудувати графіки” (Рис. 8.) кнопкою
“Записати у файл” і додаванням ще однієї кнопки з назвою “Побудувати графіки” (Рис. 9.).

Рис. 8. Інтерфейс попереднього проекту “Розкладення періодичної функції у ряд Фур'є”

Рис. 9. Інтерфейс нового проекту “Ряд Фур’є із використанням записів і файлів”


Формування інтерфейсу завершено!
Переходимо до програмного редактора середовища, натиснувши функціональну клавішу F12.
Побачимо вікно із модулем unit Unit1;.
УВАГА!! Жирним стилем позначено ті фрагменти програми, які ми додаємо у Частині 1.2 проекту!!
1. Після ключового слова type бачимо 2 власних типи даних для створення масивів:
Vector = array [0..1000] of Real; // для створення масивів із координатами графіків
Vec = array [0..50] of Real; // для створення масивів із коефіцієнтами ряду Фур’є
2. Переміщаємо у цей розділ type глобальні змінні проекту із розділу var і формуємо з них такий
запис (Record):
Zapys = Record // оголошення власного типу даних Zapys для типізованого файлу
Xe, Ye, Yg : Vector; // масиви для зберігання координат нашої періодичної функції
a, b, c : Vec; // масиви для зберігання коефіцієнтів ряду Фур’є
Іван Хвищун. Кафедра РФтаКТ. Курс “ООП”. Лаб. роб. № 1. Розкладення періодичних функцій в ряд Фур’є 9
Kx, Ky, Zx, Zy: Real; // коефіцієнти масштабування
al, bl, Tp : Real; // область визначення функції та її період: Tp = bl - al
Ne, Ngr, Ng: Integer; // Ne = Ngr кількість точок обох графіків
minYg, maxYg, maxx, maxy, minx, miny: Real; // для обчислення коефіцієнтів масштабування
krx, kry, xx, yy, Gx, Gy: Real; // для виведення осей координат і їхніх підписів
KrokX, KrokY, L: Integer;
End;
3. Після ключового слова var і рядка: Form1: TForm1;
вставляємо оголошення змінної типу Zapys: F_GRF: Zapys; // змінна типу Record
4. Для спрощення доступу до полів новоствореного запису в усіх процедурах і функціях
використаємо оператор приєднання: With <ім’я змінної-запису> do.
Наприклад, опис нашої періодичної функції матиме такий вигляд:
Function f(x: Real): Real;
Begin
With F_GRF do // оператор приєднання: для спрощення доступу до полiв запису
Begin
Tp := bl - al;
if x < TP / 2 then f:= 2 else
if(x >= TP / 2)and(x < 3 * TP / 4) then f := 4 * (TP - 2 * x) / TP
else f := 8 * (x - TP) / TP;
End;
End;
5. Переходимо за допомогою F12 до вікна з інтерфейсом проекту, ставимо курсор миші на кнопку
“Записати у файл” і двічі натискаємо ліву клавішу миші. Одержимо заготовку процедури:
Procedure TForm1.Button1Click(Sender: TObject);
6. Тіло процедури міститиме обчислення всіх даних для побудови графіків і фрагмент для роботи з
типізованим файлом для відкривання файлу, запису даних і його закривання:
Procedure TForm1.Button1Click(Sender: TObject);
Var Ft : File of Zapys; // опис типізованого файлу
i : Integer;
Begin // початок виконуваної частини процедури TForm1.Button1Click
With F_GRF do // оператор приєднання With для спрощення доступу до полiв запису F_GRF
Begin
Ne := StrToInt(Edit1.Text);
. . . . . . . .. .
// < Див. фрагмент тіла процедури із І-ї частини цієї роботи>;
// Обчислюємо зачення коефіцієнтів масштабування ---------------------
Kx := (Width - 2 * L) /(MaxX - MinX);
Ky := (Height - 2 * L) /(MinY - MaxY);
Zx := (Width * MinX - L * (MinX + MaxX)) / (MinX - MaxX);
Zy := (Height * MaxY - L * (MinY + MaxY)) / (MaxY - MinY);
End;
// Робота з типізованим файлом даних для побудови графіків--------------
AssignFile (Ft , 'Grf_file.dat'); // iнiцiалізація файлу
Rewrite ( Ft ); // створення типізованого файлу
Write (Ft, F_GRF); // запис у типізованого файл
CloseFile (Ft ); // закриття файлу
ShowMessage('Дані успішно записано у файл');
End;
End;
7. Обробник події натискання на кнопку “Побудувати графіки” матиме вигляд:
// Читання даних з типізованого файлу і побудова графіків
procedure TForm1.Button2Click (Sender: TObject);
Var Ft: File of Zapys; // оголошення типізованого файлу
i: Integer;
Procedure Garm(Ng: Integer; c: Vec); // процедура візуалізації гармонік
Var i, KrokxG, x: Integer;
MaxC, W: Real;
Begin
With F_GRF do // оператор приєднання With для спрощення доступу до полiв запису F_GRF
Begin
KrokxG := (Image1.ClientWidth - 2 * L) div Ng;
// Див. фрагмент тіла відповідної процедури із І-ї частини цієї роботи
End;
End;
Begin // початок виконуваної частини процедури TForm2.Button1Click
With F_GRF do // оператор приєднання With для спрощення доступу до полiв запису F_GRF
Begin
// Робота з типізованим файлом даних для побудови графіків--------------
AssignFile ( Ft, 'Grf_file.dat'); // iнiцiювання файлу
Reset( Ft ); // відкривання типізованого файлу
Іван Хвищун. Кафедра РФтаКТ. Курс “ООП”. Лаб. роб. № 1. Розкладення періодичних функцій в ряд Фур’є 10
Read (Ft, F_GRF); // читання даних з файлу
CloseFile (Ft ); // закриття файлу
!!! Далі продовжується текст тіла процедури: Procedure TForm1.Button1Click(Sender: TObject);
із І-ї частини цієї роботи!!!!
// Обчислюємо розташування плаваючих осей-------- ---------------------
If MinX * MaxX <= 0.0 then Gx := 0.0;
If (MinX * MaxX > 0.0) then Gx := MinX;
// Див. фрагмент тіла відповідної процедури із І-ї частини цієї роботи
ShowMessage('Показати гармоніки ?');
Image1.Picture:= nil;
Garm (Ng, c);
End;
End;
End.
8. Завершивши програмування і налагодження проекту записуємо його на диск.
9. Після запуску проекту на виконання одержимо вікно:

10. Натиснувши Записати у файл, одержимо:

11. Натиснувши по черзі ОК і Побудувати графіки одержимо:


Іван Хвищун. Кафедра РФтаКТ. Курс “ООП”. Лаб. роб. № 1. Розкладення періодичних функцій в ряд Фур’є 11

12. Натиснувши ОК у вікні Показати гармоніки, одержимо:

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

Додаткові завдання:
1. Створити інший візуальний інтерфейс проекту.
2. Додати до проекту можливість обирати одну із де-кількох періодичних функцій, які Ви
попередньо запрограмували.
3. Додати до проекту можливість обирати метод обчислення визначених інтегралів (метод
центральних прямокутників, метод трапецій або – метод Сімпсона
4. Запрограмувати (після вивчення теорії ООП) цей проект у об’єктно-орієнтованому стилі.

Написати звіт про пророблену роботу і захистити його у викладача.

You might also like