Esse site utiliza cookies
Nós armazenamos dados temporariamente para melhorar a sua experiência de navegação e recomendar conteúdo do seu interesse.
Ao utilizar os nossos serviços, você concorda com as nossas políticas de privacidade.
Esse site utiliza cookies
Nós armazenamos dados temporariamente para melhorar a sua experiência de navegação e recomendar conteúdo do seu interesse.
Ao utilizar os nossos serviços, você concorda com as nossas políticas de privacidade.
Categoria de Programação
Postado em 19 maio 2023
Atualizado em 19 maio 2023
Palavras-chave: steering,behaviors,comportamentos,navegacao,navegação,algoritmo,ambiente,virtual,seek,buscar,fugir,flee
Visualizações: 787
Steering behaviors (comportamentos de navegação) são um conjunto de técnicas que simulam o comportamento de animais, como a revoada de pássaros. Foi introduzido pela primeira vez em 1987, por Craig Reynolds na obra “Stanley and Stella in Breaking the Ice” (Stanley e Stella em quebrando o gelo). Desde então, esse algoritmo começou a ser utilizado em vários ocasiões, como filmes, jogos e materiais de ornitologia.
Apesar da simplicidade de implementação, steering behaviors traz resultados ótimos. Isso faz com que muitos desenvolvedores optem por sua adoção. As seguintes postagens de steering behaviors já foram adicionadas:
Como continuação das postagens acima, nessa postagem será discutido o comportamento wander (vagar). Esse comportamento simula um objeto que vaga aletoriamente e sem rumo pelo mapa, podendo ser útil para aplicação de comportamentos de deslocamento de NPCs em jogos de RPG.
O comportamento “wander” é um algoritmo de simulação de movimento aleatório. O agente vaga aleatoriamente pelo ambiente virtual, sem nenhum destino.
Craig Reynolds explica em seu site que uma simples implementação que gera uma força de navegação por cada frame pode ser simples, porém esse tipo de implementação realiza movimentos não muito satisfatórios. O agente se torna inquieto, alternando a sua direção rapidamente em múltiplas direções, resultando em uma moção nada natural. Invés disso, uma boa forma de lidar com esse problema é manter a direção de navegação e mudando em pequenas proporções em cada frame. Assim, o agente não mudará repentinamente a sua direção.
Um método bastante eficiente é colocar uma esfera um pouco a frente do agente. O comportamento “vagar” terá uma força que irá ser restringida pelos limites dessa esfera.
O valor de variação de direção não será descartado a cada frame. Esse valor será acumulado e ajustado com um limite pela superfície da esfera. O raio da esfera determina a força máxima do comportamento “vagar” e a distância entre o ponto de variação e o agente determina o grau de variação da direção.
Apesar de ser um comportamento aleatório, “vagar” é um comportamento controlado. Esse método pode ser útil em jogos, evitando movimentos lineares e previsíveis de atores, tornando o jogo mais emocionante.
O ponto vermelho na imagem acima é o resultado do ângulo de variação. O ângulo é definido por um valor aleatório dentro de uma esfera de valor limitado para que não haja variações muito radicais de valor, mantendo a suavidade no movimento do agente.
Antes de iniciar a implementação do algoritmo de comportamento “vagar”, o ambiente virtual deve estar preestabelecido.
A classe “Vehicle” é o agente que irá vagar pelo plano virtual. O agente irá possuir os seguintes atributos (variáveis locais):
Os atributos irão mudar constantemente durante a execução do algoritmo.
Seguindo adiante, constantes irão ser definidas no escopo global do código e nunca irão mudar durante a execução do algoritmo. São constantes globais:
Os valores das variáveis acima podem ter o seu valor influenciado pelo ambiente virtual (contexto do software). Esses valores devem ser ajustados para que o comportamento “wander” possa ser executado com efetividade.
const MAX_FORCE = 0.2 // Força máxima
const MAX_SPEED = 2 // Velocidade máxima
const CIRCLE_DISTANCE = 50 // Distância até esfera
const AGENT_R = 7 // Raio do triângulo
const OUT_CIRCLE_R = 25 // Raio da esfera
Dentro da classe veículo, definimos o construtor e os atributos. Exceto o ângulo, todos os atributos serão vetores.
class Vehicle {
constructor(x, y) {
this.pos = createVector(x, y) // Posição
this.velocity = createVector(2, 0) // Velocidade atual
this.wanderAngle = 0 // Ângulo vagar
}
}
Em seguida, definimos a função “draw” que irá exibir o agente na tela:
class Vehicle {
...
draw() {
// Desenha um triângulo com tamanho 10
let triangle = triangle(this.pos.x, this.pos.y, AGENT_R * 2)
// Aponta a cabeça do triângulo para frente
triangle.rotate(this.velocity.heading);
}
}
Uma vez que os requisitos básicos foram definidos, implementamos o comportamento “wander”.
class Vehicle {
...
wander() {
// TODO
}
}
Para facilitar a implementação e a testagem, exibimos na tela os seguintes elementos:
Os três elementos acima serão exibidos usando a função wander.
wander() {
// Copia o vetor da velocidade
let spherePos = this.velocity.clone()
// Normaliza, multiplica pela distância até o circulo e soma com a posição atual
spherePos.normalize().mult(CIRCLE_DISTANCE).add(this.pos)
// Exibi a esfera
circle(spherePos.x, spherePos.y, OUT_CIRCLE_R * 2)
// Exibi o centro da esfera
circle(spherePos.x, spherePos.y, 5)
// Exibi a distância até o centro da esfera
line(this.pos.x, this.pos.y, spherePos.x, spherePos.y)
}
Finalmente instanciamos o agente para vermos o resultado.
var vehicle;
start() {
// Instancia o agente
vehicle = new Vehicle(width / 2, height / 2)
}
update() {
// Exibi o agente
vehicle.draw()
// Exibi os elementos para testar o comportamento vago
vehicle.wander()
}
O resultado será o agente apontando para a esfera.
A posição da esfera e dos outros elementos de exibição estão funcionando perfeitamente. Uma vez que podemos ver a esfera de ajuste de direcionamento, podemos começar a implementar o código principal.
Dentro da função “wander”, calculamos a variação de direção usando o ângulo do agente. Em seguida, partindo do centro da esfera, calculamos a força de direção e subtraímos esse valor pela posição atual.
wander() {
// Copia o vetor da velocidade
let spherePos = this.velocity.clone()
// Normaliza, multiplica pela distância até o circulo e soma com a posição atual
spherePos.normalize().mult(CIRCLE_DISTANCE).add(this.pos)
// Cálculo de variação de direcionamento
let displacement = new Vector(0, 0)
// Calcula a força de direção com coordenadas polares
displacement.x = OUT_CIRCLE_R * cos(this.angle)
displacement.y = OUT_CIRCLE_R * sin(this.angle)
// Calcula a direção de deslocamento
let direction = spherePos + displacement
// Calcula comportamento de vagar
let vagar = this.pos - direction
vagar.limit(MAX_FORCE)
...
return vagar
}
O valor da variável “vagar” é retornado pela função “wander”. Usaremos esse valor dentro da função “move”.
class Vehicle {
...
move () {
let vagar = this.wander()
// Adiciona o valor de wander na velocidade
this.velocity.add(vagar)
this.velocity.limit(MAX_SPEED)
// Muda a posição
this.pos.add(this.velocity)
// No final, adiciona uma pequena variação aleatória ao ângulo
this.angle += random(-0.5, 0.5)
}
}
Finalmente, chamamos a função “move” para o agente começar a se locomover.
update() {
// Exibi o agente
vehicle.draw()
// Move o agente
vehicle.move()
}
Para complementar, exibimos o ponto de variação e a distância até esse ponto.
wander() {
...
// Exibi a variação da direção pelo ângulo
circle(displacement.x, displacement.y, 7)
line(this.pos.x, this.pos.y, direction.x, direction.y)
...
return vagar
}
O algoritmo deve mostrar o vetor que muda aleatoriamente cada frame. Apesar de haver múltiplas atualizações por segundo, o agente ainda tem uma movimentação suave e satisfatória.
“Wander” é um algoritmo de comportamento que simula um agente vagando pelo ambiente virtual. Esse comportamento pertence ao Steering Behaviors, sendo apenas um dos diversos comportamentos diponíveis. Sua implementação é simples e traz resultados eficientes. Pode ser implementado em jogos, robôs e em softwares educativos.
Projetos práticos
Programando um jogo clássico de arcade usando javascript e p5.js. O usuário deve quebrar os blocos utilizando uma bola ao mesmo tempo que evita que a bola saia pela parte inferior da tela
Projeto de criação de um sistema de busca usando o framework Symfony e Elasticsearch. A integração com Kibana também é feito de modo remoto com um raspberrypi.
Fazendo a integração contínua de Jenkins, Sonatype Nexus, Sonatype, JUnit e Gradle para automatizar processos repetitivos. Prática bastante usada em tecnologias de DevOps.
Usando JavaFX e arquitetura limpa para criar um aplicativo de caixa eletrônico extremamente simples.
Simulação dos gráficos do segundo turno das eleições presidenciais, utilizando python e ferramentas de análise de dados, pandas e jupyter.
A ausência e a presença de energia são dois estados que podem ser usados como valores. Esses valores são respectivamente zero e um.
Quando nos conectamos à internet, nós recebemos um endereço IP. O endereço IP é o nosso endereço virtual que vai servir como localização para a transferência de dados na internet
PoW atua como um intermediário não-humano entre os negociadores de criptomoedas. Em média, uma transação em bitcoin dura 10 minutos.
Um dos comportamentos de navegação (steering behaviors). Faz com que um agente siga um caminho pré-determinado pelo desenvolvedor.
O algoritmo é um conjunto de instruções escritas por um programador com intuito de solucionar um problema ou obter um resultado previsto.
Algoritmo que busca o caminho com o menor custo entre dois pontos. É usado em jogos e aplicativos de navegação para calcular a menor distância possível.