Nadesłany przez Marcin Ant, 15 marca 2006 01:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
Rownania rozniczkowe czastkowe Poissona/rozkladU.pas:
// Rownania rozniczkowe czastkowe Poissona // www.algorytm.org // (c)2006 Marcin Ant unit rozkladU; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Math, ComCtrls; type TRozklad = class(TForm) Image1: TImage; btnPrzerwij: TButton; btnObliczenia: TButton; Bevel1: TBevel; Image2: TImage; lbMin: TLabel; lbMax: TLabel; procedure btnObliczeniaClick(Sender: TObject); procedure btnPrzerwijClick(Sender: TObject); private { Private declarations } public { Public declarations } end; var Rozklad: TRozklad; bWarunek : boolean; implementation {$r *.dfm} procedure TRozklad.btnObliczeniaClick(Sender: TObject); const Kolor : Array[1..32] of TColor = ($0000ff, $0040ff, $0060ff, $0080ff, $00a0ff, $00c0ff, $00e0ff, $00ffff, $04fbed, $0cf3d7, $12e9b9, $1fe0a6, $26d98d, $2cd362, $35ca57, $46bf45, $73c03f, $87c63c, $9aca35, $aecd32, $c7cb35, $d3d32c, $e5d91c, $e4d01b, $e6c71a, $e6b71a, $e6ad1a, $e69e1a, $e68e1a, $e67a1a, $e6671a, $e64a1b); var i,j : integer; eps,epsmax,Vs : double; V: array [0..100,0..100] of double; // potencjal V_bok : array [1..6] of double; //potencjaly boków (temperatury) minV,maxV : double; imgRozklad:TBitmap; function ktory_color(v:real):TColor; var i,il_barw : integer; zakres,d_color : double; begin zakres := abs(maxV-minV); il_barw := 32; d_color := zakres / (il_barw-1); i := Trunc((V-minV)/(d_color)); ktory_color := Kolor[32 - i]; end; begin imgRozklad:=TBitmap.create; imgRozklad.Height:=101; imgRozklad.Width:=101; // war poczatkowe V_bok[1]:=100; //V gora V_bok[2]:=0; //V dol tu nalezy zmienic wartosci temperatury V_bok[3]:=0; //V prawa V_bok[4]:=0; //V lewa V_bok[5]:=0; //wartosci poczatkowe - warunek poczatkowy V_bok[6]:=-30; //Wartosc Losowa - wartosc zaburzenia // szukanie min i max minV := v_bok[1]; maxV := v_bok[1]; for i:=1 to 6 do begin if V_bok[i] < minV then minv := v_bok[i]; if V_bok[i] > maxV then MaxV := v_bok[i]; end; lbMin.Caption := FloatToStr(minV); lbMax.Caption := FloatToStr(maxV); //Skala rysowanie for i:=1 to Image2.Height do begin Image2.Canvas.Pen.Color := ktory_color(i*(maxV-minV)/Image2.Height+minV); Image2.Canvas.Moveto(0, Image2.Height-i); Image2.Canvas.LineTo(Image2.Width, Image2.Height-i); end; // inicjalizacja wartosci poczatkowych () for i:=0 to 100 do for j:=0 to 100 do v[i,j]:=v_bok[5]; bWarunek := false; //war zakonczenia epsmax := 0.1; repeat // obliczenia numeryczne (metoda Gaussa-Seidla) for i:=0 to 100 do for j:=0 to 100 do begin if i = 0 then V[i,j]:=V_bok[4] else if i = 100 then V[i,j]:=V_bok[3] else //if i = 100 then V[i,j]:=V[i-1,j] else //przy warunku Neumana if j = 0 then V[i,j]:=V_bok[1] else if j = 100 then V[i,j]:=V_bok[2] else if (i in [40..45]) and (j in [40..45]) then V[i,j]:=V_bok[6] //zaburzenie osrodka else // z przedzialu V[i,j]:=(V[i-1,j]+V[i+1,j]+V[i,j-1]+V[i,j+1])/4; eps:=eps+abs(V[i,j]-Vs) end; // wyswietlenie wyniku for i:=0 to 100 do for j:=0 to 100 do imgRozklad.Canvas.Pixels[i,j]:=ktory_color(V[i,j]); Image1.Canvas.StretchDraw(Image1.Canvas.ClipRect,imgRozklad); Image1.Invalidate; Application.ProcessMessages; until ((eps/MaxV)<epsmax) or bWarunek; end; procedure TRozklad.btnPrzerwijClick(Sender: TObject); begin bWarunek := true; end; end.