Grupo - BOIDS: mudanças entre as edições
Linha 37: | Linha 37: | ||
[[Arquivo:Separacao.gif |none|500px| Simulação apenas da regra de separação entre BOIDS. ]] | [[Arquivo:Separacao.gif |none|500px| Simulação apenas da regra de separação entre BOIDS. ]] | ||
Figura 1: Simulação apenas da regra de separação entre BOIDS. | Figura 1: Simulação apenas da regra de separação entre BOIDS. | ||
[[Arquivo:Coesao.gif|none|500px|Simulação apenas da regra de separação entre BOIDS.]] | [[Arquivo:Coesao edit.gif|none|500px|Simulação apenas da regra de separação entre BOIDS.]] | ||
Figura 2: Simulação apenas da regra de separação entre BOIDS. | Figura 2: Simulação apenas da regra de separação entre BOIDS. | ||
Edição das 20h07min de 21 de janeiro de 2018
Contexto Histórico
Desenvolvido por Craig Reynolds em 1986, é um algoritmo que busca, por meio de regras de comportamento, reproduzir o comportamento sincronizado de grupos de animais. Por exemplo manadas de animais terrestres, cardumes de peixes, bando de pássaros e etc. O nome BOID corresponde ao encurtamento da expressão em inglês “bird-oid object”, que se refere a um objeto “tipo pássaro”. Seu trabalho foi publicado em 87 sob o título original, em inglês, "Flocks, herds and schools: A distributed behavioral model". O modelo base de Craig já fora utilizado para diversas implementações e estudos. Como estudo comportamental de medo, interação entre animais via olfato modelando feromônios, mudança de liderança de um bando, dentre muitas outras aplicações interessantes.
Motivação
O movimento de animais em sincronia é extremamente complexo e é chave para sua sobrevivência em bando. Peixes, pássaros e mamíferos terrestres tem esse tipo de comportamento principalmente no que diz respeito a defesa em momentos em que sentem em perigo. A concentração intimida e o movimento confunde seus predadores. Além de ser extremamente prazeroso assistir um bando de pássaros ou um cardume de peixes em sua dança sincronizada.
Este trabalho busca, em suas etapas, reproduzir um cardume de peixes em seu padrão síncrono de movimento e, posteriormente, na presença de um ou mais predadores.
O Algoritmo
Inicialmente são sorteadas posições e velocidades aleatórias para os objetos. As regras são então calculadas a cada de passo temporal. Embora cada boid tenha liberdade sobre todo o espaço descrito, o seu comportamento é influenciado apenas por outros dentro de uma região circular centrada no objeto dita raio de interação (R). Após o cálculo das novas posições e velocidades é somado um incremento de tempo e o algoritmo recomeça.
Separação
Interação de repulsão entre os indivíduos para evitar superconcentração local (ou no caso extremo uma superposição). Um potencial análogo à Lei de Coulomb para cargas de mesmo sinal: , onde e S é um coeficiente de separação.
Alinhamento (vetor velocidade)
A velocidade média dos parceiros próximos influencia o vetor velocidade do objeto, fazendo-o ter um comportamento parecido com sua vizinhança.
Coesão
Os BOIDs interagentes tem um potencial de mola entre si, fazendo com que tenham a tendência de mover-se em direção ao centro de massa do grupo. Calculando primeiramente o centro de massa (CM) das partículas vizinhas utiliza-se da força elástica para simular uma mola entre o objeto e o CM da vizinhança.
, N sendo o número de partículas dentro do raio de interação.
, C é o coeficiente elástico.
Resultados e Conclusões
Figura 1: Simulação apenas da regra de separação entre BOIDS.
Figura 2: Simulação apenas da regra de separação entre BOIDS.
Desenvolvimento em C
Abaixo verá trechos do código em linguagem de programação C para as regras e etapas em questão.
Link para o código completo aqui.
Coesão
//**********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 potencial de mola na componente x
v[j][1] = v[j][1] - C*(r[j][1] - y)/L; // atualiza velocidade c potencial de mola na componente y
}
Separação
//**********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); // Atualiza velocidade c potencial analogo a lei de Coulomb 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); // Atualiza velocidade c potencial analogo a lei de Coulomb na componente y
}
}
}
Alinhamento (vetor Velocidade)
//**********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(vmedl > .7*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.8*v[j][0]; // velocidade reduz 20%
v[j][1] = 0.8*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.85*v[j][0]; // velocidade reduz 15%
v[j][1] = 0.85*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.9*v[j][0]; // velocidade reduz 10%
v[j][1] = 0.9*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.95*v[j][0]; // velocidade reduz 5%
v[j][1] = 0.95*v[j][1]; // velocidade reduz 5%
}
vizinhos[j][1] = 1; // chave 2 fecha
}
Ruído
Para reproduzir melhor um ser vivo, um pequeno ruído compõe a velocidade. Isso faz com que tenhamos uma maior flutuação no caminho que os boids traçam.
//**********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(randomi)*v[j][0] + sin(randomi)*v[j][1]; // rotaçao
v[j][1] = - sin(randomi)*v[j][0] + cos(randomi)*v[j][1]; // rotaçao
Predador
//Barreira puntual no centro
if(norm(r[j][0] -bx, r[j][1] - by) < ERRE){ // se a particula ta a menos
// de "ERRE" entao
if(r[j][0] < bx && r[j][1] < by){ // se estiver atras e abaixo
v[j][0] = v[j][0] - B*norm(r[j][0] - bx, r[j][0] - bx)/pow(norm(r[j][0] - bx, r[j][1]- by),1.5); // atualiza velocidade com potencial analogo "gravitac"
v[j][1] = v[j][1] - B*norm(r[j][1] - by, r[j][1] - by)/pow(norm(r[j][0] - bx, r[j][1]- by),1.5); // atualiza velocidade com potencial analogo "gravitac"
}else if(r[j][0] > bx && r[j][1] < by){ // se estiver a frente e abaixo
v[j][0] = v[j][0] + B*norm(r[j][0] - bx, r[j][0] - bx)/pow(norm(r[j][0] - bx, r[j][1]- by),1.5); // atualiza velocidade com potencial analogo "gravitac"
v[j][1] = v[j][1] - B*norm(r[j][1] - by, r[j][1] - by)/pow(norm(r[j][0] - bx, r[j][1]- by),1.5); // atualiza velocidade com potencial analogo "gravitac"
}else if(r[j][0] < bx && r[j][1] > by){ // se estiver abaixo e acima
v[j][0] = v[j][0] - B*norm(r[j][0] - bx, r[j][0] - bx)/pow(norm(r[j][0] - bx, r[j][1]- by),1.5);// atualiza velocidade com potencial analogo "gravitac"
v[j][1] = v[j][1] + B*norm(r[j][1] - by, r[j][1] - by)/pow(norm(r[j][0] - bx, r[j][1]- by),1.5);// atualiza velocidade com potencial analogo "gravitac"
}else if(r[j][0] > bx && r[j][1] > by){// se estiver a frente e acima
v[j][0] = v[j][0] + B*norm(r[j][0] - bx, r[j][0] - bx)/pow(norm(r[j][0] - bx, r[j][1]- by),1.5); // atualiza velocidade com potencial analogo "gravitac"
v[j][1] = v[j][1] + B*norm(r[j][1] - by, r[j][1] - by)/pow(norm(r[j][0] - bx, r[j][1]- by),1.5); // atualiza velocidade com potencial analogo "gravitac"
}
}
Referências
- https://en.wikipedia.org/wiki/Boids
- Reynolds, C. W. (1987) Flocks, Herds, and Schools: A Distributed Behavioral Model, in Computer Graphics, 21(4) (SIGGRAPH '87 Conference Proceedings) pages 25-34.