Grupo - BOIDS/codigo BOIDS cardume: mudanças entre as edições
Ir para navegação
Ir para pesquisar
(Criou página com '<br /> <source lang="c"> #include<stdio.h> #include<math.h> #include<stdlib.h> #include<time.h> // programa particulas boids para CC periodica. #define N 500...') |
Sem resumo de edição |
||
Linha 35: | Linha 35: | ||
//**********inicializar particulas (posicao e velocidade)**********// | //**********inicializar particulas (posicao e velocidade)**********// | ||
printf("set terminal gif animate delay 1.0E-5\n");// Produz arquivo .gif | printf("set terminal gif animate delay 1.0E-5\n");// Produz arquivo .gif | ||
printf("set output ' | printf("set output 'boidcvel.gif'\n"); // | ||
printf("set title 'Tempo t = 0'\n"); // | printf("set title 'Tempo t = 0'\n"); // | ||
printf("set xrange [0:%lf]\n", L); // caso rode com |gnuplot aparecem | printf("set xrange [0:%lf]\n", L); // caso rode com |gnuplot aparecem |
Edição atual tal como às 05h20min de 25 de janeiro de 2018
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<time.h>
// programa particulas boids para CC periodica.
#define N 500 // numero de particulas
#define T 3200 // numero de passos
#define C 0.2 // constante de coesao
#define S 0.3 // constante de separaçao
#define ini 2 // valor maximo das componentes da velocidade
// valor maximo da velocidade (sqrt(2)*ini)
#define PI 3.1415926538979 //aprox de pi
#define I 15 // numero de passos entre as plotagens
#define E 8 // distancia maxima que a barreira afeta os BOIDS
#define EE 0.01 // barreira dificulta a chegada nas fronteiras
double norm(double x, double y){ //funçao norma
return sqrt(x*x + y*y);
}
main(){
double r[N][2], v[N][2], epsilon=0.00001, R=8, rmin=2, erre=7, dt = 0.1;
double randomi=0;
double x=0., y=0., vel[N], L=100, vmx=0, vmy=0, vmed=0, vmedl =0;
int i=0, j=0, k=0, l=0, m=0, t=0;
int cont=0, kont=0; //conta o numero de vizinhos proximos da particula
int vizinhos[N][2]; //nao deixa a velocidade explodir nem tender a 0
//**********inicializar particulas (posicao e velocidade)**********//
printf("set terminal gif animate delay 1.0E-5\n");// Produz arquivo .gif
printf("set output 'boidcvel.gif'\n"); //
printf("set title 'Tempo t = 0'\n"); //
printf("set xrange [0:%lf]\n", L); // caso rode com |gnuplot aparecem
printf("set yrange [0:%lf]\n", L); // os graficos.
printf("plot '-' w p pt 10\n"); //
for(i=0;i<N;i++){
r[i][0] = L*rand()/RAND_MAX; //
r[i][1] = L*rand()/RAND_MAX; // Inicializa as pos e vel
v[i][0] = ini*(2.*rand()/RAND_MAX - 1); // das particulas aleatoriamente
v[i][1] = ini*(2.*rand()/RAND_MAX - 1); //
printf("%lf %lf \n", r[i][0], r[i][1]); //
}
printf("e \n");
//**********Dinamica das Particulas**********//
do{ //inicio do passo de tempo
if(t%I == 0){
printf("set title 'Tempo t = %.1lf'\n", t*dt); //
printf("set xrange [0:%lf]\n",L); // Caso rode com |gnuplot
printf("set yrange [0:%lf]\n",L); // sao gerados os graficos
printf("plot '-' w p pt 10\n"); //
}
vmed = 0; // velocidade media das particulas
for(j=0;j<N;j++){ // dinamica de cada particula
cont=0; // contador para coesao das particulass
x = 0; // media das particulas vizinhas para coesao
y = 0; // media das particulas vizinhas para coesao
kont = 0; // contador para media das velocidades
vmx = 0; // media das veloc. das particulas
vmy = 0; // media das veloc. das particulas
//**********Media da Velocidade dos Vizinhos**********//
for(k=0;k<N;k++){ // laço para todas ass particulas
if(k == j){ // se eh a mesma particula nao faz nada
}else if(norm(r[j][1]-r[k][1],r[j][0]-r[k][0])<erre){
kont++; // se eh outra particula acrescenta no contador
vmx = vmx + v[k][0]; // acrescenta a velocidade na componente x
vmy = vmy + v[k][1]; // acrescenta a velocidade na componente y
}
}
if(kont > 1){
v[j][0] = vmx/kont; // media com peso M para a vel.
v[j][1] = vmy/kont; // dos vizinhos e a propria
}
//**********Coesao Entre Particulas e CM**********//
for(m=0;m<N;m++){ // laço das particulas
if(norm(r[j][1]-r[m][1],r[j][0]-r[m][0])<R){// se as particulas tiverem
// a uma distancia menor q
// "R"
cont++; // acrescenta no contador
x = x + r[m][0]; // acrescenta na posicao das particulas na comp. x
y = y + r[m][1]; // acrescenta na posicao das particulas na comp. y
}
}
if(cont>1){ // se contador for cont > 1
x = x/cont; // media aritmetica na componente x
y = y/cont; // media aritmetica a componente y
v[j][0] = v[j][0] - C*(r[j][0] - x)/L; // atualiza velocidade c pote-
// ncial de mola na componente x
v[j][1] = v[j][1] - C*(r[j][1] - y)/L; // atualiza velocidade c pote-
} // ncial de mola na componente y
//**********Separacao Entre Particulas**********//
for(l=0;l<N;l++){ //laço para particulas
if(l==j){ // se a particula for ela mesma nao faz nada
}else{ // se nao é ela entao
if(norm(r[j][0]-r[l][0],r[j][1]-r[l][1])<rmin){ // se as particulas estao a uma distancia menor que "rmin"
v[j][0] = v[j][0] + S*(r[j][0] - r[l][0])/pow(norm(r[l][0]-r[j][0],r[l][1]-r[j][1]),2)/L; // Atualiza velocidade c potencial analogo ao gravitacional
// na componente x
v[j][1] = v[j][1] + S*(r[j][1] - r[l][1])/pow(norm(r[l][0]-r[j][0],r[l][1]-r[j][1]),2)/L; // Atualiza velocidade c potencial analogo ao gravitacional
// na componente y
}
}
}
//**********Velocidade Pela Densidade de Vizinhos**********//
if(cont + kont < 0.1*N){ // se o numero de vizinhos for menor que 0.1*N
vizinhos[j][0] = 1; // chave 1 fecha
vizinhos[j][1] = 0; // chave 2 abre
}else{
vizinhos[j][0] = 0; // chave 1 abre
}
if(norm(v[j][0],v[j][1]) > 0.5*ini){ // se a velocidade media do passo anterior for maior
// que 0.7*ini
vizinhos[j][1] = 0; // chave 2 "abre"
}
if(vizinhos[j][0] == 0){ // se chave 1 aberta
if(vizinhos[j][1] == 1){ // se chave 2 fechada entao nao faz nada
}else if(cont +kont >0.5*N){ // se vizinhos > 0.5*N entao
v[j][0] = 0.85*v[j][0]; // velocidade reduz 20%
v[j][1] = 0.85*v[j][1]; // velocidade reduz 20%
}else if(cont + kont > 0.4*N){ // se vizinhos 0.5> e >0.4 entao
v[j][0] = 0.9*v[j][0]; // velocidade reduz 15%
v[j][1] = 0.9*v[j][1]; // velocidade reduz 15%
}else if(cont + kont > 0.3*N){ // se vizinhos 0.4> e >0.3 entao
v[j][0] = 0.93*v[j][0]; // velocidade reduz 10%
v[j][1] = 0.93*v[j][1]; // velocidade reduz 10%
}else if(cont + kont > 0.2*N){ // se vizinhos 0.3> e >0.2 entao
v[j][0] = 0.97*v[j][0]; // velocidade reduz 5%
v[j][1] = 0.97*v[j][1]; // velocidade reduz 5%
}
vizinhos[j][1] = 1; // chave 2 fecha
}
//**********Ruido**********//
if(rand()%2 == 0){ // criterio para decidir a fase
randomi = - rand()/RAND_MAX; // fase
}else{
randomi = rand()/RAND_MAX; // fase
}
v[j][0] = cos(PI*randomi)*v[j][0] - sin(PI*randomi)*v[j][1]; // rotaçao
v[j][1] = sin(PI*randomi)*v[j][0] + cos(PI*randomi)*v[j][1]; // rotaçao
//**********Passo das particulas com CC periodica**********//
if(L-r[j][0] < epsilon){ // final do dominio na componente x
r[j][0] = L - r[j][0]; // recomeça no inicio do dominio em x
}else if(r[j][0] < 0){ // inicio do dominio na coomponente x
r[j][0] = L + r[j][0]; // recomeça no finaldo dominio em x
}
r[j][0] = r[j][0] + v[j][0]*dt; // atualiza a posiçao da particula em x
if(L-r[j][1] < epsilon){ // final do dominio em y
r[j][1] = L - r[j][1]; // recomeça no inicio do dominio em y
}else if(r[j][1] < 0){ // inicio do dominio em y
r[j][1] = L + r[j][1]; // recomeça no final do dominio em y
}
r[j][1] = r[j][1] + v[j][1]*dt; // atualiza a posiçao da particula em y
if(t%I == 0){
printf("%lf %lf \n", r[j][0], r[j][1]); // imprime a posiçao da particula
}
vmed = vmed + norm(v[j][0],v[j][1]); // contador para velocidade media
}
if(t%I == 0){
printf("e\n"); // final do grafico para |gnuplot
}
vmedl = vmed/N; // velocidade media no tempo t
//printf("%lf %lf\n", t*dt, vmed);
t++; // contador para o tempo (numero de passos)
}while(t<T);
printf("\n\n");
}