Vagar (Wander)

Técnica de algoritmo que faz o agente vagar pelo ambiente virtual sem um destino definido. Esse comportamento pertence ao steering behaviors.

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 que é o comportamento wander (vagar)?

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.

wander steering behaviors

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.

Implementando os requisitos básicos

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):

  • Posição
  • Velocidade
  • Ângulo “vagar”

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:

  • Velocidade máxima
  • Força máxima
  • Raio do agente (Triângulo)
  • Distância até o centro da esfera
  • Raio da esfera

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);
	}
}

Como implementar o comportamento wander

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:

  • Esfera
  • Centro da esfera
  • Distância do agente até a esfera

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.
wander steering behaviors test

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.

Conclusão

“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

Desenvolvendo um jogo de quebra blocos em javascript

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

Integrando o PHP com Elasticsearch no desenvolvimento de um sistema de busca

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.

Criando um sistema de integração contínua (CI/CD)

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.

Caixa eletrônico usando arquitetura limpa

Usando JavaFX e arquitetura limpa para criar um aplicativo de caixa eletrônico extremamente simples.

Usando dados fornecidos pelo TSE para simular o gráfico das eleições presidenciais de 2022

Simulação dos gráficos do segundo turno das eleições presidenciais, utilizando python e ferramentas de análise de dados, pandas e jupyter.

Veja também

Os computadores usam a numeração binária para a manipulação de dados em circuitos elétricos

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.

Pessoas sem um endereço não podem utilizar os correios. Dispositivos sem um endereço não podem acessar a internet.

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

Blockchain Parte2

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.

Seguir caminho (path following)

Um dos comportamentos de navegação (steering behaviors). Faz com que um agente siga um caminho pré-determinado pelo desenvolvedor.

Algoritmo

O algoritmo é um conjunto de instruções escritas por um programador com intuito de solucionar um problema ou obter um resultado previsto.

Algoritmo A* (A-estrela)

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.