EP2
EP02 – Animando um cardume em 2D
Informações gerais
- Entrega: até 23:59 h de sábado, 20 de maio de 2023.
- Esse é um projeto individual. Leia com atenção as informações gerais na página da disciplina.
- Não deixe para a última hora.
- Em caso de atraso: trabalhos atrasados receberão 20% de desconto para cada 24 h de atraso.
Objetivos
Treinar o uso de WebGL criando uma animação em 2D para simular o comportamento de movimento coletivo de múltiplos objetos.
Introdução
Muitos videogames e sistemas de simulação física envolvem planejar e
coordenar o movimento de um grupo de objetos, como pássaros em um bando,
um cardume de peixes ou um enxame de abelhas. Nesse exercício você vai
implementar um programa simples bidimensional que modele o comportamento
de um grupo de objetos em movimento no plano, que vamos chamar de
boids
. Nesse exercício, para facilitar o entendimento,
podemos assumir que os boids
são peixes que buscam nadar em
cardume, mas podem ser pássaros, morcegos, abelhas, búfalos etc.
Um cardume é um tipo de movimento coletivo
(flocking
motion) que deve satisfazer:
Separação: Os boids devem tentar manter uma certa distância mínima de separação entre si e com quaisquer obstáculos que possam estar presentes. A figura abaixo ilustra esse comportamento. Considerando uma região ao redor do peixe, esse peixe deve alterar sua velocidade para que mantenha uma distância entre ele e seus vizinhos. Essa nova velocidade é função da velocidade atual e as distâncias entre o peixe e seus vizinhos.
Alinhamento: Boids tendem a se mover aproximadamente na mesma velocidade e aproximadamente na direção dos boids mais próximos. A figura abaixo ilustra esse comportamento. Considerando uma região ao redor do peixe, calcule a velocidade média entre todos os peixes nessa vizinhança. O peixe deve alterar sua velocidade para que sua nova velocidade se aproxima da velocidade médias dos demais.
Coesão: Idealmente, os boids devem permanecer juntos como um grupo. A figura abaixo ilustra esse comportamento. Considerando uma região ao redor do peixe, ele deve procurar se aproximar do baricentro da posições dos outros peixes que estiverem dentro da região. Seu programa deve calcular uma alteração na velocidade de cada peixe para que isso aconteça.
Na presença de um obstáculo, os boids podem se separar para evitar o obstáculo. Idealmente, eles devem se reagrupar, uma vez que tenham contornado o obstáculo, supondo que o obstáculo não seja muito grande.
Essas propriedades definem a natureza do movimento localmente, mas não restringem o movimento global do grupo. Nesse exercício, o programa deve começar com um peixe líder, que tem comportamento semi-autônomo, como descrito mais abaixo. O maior desafio desse EP é escolher os pesos adequados para que os peixes apresentem um comportamento coletivo de cardume.
O que o seu programa deve fazer
Nesse EP, você deve escrever um programa para simular o movimento de um grupo de boids bidimensionais, sujeito aos requisitos gerais acima. O crédito básico será baseado no conjunto de recursos que você implementar com sucesso. Créditos extras poderão ser atribuídos pelo avaliador de acordo com o interesse e complexidade das partes extras implementadas.
Seu programa deve implementar os seguintes elementos básicos:
[25 pontos] Comportamento individual do peixe líder: Seu programa deve começar com apenas um peixe chamado de líder, que deve ter uma cor diferente dos outros peixes. Quando criado sua velocidade é (0.5, 0.5), mas você pode controlar sua velocidade e ângulo por meio das teclas (setas) UP, DOWN, RIGHT e LEFT. Nesse exercício, o movimento do líder (e de todos os demais boids) é refletido quando batem na parede do canvas. Assim, nenhum peixe nada para fora do canvas.
- Para desenhar um peixe, escolha alguma forma que permita visualizar a direção do movimento (por exemplo um triângulo com uma ponta na direção do movimento).
[10 pontos] Adicionar outros boids: O número de boids pode ser ajustado durante a execução do programa. Quando a tecla
+
for pressionada, seu programa deve cria um novo boid em um local aleatório no canvas, com velocidade também arbitrária. Ao pressionar a tecla-
, um boid qualquer deve ser removido. Apenas o peixe líder nunca pode ser removido (e portanto pode ficar nadando sozinho).- [10 pontos] para facilitar a depuração de seu programa, ao pressionar a tecla ‘P’ (ou ‘p’) a simulação deve ser pausada ou retomada. A tecla ‘S’ (ou ‘s’) deve permitir avançar um passo na simulação (que pode ser de 50 milisegundos). As teclas “+” e “-” devem continuar funcionando mesmo quando o simulador estiver pausado.
[20 pontos] Comportamento coletivo: Na presença de outros boids, o movimento exibido por um bando deve satisfazer os três elementos: separação, coesão e alinhamento, descritos acima. Observe que sem esse “comportamento”, o comportamento de cada peixe é definido apenas pela sua velocidade no instante em que foi criado.
[25 pontos] Obstáculos: Alguns obstáculos circulares desconexos podem estar presentes na cena. Você pode sortear ou definir os obstáculos de alguma forma conveniente, por exemplo, por exemplo limitando os raios e coordenadas, ou ainda definindo explicitamente as posições e outros parâmetros em um arquivo
configuracao.js
. Boids devem evitar obstáculos. Se o bando for dividido nadando em torno de um pequeno obstáculo, ele deve se reagrupar de forma natural.[10 pontos] Documentação: veja na seção “o que você deve entregar”.
Sugestões
para obter créditos extras na nota desse EP
Movimento da nadadeira: desenhe seus peixes para
que pareçam mais como peixes nadando (ou pássaros voando, ou animais
andando, ou o que você quiser!). Idealmente o movimento deve ser
realista. Por exemplo, nem todas as aves batem as asas exatamente ao
mesmo tempo.
Múltiplos Cardumes: Tenha vários cardumes ou
bandos, que devem evitar um ao outro. Você pode atribuir peixes a
cardumes aleatoriamente.
Obstáculos complexos: Permita obstáculos mais
complexos (não circulares), ou obstáculos circulares sobrepostos, ou
obstáculos móveis que se desloquem no espaço ou que alterem seu tamanho
ou forma dinamicamente.
Predador: Tenha um peixe predador que voe
aleatoriamente (ou sob o controle do mouse). Os outros peixes devem
evitar o predador a todo custo, mesmo que isso signifique violar as
regras de agrupamento. Uma vez que o predador esteja a uma certa
distância segura, os peixes devem retomar seu comportamento
coletivo.
Dicas para escrever o seu
programa
Movimento da nadadeira: desenhe seus peixes para que pareçam mais como peixes nadando (ou pássaros voando, ou animais andando, ou o que você quiser!). Idealmente o movimento deve ser realista. Por exemplo, nem todas as aves batem as asas exatamente ao mesmo tempo.
Múltiplos Cardumes: Tenha vários cardumes ou bandos, que devem evitar um ao outro. Você pode atribuir peixes a cardumes aleatoriamente.
Obstáculos complexos: Permita obstáculos mais complexos (não circulares), ou obstáculos circulares sobrepostos, ou obstáculos móveis que se desloquem no espaço ou que alterem seu tamanho ou forma dinamicamente.
Predador: Tenha um peixe predador que voe aleatoriamente (ou sob o controle do mouse). Os outros peixes devem evitar o predador a todo custo, mesmo que isso signifique violar as regras de agrupamento. Uma vez que o predador esteja a uma certa distância segura, os peixes devem retomar seu comportamento coletivo.
Consideremos o caso mais simples em que não há obstáculos. Cada peixe é especificado por seu ponto de localização atual P, e pelo vetor velocidade v. Uma outra representação possível é por meio de seu ângulo direcional θ e sua velocidade escalar s (magnitude da velocidade na direção theta). O ângulo θ pode ser útil para orientar o desenho do peixe. É possível converter uma representação para outra usando as seguintes fórmulas:
s = |v| e θ = atan2(vy,vx)
e a inversa
v = [s ⋅ cos(θ), s ⋅ sin(θ)]
A melhor maneira de calcular a tangente do arco é usar a função
nativa Math.atan2(vy, vx)
, que retorna um ângulo no
intervalo [ − π, + π]. Você pode escolher a forma
que achar mais conveniente (ou melhor para o seu programa) para
representar a velocidade, ou seja, usando s e θ ou o vetor v. Mas qualquer que seja a sua
escolha, é provável que você precise converter para o outro modo.
Para fazer a animação, sugerimos usar o relógio da máquina na atualização de todos os peixes. A atualização utiliza o intervalo de tempo transcorrido desde a última atualização e a velocidade (com unidade pixels por segundo ou algo assim) para calcular a nova posição de cada peixe.
Mas lembre-se que antes de calcular a posição, é necessário também atualizar o vetor velocidade que define o comportamento do peixe. Observe que o peixe pode precisar acelerar, ou brecar, ou mudar de direção. Procure ajustar a velocidade de forma incremental, que resulta em um movimento mais suave. Assim, cada etapa da animação envolve os seguintes elementos:
- Para cada peixe, determine os outros peixes e obstáculos que se aproximam, dentro de algum raio limitado (imagine algo como o campo de percepção do peixe), talvez, dando maior prioridade às coisas que estão na frente.
- Atualize o vetor velocidade para cada peixe a fim de satisfazer as várias restrições do movimento coletivo e evitar obstáculo/predador.
- Mova cada peixe com a orientação apropriada (na direção do movimento).
- Redesenhe a cena.
Talvez o passo mais desafiador seja a definição do comportamento coletivo (passo 2) que afeta a velocidade dos peixes. Cada uma das várias propriedades do movimento coletivo pode aplicar um certo “puxão” (força) no vetor de velocidade. Por exemplo:
- Conhecendo os peixes vizinhos e obstáculos à frente, o peixe não deve se chocar com eles. Imagine que cada vizinho e obstáculo cria uma “força de repulsão” que afeta a velocidade do peixe. No caso de obstáculos, o peixe deve ser girado na direção que mais facilmente evita o obstáculo. Esta curva tem o efeito de influenciar o vetor de velocidade atual. Observe que o peixe só precisa desviar se for se chocar no obstáculo.
- Para se manterem “juntos”, imagine outra “força” que atraia o peixe para o centro de massa dos peixes vizinhos.
- Para que todos nadem juntos com a mesma velocidade, imagine outra “força” que muda a velocidade do peixe para uma velocidade mais perto da média do grupo.
- A nova velocidade é resultante de uma média ponderada das forças que você calculou.
- Observe que o peixe líder não deve ser afetado por todas essas forças.
Em resumo, há uma série de “correções” que devem ser feitas sobre a velocidade atual. Para determinar a velocidade atualizada, atribua pesos a essas correções e, em seguida, adicione a soma ponderada ao vetor de velocidade atual. Essa atribuição de pesos é uma tarefa não trivial e cada distribuição distinta de pesos corresponde a comportamentos distintos do cardume. Teste algumas para ver como fica o comportamento global. Algumas forças (por exemplo, o desejo de evitar obstáculos ou predadores) podem ser muito mais fortes do que outras (por exemplo, o desejo de manter a coesão). Provavelmente é uma boa ideia colocar algum limite superior em quanto a velocidade pode mudar, para evitar mudanças de velocidade excessivamente rápidas.
Mais informações sobre Boids e comportamento de movimento coletivo podem ser encontradas na web como:
Esse material pode ser útil para obter ideias, mas você deve fazer sua própria implementação para esta tarefa de programação.
O que você deve entregar
Um arquivo zip contendo todos os arquivos necessários para executar seu programa, incluindo:
ep02.js
: deve conter um cabeçalho como:/* EP02 de MAC0420/MAC5744 - Simulação de movimento coletivo Nome: NUSP: */
ep02.html
ep02.css
leiame.txt
: breve descrição do seu projeto e desenvolvimento com- Introdução: Um parágrafo descrevendo a simulação (projeto)
- Horas de trabalho: horas dedicadas (aproximadamente)
- por semana
- total
- Dificuldades: uma seção (alguns parágrafos) descrevendo as dificuldades encontradas ao longo do exercício.
- Bugs: descreva o que não foi concluído e bugs conhecidos.
- Opcionais: descreva coisas a mais que você fez para deixar a simulação mais “interessante” e/ou complexa (realista, eficaz,etc.), para que possa também receber algum crédito extra.
Para receber a nota de documentação, procure comentar todas as suas funções, além de incluir o arquivo
leiame.txt
.Caso deseje, crie classes para os objetos que precisar desenhar, como obstáculos e peixes. Caso você decida por colocar suas classes em arquivos separados, não se esqueça de incluir esses arquivos também. Submissões incompletas poderão receber nota zero.
Dicas
Não deixe para a última hora
Implemente e teste uma parte do sistema de cada vez. Sugestão de passos:
- comece com a implementação do peixe líder
- sua animação autônoma, refletindo nas paredes do canvas, com a orientação adequada, na direção do movimento.
- a interface de controle
- demais peixes
- comportamento coletivo
- obstáculos
- documentação