Nadesłany przez Tomasz Lubiński, 01 sierpnia 2005 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.
Krzywe cykliczne/kc.pas:
//www.algorytm.org //krzywe cykliczne by Tomasz Lubinski (C)2002 unit kc; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Buttons, ToolWin, ComCtrls, ActnList, StdActns, ExtDlgs; type TForm1 = class(TForm) GroupBox1: TGroupBox; Label1: TLabel; Label2: TLabel; Label3: TLabel; Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Button2: TButton; Button3: TButton; Shape1: TShape; Timer1: TTimer; ScrollBar1: TScrollBar; ScrollBar2: TScrollBar; ScrollBar3: TScrollBar; SpeedButton1: TSpeedButton; SpeedButton2: TSpeedButton; SpeedButton3: TSpeedButton; SaveDialog1: TSaveDialog; RadioButton1: TRadioButton; RadioButton2: TRadioButton; procedure Edit1Change(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure FormCreate(Sender: TObject); procedure ScrollBar3Change(Sender: TObject); procedure ScrollBar2Change(Sender: TObject); procedure ScrollBar1Change(Sender: TObject); procedure SpeedButton3Click(Sender: TObject); procedure SpeedButton1Click(Sender: TObject); procedure SpeedButton2Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure FormPaint(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private { Private declarations } public { Public declarations } end; type watek = class(TThread) private protected procedure Execute; override; procedure Rysowanie; end; var Form1: TForm1; r, r_toru, m, predkosc, gestosc, x, y, x1, y1, wsp, znak: Integer; i: Real; okrag1,okrag2,odcinek: TColor; rys, tmp: TBitMap; w: TThread; implementation uses opcje; {$R *.DFM} //początkowe ustawienie wszystkich wartosci procedure TForm1.FormCreate(Sender: TObject); begin okrag1:=clRed; okrag2:=clBlue; odcinek:=clGreen; gestosc:=50; predkosc:=100; rys:=TBitMap.Create; rys.Height:=400; rys.Width:=400; tmp:=TBitMap.Create; tmp.Height:=400; tmp.Width:=400; wsp:=60; znak:=+1; tmp.Canvas.Brush.Style:= bsClear; //bez wypelnienia Timer1.Enabled:=True; end; //funkcja wywolywana podczas zmiany danych w paramtetrach podstawowych procedure TForm1.Edit1Change(Sender: TObject); begin i:=0; Timer1Timer(Form1); end; //rysowanie podstawowe (dwa okręgi i odcinek wodzacy i dotychczasowa krzywa) procedure TForm1.Timer1Timer(Sender: TObject); begin if Edit1.Text<>'' then r:=StrToInt(Edit1.text); if Edit2.Text<>'' then r_toru:=StrToInt(Edit2.text); if Edit2.Text<>'' then m:=StrToInt(Edit3.text); if RadioButton1.checked then begin //hipotrochoida wsp:=r_toru-r; znak:=+1; end else begin //epitrochoida wsp:=r_toru+r; znak:=-1; end; x:=trunc(wsp*cos(i)+znak*m*cos(wsp*(i/r))); //oblicz wspolrzedne y:=trunc(wsp*sin(i)-m*sin(wsp*(i/r))); x1:=trunc(wsp*cos(i)); y1:=trunc(wsp*sin(i)); tmp.Canvas.Draw(0,0,rys); //dotychczasowa krzywa tmp.Canvas.Pen.Color:=okrag2; tmp.Canvas.Ellipse(x1+200-r,y1+r+200,x1+r+200,y1-r+200); tmp.Canvas.Pen.Color:=okrag1; tmp.Canvas.Ellipse(200-r_toru,200+r_toru,200+r_toru,200-r_toru); tmp.Canvas.Pen.Color:= odcinek; tmp.Canvas.MoveTo(x1+200,y1+200); tmp.Canvas.LineTo(x+200,y+200); Form1.Canvas.Draw(175,10,tmp); //narysuj calosc Timer1.Enabled:=False; end; //watek do rysowania procedure watek.Rysowanie; begin rys.Canvas.Pen.Color:= odcinek; rys.Canvas.MoveTo(x+200,y+200); rys.Canvas.LineTo(x+201,y+201); tmp.Canvas.Draw(0,0,rys); //dotychczasowa krzywa tmp.Canvas.Pen.Color:=okrag2; tmp.Canvas.Ellipse(x1+200-r,y1+r+200,x1+r+200,y1-r+200); tmp.Canvas.Pen.Color:=okrag1; tmp.Canvas.Ellipse(200-r_toru,200+r_toru,200+r_toru,200-r_toru); tmp.Canvas.Pen.Color:= odcinek; tmp.Canvas.MoveTo(x1+200,y1+200); tmp.Canvas.LineTo(x+200,y+200); Form1.Canvas.Draw(175,10,tmp); //narysuj calosc end; //watek do animacji procedure watek.Execute; begin while (true) do begin i:=i+1/gestosc; sleep(Trunc(100/predkosc)); //odczekaj chwile okreslona przez predkosc x:=trunc(wsp*cos(i)+znak*m*cos(wsp*(i/r))); //oblicz wspolrzedne y:=trunc(wsp*sin(i)-m*sin(wsp*(i/r))); x1:=trunc(wsp*cos(i)); y1:=trunc(wsp*sin(i)); Synchronize(Rysowanie); end; end; //obsluga paskow przewijania procedure TForm1.ScrollBar1Change(Sender: TObject); begin Edit1.Text:=IntToStr(ScrollBar1.Position); end; procedure TForm1.ScrollBar2Change(Sender: TObject); begin Edit2.Text:=IntToStr(ScrollBar2.Position); end; procedure TForm1.ScrollBar3Change(Sender: TObject); begin Edit3.Text:=IntToStr(ScrollBar3.Position); end; //wymazanie obrazu krzywych procedure TForm1.SpeedButton1Click(Sender: TObject); begin rys.FreeImage; rys:=TBitMap.Create; rys.Height:=400; rys.Width:=400; Timer1.Enabled:=True; end; //zapisanie obrazu krzywych procedure TForm1.SpeedButton2Click(Sender: TObject); var f:String; begin SaveDialog1.Execute; f:=SaveDialog1.FileName; rys.SaveToFile(f); Timer1.Enabled:=True; end; //wywolanie opcji zaawansowanych procedure TForm1.SpeedButton3Click(Sender: TObject); begin Form2.Visible:=True; end; //uruchomienie watku procedure TForm1.Button2Click(Sender: TObject); begin if w=nil then begin w:=watek.Create(false); w.Priority:=tpNormal; end; if w<>nil then if w.Suspended then w:=watek.Create(false); end; //odrysowywanie rysunku tylko wowczas gdy watek jest wylaczony procedure TForm1.FormPaint(Sender: TObject); begin if w<>nil then if w.Suspended then Timer1.Enabled:=True; if w=nil then Timer1.Enabled:=True; end; //zatrzymanie watku procedure TForm1.Button3Click(Sender: TObject); begin if w<>nil then w.Suspend; end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin if w<>nil then w.Suspend; end; end.