Advertisement
daniv1

Untitled

Mar 2nd, 2018
150
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 8.71 KB | None | 0 0
  1.  unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
  9.   StdCtrls, Spin;
  10.  
  11. type
  12.      Vector = array [0..1000] of Real; // для створення масивів із координатами графіків
  13. Vec = array [0..50] of Real; // для створення масивів із коефіцієнтами ряду Фур’є
  14.   { TForm1 }
  15.  
  16.   TForm1 = class(TForm)
  17.     Button1: TButton;
  18.     Button2: TButton;
  19.     Edit1: TEdit;
  20.     Edit2: TEdit;
  21.     Edit3: TEdit;
  22.     Edit4: TEdit;
  23.     GroupBox1: TGroupBox;
  24.     Image1: TImage;
  25.     Label1: TLabel;
  26.     Label10: TLabel;
  27.     Label11: TLabel;
  28.     Label2: TLabel;
  29.     Label3: TLabel;
  30.     Label4: TLabel;
  31.     Label5: TLabel;
  32.     Label6: TLabel;
  33.     Label7: TLabel;
  34.     Label8: TLabel;
  35.     Label9: TLabel;
  36.     SpinEdit1: TSpinEdit;
  37.     SpinEdit2: TSpinEdit;
  38.     SpinEdit3: TSpinEdit;
  39.     SpinEdit4: TSpinEdit;
  40.     procedure Button1Click(Sender: TObject);
  41.     procedure Button2Click(Sender: TObject);
  42.     procedure Image1Click(Sender: TObject);
  43.   private
  44.  
  45.   public
  46.  
  47.   end;
  48.  
  49. var
  50.   Form1: TForm1;
  51.   Xe, Ye : Vector; // Масиви для зберігання координат нашої періодичної функції
  52. Xg, Yg : Vector; // Масиви для зберігання координат протабульованого ряду Фур'є
  53. a, b, c : Vec; // Масиви для зберігання коефіцієнтів ряду Фур'є
  54. Ne, Ngr, Ng : Integer; // Ne = Ngr кількість точок обох графіків
  55. al, bl, Tp : Real; // Область визначення функції та її період : Tp = bl – al
  56. implementation
  57.  
  58. {$R *.lfm}
  59.   Function f(x : Real) : Real; // Опис нашої періодичної функції
  60. Begin
  61. Tp := bl - al;
  62. if x < TP / 2 then
  63. f:= 2 else
  64. if(x >= TP / 2) and (x < 3 * TP / 4) then
  65. f := 4 * (TP - 2 * x) / TP
  66. else
  67. f := 8 * (x - TP) / TP;
  68. end;
  69. Procedure TabF(var Xe: Vector; var Ye: Vector);// Процедура табулювання періодичної функції
  70. Var h : Real;
  71. i : Integer;
  72. Begin
  73. h := (bl - al) / Ne;
  74. Xe[0]:= al;
  75. For i := 0 to Ne - 1 do
  76. Begin
  77. Ye[i] := f(Xe[i]) ;
  78. Xe[i+1] := Xe[i] + h;
  79. End;
  80. End;
  81. // Процедура побудови і табулювання ряду Фур’є згідно з алгоритмом, що є на рис. 4.
  82. Procedure Furje(Xe, Ye : Vector; Ne : Integer; var Yg : Vector);
  83. Var i, k : Integer;
  84. w, KOM, S, G, D : Real;
  85. Begin
  86. Ng := StrToInt(Form1.Edit2.text); // Вводимо кількість гармонік
  87. TP := bl - al; // TP – період нашої функції
  88. // Обчислення коефіцієнтів ряду Фур'є
  89. w := 2 * Pi / TP;
  90. For k := 1 to Ng do
  91. Begin
  92. KOM := k * w;
  93. G := 0.0;
  94. D := 0.0;
  95. For i :=1 to Ne do
  96. Begin
  97. S := KOM * Xe[i];
  98. G := G + Ye[i] * Cos(S);
  99. D := D + Ye[i] * Sin(S);
  100. End;
  101. a[k] := 2 * G / Ne;
  102. b[k] := 2 * D / Ne;
  103. c[k] := Sqrt(Sqr(a[k]) + Sqr(b[k]));
  104. End;
  105. a[0] := 0.0;
  106. For i := 1 to Ne do
  107. a[0] := a[0] + Ye[i];
  108. a[0] := a[0] / Ne;
  109. For i := 0 to Ne - 1 do // Побудова і табулювання суми ряду Фур’є
  110. Begin
  111. S := 0;
  112. D := Xe[i] * w;
  113. For k:=1 to Ng do
  114. Begin
  115. KOM := k * D;
  116. S := S + b[k] * Sin(KOM) + a[k] * Cos(KOM);
  117. End;
  118. Yg[i] := a[0] + S;
  119. End;
  120. End;
  121. { TForm1 }
  122.  
  123. procedure TForm1.Image1Click(Sender: TObject);
  124. begin
  125.  
  126. end;
  127.  
  128. procedure TForm1.Button1Click(Sender: TObject);
  129. Var p,zx,zy,ay,bx,krx,kry,xx,yy,Gx,Gy : Real;
  130. i,j,krokx,kroky,drv,drm,visx,visy : Integer;
  131. l:Integer;
  132. minYg,maxYg,maxx,maxy,minx,miny,kx,ky:real;
  133.   Procedure Garm(Ng : Integer; c:Vec);
  134. Var i , Krokx, x : Integer;
  135. MaxC, Ky, W : Real;
  136. Begin
  137. Krokx := (Image1.ClientWidth - 2 * L) div Ng;
  138. MaxC := c[1];
  139. For I := 2 to Ng do
  140. If c[i] > MaxC then MaxC := c[i];
  141. Ky := (Image1.ClientHeight div 2) / MaxC;
  142. With Image1.Canvas do
  143. Begin
  144. Pen.Color := clHighlight;
  145. Pen.Width := 2;
  146. MoveTo(L, L + 20 );
  147. LineTo(L + 10, L + 10);
  148. LineTo(L + 20, L + 20);
  149. MoveTo(L + 10, L + 10);
  150. LineTo(L + 10, Image1.ClientHeight - 50);
  151. LineTo(Image1.ClientWidth-20, Image1.ClientHeight-50);
  152. MoveTo(Image1.ClientWidth-40, Image1.ClientHeight-60);
  153. LineTo(Image1.ClientWidth-20, Image1.ClientHeight-50);
  154. LineTo(Image1.ClientWidth-40, Image1.ClientHeight-40);
  155. TextOut(L - 2, L ,'C');
  156. TextOut(ClientWidth - 50, ClientHeight - 25 ,'W');
  157. Pen.Color := clFuchsia;
  158. Pen.Width := 2;
  159. x := KrokX + 20;
  160. w := 2 * Pi /(bl - al);
  161. For i:= 1 to Ng do
  162. Begin
  163. MoveTo(Round(x)+3,Image1.ClientHeight-50);
  164. LineTo(Round(x)+3,Image1.ClientHeight-50-Round(ky*c[i]));
  165. TextOut(round(x),Image1.ClientHeight - Round(ky*c[i])-65, FloatToStrF(x,ffGeneral,0,0));
  166. Ellipse(round(x),Image1.ClientHeight-53,round(x)+5,Image1.ClientHeight-48);
  167. Ellipse(Round(x)+1,Image1.ClientHeight-50-Round(ky*c[i]),Round(x)+7,
  168. Image1.ClientHeight-50-Round(ky*c[i])+5);
  169. x := x + KrokX;
  170. End;
  171. x := KrokX + 19;
  172. TextOut(round(x),Image1.ClientHeight - 30,'W='+FloatToStrF(w,ffGeneral,0,0));
  173. End;
  174. End;
  175. // Процедура візуалізації гармонік
  176. begin
  177.  
  178.  
  179. // Початок виконуваної частини процедури TForm1.Button1Click
  180. Begin
  181. Ne := StrToInt(Edit1.Text);
  182. Ngr:= Ne;
  183. al := StrToFloat(Form1.Edit3.Text);
  184. bl := StrToFloat(Form1.Edit4.Text);
  185. TabF( Xe, Ye); // Табулюємо задану нами періодичну функцію
  186. Furje(Xe,Ye,Ne,Yg); // Обчислюємо коефіцієнти ряду Фур'є і табулюємо суму ряду
  187. // Будуємо графіки обох функцій Ye(Xe) та Yg(Xe)
  188. L:=40; // Відступ від країв компоненти TImage
  189. With Form1.Image1 do
  190. Begin
  191. Canvas.Pen.Width := 2;
  192. Canvas.Pen.Color := clBlue;
  193. Canvas.Pen.Style := psSolid;
  194. Canvas.Rectangle(1, 1, Width - 1, Height - 1);
  195. MinYg:=Yg[0]; MaxYg:=Yg[0];
  196. For i := 1 to Ngr - 1 do
  197. Begin
  198. If MaxYg < Yg[i] then MaxYg := Yg[i];
  199. If MinYg > Yg[i] then MinYg := Yg[i];
  200. End;
  201. MinX := Xe[0]; MaxX := Xe[Ne-1];
  202. MinY := Ye[0]; MaxY := Ye[0];
  203. For i := 1 to Ne - 1 do
  204. Begin
  205. If MaxY< Ye[i] then MaxY := Ye[i];
  206. If MinY> Ye[i] then MinY := Ye[i];
  207. End;
  208. If MaxY < MaxYg then MaxY := MaxYg;
  209. If MinY > MinYg then MinY := MinYg;
  210. // Обчислюємо зачення коефіцієнтів масштабування
  211. Kx := (Width - 2 * L) /(MaxX - MinX);
  212. Ky := (Height - 2 * L) /(MinY - MaxY);
  213. Zx := (Width * MinX - L * (MinX + MaxX)) / (MinX - MaxX);
  214. Zy := (Height * MaxY - L * (MinY + MaxY)) / (MaxY - MinY);
  215. End;
  216. // Обчислюємо розташування плаваючих осей
  217. If MinX * MaxX <= 0.0 then Gx := 0.0;
  218. If (MinX * MaxX > 0.0) then Gx := MinX;
  219. If (MinX * MaxX > 0.0) then Gx := MinX;
  220. If (MinX * MaxX > 0.0) and (MinX < 0.0) then Gx := MaxX;
  221. If MinY * MaxY <= 0.0 then Gy := 0.0;
  222. If (MinY * MaxY > 0.0) and (MinY > 0.0) then Gy := MinY;
  223. If (MinY * MaxY > 0.0) and (MinY < 0.0) then Gy := MaxY;
  224. With Form1.Image1.Canvas do // ------------------------
  225. Begin
  226. Pen.Color := clSilver;
  227. Pen.Width := SpinEdit3.Value;
  228. KrokX := (Width - 2 * L) div 10;
  229. KrokY := (Height - 2 * L) div 10;
  230. For i := 0 to 10 do
  231. Begin
  232. MoveTo(L, Round(Ky * Gy + Zy) + i * KrokY);
  233. LineTo(Width - L, Round(Ky * Gy + Zy) + i * KrokY);
  234. MoveTo(L, Round(Ky * Gy + Zy) - i * KrokY);
  235. LineTo(Width - L, Round(Ky * Gy + Zy) - i * KrokY);
  236. MoveTo(Round(Kx * Gx + Zx) + i * KrokX,L);
  237. LineTo(Round(Kx * Gx + Zx) + i * KrokX, Height - L);
  238. MoveTo(Round(Kx * Gx + Zx) - i * KrokX, L);
  239. LineTo(Round(Kx * Gx + Zx) - i * KrokX, Height - L);
  240. End;
  241. // Виведення підписів осей координат---------------------------------
  242. xx := MinX; yy := MaxY;
  243. KrX := (MaxX - MinX) / 10.0;
  244. KrY := (MaxY - MinY) / 10.0;
  245. For i:=0 to 9 do
  246. Begin
  247. TextOut(L + 4 + i * KrokX,
  248. Round(Ky * Gy + Zy) - L + 43,
  249. FloatToStrF(XX, ffGeneral, 2, 5));
  250. TextOut(Round(Kx*Gx+Zx)-L+10,
  251. L + i * KrokY - 5,
  252. FloatToStrF(YY, ffGeneral, 2, 5));
  253. Pen.Color:=clFuchsia;
  254. XX := XX + KrX;
  255. yy := yy - KrY;
  256. End;
  257. Pen.Style := psSolid;// Малюємо плаваючі осі----------
  258. Pen.Color := clGreen;
  259. Pen.Width := SpinEdit2.Value;
  260. MoveTo(L, Round(Ky * Gy + Zy));
  261. LineTo(Round(Width - L), Round(Ky * Gy + Zy));
  262. MoveTo(Round(Kx * Gx + Zx), L);
  263. LineTo(Round(Kx * Gx + Zx), Round( Height - L));
  264. Pen.Width:=SpinEdit1.Value;
  265. Pen.Color:=clFuchsia;
  266. MoveTo(Round(Kx * Xe[0]+Zx), Round(Ky * Ye[0] + Zy));
  267. For i := 0 to Ne - 1 do
  268. LineTo(Round(Kx * Xe[i]+Zx), Round(Ky * Ye[i] + zy));
  269. Pen.Width:=SpinEdit4.Value;
  270. Pen.Color:=clGreen;
  271. MoveTo(Round (Kx*Xe[0]+Zx),Round(Ky*Yg[0]+Zy));
  272. For i:=0 to Ne-1 do
  273. LineTo(Round (Kx*Xe[i]+Zx),Round(Ky*Yg[i]+Zy));
  274. end;
  275. ShowMessage('Показати гармоніки ?');
  276. Garm(Ng, c);
  277. end;
  278. end;
  279.  
  280. procedure TForm1.Button2Click(Sender: TObject);
  281. begin
  282.   Close();
  283. end;
  284.  
  285. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement