From 3c0a3b8413ee58a3e5678075c862e95f7c8395c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=B3=D0=BE=D1=80=20=D0=9B=D1=8C=D0=B2=D0=BE=D0=B2?= Date: Mon, 27 Mar 2023 11:25:27 +0300 Subject: =?UTF-8?q?=D0=9D=D0=B0=D1=87=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9?= =?UTF-8?q?=20=D0=BA=D0=BE=D0=BC=D0=BC=D0=B8=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- simulations/boids.c | 237 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 237 insertions(+) create mode 100644 simulations/boids.c (limited to 'simulations/boids.c') diff --git a/simulations/boids.c b/simulations/boids.c new file mode 100644 index 0000000..84afc21 --- /dev/null +++ b/simulations/boids.c @@ -0,0 +1,237 @@ +#ifdef _WIN32 // грубый способ определения; на деле разница не в ОС, а в компиляторe + #include + #include + #include +#else + #include + #include + #include +#endif +#include +#include + +#define SCALE 1 +#define BOIDNUM 30 +#define SPEED 1 +#define CRANGE 30 +#define WIDTH 1280 +#define HEIGHT 640 +#define PI 3.1415926535 + +struct boid { double x, y, dx, dy, th; }; +typedef struct vec { float x, y; } vector; +struct boid B[BOIDNUM]; +char color[3] = {0, 255, 0}; + +int init() +{ + srand(time(NULL)); + + for(int i = 0; i CRANGE) {continue;} + if(b == n) {continue;} + sum.x += B[b].x; + sum.y += B[b].y; + } + + sum.x /= BOIDNUM - 1; + sum.y /= BOIDNUM - 1; + + sum.x -= B[n].x; + sum.y -= B[n].y; + sum.x /= factor; + sum.y /= factor; + + return sum; +} + +vector separation(int n, float dist, int factor) +{ + vector c = {0, 0}; + c.x = 0; + c.y = 0; + + for(int b = 0; b < BOIDNUM; b++) { + if(geomdist(n, b) > CRANGE) {continue;} + if(b == n) {continue;} + if(geomdist(n, b) < dist) { + c.x -= B[b].x - B[n].x; + c.y -= B[b].y - B[n].y; + } + } + + c.x /= factor; + c.y /= factor; + + return c; +} + +vector alignment(int n, int factor) +{ + vector pv = {0, 0}; + + for(int b = 0; b < BOIDNUM; b++) { + if(geomdist(n, b) > CRANGE) {continue;} + if(b == n) {continue;} + pv.x += B[b].dx; + pv.y += B[b].dy; + } + + pv.x /= BOIDNUM - 1; + pv.y /= BOIDNUM - 1; + + pv.x -= B[n].dx; + pv.y -= B[n].dy; + pv.x /= factor; + pv.y /= factor; + + return pv; +} + +int updatePos(SDL_Renderer *renderer) { + vector v[3]; + for(int i = 0; i WIDTH) + B[i].x -= WIDTH; + // B[i].dx = 0; + if(B[i].y > HEIGHT) + B[i].y -= HEIGHT; + // B[i].dy = 0; + if(B[i].x < 0) + B[i].x += WIDTH; + // B[i].dx = 0; + if(B[i].y < 0) + B[i].y += HEIGHT; + // B[i].dy = 0; + + v[0] = cohesion(i, 40); + v[1] = separation(i, 20, 200); + // v[0].x = 0; + // v[0].y = 0; + v[2] = alignment(i, 80); + // v[2].x = 0; + // v[2].y = 0; + + for(int j = 0; j<3; j++) { + if(i == 0) { + SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); + SDL_RenderDrawLine(renderer, B[i].x, B[i].y, B[i].x-v[j].x, B[i].y - v[j].y); + SDL_RenderPresent(renderer); + printf("|vx = %f, vy = %f", v[j].x, v[j].y); + } + + B[i].dx += v[j].x / 1000; + B[i].dy += v[j].y / 1000; + } + // if (B[i].dx > sqrt(50)) B[i].dx = sqrt(50); + // if (B[i].dy > sqrt(50)) B[i].dy = sqrt(50); + B[i].th = acos(B[i].dx / sqrt(B[i].dx * B[i].dx + B[i].dy * B[i].dy) + 0.0001); + // if(i == 0) { + // printf("%f|", B[i].th); + // } + } + return 0; +} + +int main(int argc, char *argv[]) +{ + SDL_Window *window = NULL; + SDL_Renderer *renderer = NULL; + + init(); + SDL_Init(SDL_INIT_VIDEO); + + window = SDL_CreateWindow("Boids", + SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, + WIDTH, + HEIGHT, + 0); + renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); + + while(1) { + if(processEvents(window) == 1) + break; + render(renderer); + updatePos(renderer); + SDL_Delay(10); + } + + return 0; +} \ No newline at end of file -- cgit v1.2.3