algorytm.org

Implementacja w C/C++



Baza Wiedzy
wersja offline serwisu przeznaczona na urządzenia z systemem Android
Darowizny
darowiznaWspomóż rozwój serwisu
Nagłówki RSS
Artykuły
Implementacje
Komentarze
Forum
Bookmarki






Sonda
Implementacji w jakim języku programowania poszukujesz?

Boidy - Implementacja w C/C++
Ocena użytkownikóww: *****  / 6
SłabyŚwietny
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;
                }
        }
}
//---------------------------------------------------------------------------
 
Dodaj komentarz