Nadesłany przez Tomasz Lubiński, 27 lipca 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.
Boidy C++/Unit2.cpp:
//www.algorytm.org //Boidy //(c) 2003 Tomasz Lubinski #include <vcl.h> #include "unit1.h" #include <math.h> #pragma hdrstop #include "Unit2.h" #pragma package(smart_init) __fastcall Watek::Watek(bool CreateSuspended) : TThread(CreateSuspended){ } struct boid { float x,y; //polozenie float vx,vy; //skladowa pionowa i pozioma predkosci float srednia_vx, srednia_vy, srednia_odleglosc;//srednie sasiadow int l; //liczba sąsiadow+1 }; int n; boid b[100]; float r,odl,k,min,kat,w_predkosci,w_odleglosci,w_minimum,w_zaklucen,v_max; Graphics::TBitmap *tmp = new Graphics::TBitmap(); void __fastcall Watek::Rysowanie() { //ruch i rysowanie tmp->Canvas->Rectangle(0,0,450,400); for (int i=0; i<n; i++) { b[i].x+=b[i].vx; b[i].y+=b[i].vy; if (b[i].vx==0) b[i].vx=v_max/1000; if (b[i].vy==0) b[i].vy=v_max/1000; if (b[i].vx<0) { tmp->Canvas->MoveTo(b[i].x,b[i].y); tmp->Canvas->LineTo(b[i].x-8*cos(atan(b[i].vy/b[i].vx)),b[i].y-8*sin(atan(b[i].vy/b[i].vx))); tmp->Canvas->MoveTo(b[i].x,b[i].y); tmp->Canvas->LineTo(b[i].x-3*cos(atan(b[i].vy/b[i].vx)+M_PI/2),b[i].y-3*sin(atan(b[i].vy/b[i].vx)+M_PI/2)); tmp->Canvas->LineTo(b[i].x-7*cos(atan(b[i].vy/b[i].vx)),b[i].y-7*sin(atan(b[i].vy/b[i].vx))); tmp->Canvas->MoveTo(b[i].x,b[i].y); tmp->Canvas->LineTo(b[i].x-3*cos(atan(b[i].vy/b[i].vx)-M_PI/2),b[i].y-3*sin(atan(b[i].vy/b[i].vx)-M_PI/2)); tmp->Canvas->LineTo(b[i].x-7*cos(atan(b[i].vy/b[i].vx)),b[i].y-7*sin(atan(b[i].vy/b[i].vx))); } else { tmp->Canvas->MoveTo(b[i].x,b[i].y); tmp->Canvas->LineTo(b[i].x+8*cos(atan(b[i].vy/b[i].vx)),b[i].y+8*sin(atan(b[i].vy/b[i].vx))); tmp->Canvas->MoveTo(b[i].x,b[i].y); tmp->Canvas->LineTo(b[i].x+3*cos(atan(b[i].vy/b[i].vx)+M_PI/2),b[i].y+3*sin(atan(b[i].vy/b[i].vx)+M_PI/2)); tmp->Canvas->LineTo(b[i].x+7*cos(atan(b[i].vy/b[i].vx)),b[i].y+7*sin(atan(b[i].vy/b[i].vx))); tmp->Canvas->MoveTo(b[i].x,b[i].y); tmp->Canvas->LineTo(b[i].x+3*cos(atan(b[i].vy/b[i].vx)-M_PI/2),b[i].y+3*sin(atan(b[i].vy/b[i].vx)-M_PI/2)); tmp->Canvas->LineTo(b[i].x+7*cos(atan(b[i].vy/b[i].vx)),b[i].y+7*sin(atan(b[i].vy/b[i].vx))); } } Form1->Canvas->Draw(185,10,tmp); } void __fastcall Watek::Execute() { tmp->Width=450; tmp->Height=400; tmp->Canvas->Brush->Color=clSkyBlue; n=StrToInt(Form1->LabeledEdit1->Text); for (int i=0; i<n; i++) { b[i].x=random(400); b[i].y=random(400); b[i].vx=random(40)/10.0-2; b[i].vy=random(40)/10.0-2; } while (1==1) { //odczytanie parametrow z formularza r=StrToFloat(Form1->LabeledEdit2->Text); kat=StrToFloat(Form1->LabeledEdit3->Text); min=StrToFloat(Form1->LabeledEdit4->Text); w_predkosci=StrToFloat(Form1->LabeledEdit5->Text)/100; w_odleglosci=StrToFloat(Form1->LabeledEdit6->Text)/100; w_minimum=StrToFloat(Form1->LabeledEdit7->Text)/100; w_zaklucen=StrToFloat(Form1->LabeledEdit8->Text)/100; v_max=StrToFloat(Form1->LabeledEdit9->Text); //ruch i rysowanie Synchronize(Rysowanie); Sleep(20); //obliczenia for (int i=0; i<n; i++) { b[i].srednia_vx=b[i].vx; b[i].srednia_vy=b[i].vy; b[i].srednia_odleglosc=0; b[i].l=1; for (int j=0; j<n; j++) { if (j==i) continue; odl=sqrt(pow(b[i].x-b[j].x,2)+pow(b[i].y-b[j].y,2)); k = b[i].vx/sqrt(b[i].vx*b[i].vx+b[i].vy*b[i].vy) * ((b[j].x-b[i].x)/odl) + b[i].vy/sqrt(b[i].vx*b[i].vx+b[i].vy*b[i].vy) * ((b[j].y-b[i].y)/odl); if (k < -1) k = -1; else if (k > 1) k = 1; k = fabs((180.0*acos(k))/M_PI); if (odl<r&&k<kat) { b[i].l++; b[i].srednia_vx+=b[j].vx; b[i].srednia_vy+=b[j].vy; b[i].srednia_odleglosc+=odl; } } } for (int i=0; i<n; i++) { //dostosuj do srednich predkosci sasiadow b[i].vx+=(w_predkosci*((b[i].srednia_vx/b[i].l)-b[i].vx)); b[i].vy+=(w_predkosci*((b[i].srednia_vy/b[i].l)-b[i].vy)); //zaklucenia b[i].vx+=(w_zaklucen*((random(100)/100.0-0.5)*v_max)); b[i].vy+=(w_zaklucen*((random(100)/100.0-0.5)*v_max)); if (b[i].l>1) b[i].srednia_odleglosc/=(b[i].l-1); for (int j=0; j<n; j++) { if (j==i) continue; odl=sqrt(pow(b[i].x-b[j].x,2)+pow(b[i].y-b[j].y,2)); k = b[i].vx/sqrt(b[i].vx*b[i].vx+b[i].vy*b[i].vy) * ((b[j].x-b[i].x)/odl) + b[i].vy/sqrt(b[i].vx*b[i].vx+b[i].vy*b[i].vy) * ((b[j].y-b[i].y)/odl); if (k < -1) k = -1; else if (k > 1) k = 1; k = fabs((180.0*acos(k))/M_PI); if (odl<r&&k<kat) { if (abs(b[j].x-b[i].x)>min) { b[i].vx+=(w_odleglosci/b[i].l)*(((b[j].x-b[i].x)*(odl-b[i].srednia_odleglosc))/odl); b[i].vy+=(w_odleglosci/b[i].l)*(((b[j].y-b[i].y)*(odl-b[i].srednia_odleglosc))/odl); } else //jeżeli sąsiedzi są za blisko { b[i].vx-=(w_minimum/b[i].l)*((((b[j].x-b[i].x)*(min))/odl)-(b[j].x-b[i].x)); b[i].vy-=(w_minimum/b[i].l)*((((b[j].y-b[i].y)*(min))/odl)-(b[j].y-b[i].y)); } } } if (sqrt(b[i].vx*b[i].vx+b[i].vy*b[i].vy)>v_max) { b[i].vx=0.75*b[i].vx; b[i].vy=0.75*b[i].vy; } } //przepisanie boidow znajdujacych sie za plansza for (int i=0; i<n; i++) { if (b[i].x<0) b[i].x+=450; if (b[i].y<0) b[i].y+=400; if (b[i].x>450) b[i].x-=450; if (b[i].y>400) b[i].y-=400; } } } //---------------------------------------------------------------------------