Navegação florestal
O * Path Finder Algorithm é uma ferramenta poderosa para gerar rapidamente os melhores caminhos. Normalmente, A * é mostrado ao navegar mapas de grades, mas pode ser usado não apenas para grades! Pode funcionar com qualquer gráfico. Você pode usar A * para encontrar o seu caminho no mundo dos obstáculos redondos.
No artigo original, todas as imagens são interativas.Como um algoritmo resolve esses dois problemas? Vamos começar com uma breve descrição de como o A * funciona.
Algoritmo A *
O algoritmo A * encontra o
caminho ideal do ponto inicial ao final, evitando obstáculos ao longo do caminho. Ele percebe isso, expandindo gradualmente muitos
caminhos parciais . Cada caminho parcial é uma série de etapas desde o ponto de partida até um ponto intermediário no caminho para a meta. No processo de trabalhar com A *, os caminhos parciais estão se aproximando do ponto final. O algoritmo para de funcionar quando encontra o caminho completo, melhor do que as opções restantes, e isso pode ser provado.
Em cada etapa do algoritmo, A * avalia o conjunto de caminhos parciais e gera novos caminhos, expandindo o caminho mais promissor fora do conjunto. Para fazer isso, A * armazena caminhos parciais em uma fila prioritária, classificados pelo
comprimento aproximado - o
comprimento real do caminho medido mais a distância restante aproximada do destino. Essa aproximação deve ser
subestimada ; isto é, a aproximação pode ser menor que a distância real, mas não maior que ela. Na maioria das tarefas de localização de caminhos, uma boa estimativa discreta é a distância geométrica em uma linha reta desde o final do caminho parcial até o ponto final. O melhor caminho verdadeiro para a meta a partir do final do caminho parcial pode ser maior que essa distância em linha reta, mas não pode ser menor.
Quando A * é iniciado, a fila de prioridade contém apenas um caminho parcial: o ponto de partida. O algoritmo remove repetidamente o caminho mais promissor da fila de prioridade, ou seja, o caminho com o menor tamanho aproximado. Se esse caminho terminar no ponto final, o algoritmo concluiu a tarefa - a fila de prioridade garante que nenhum outro caminho possa ser melhor. Caso contrário, a partir do final do caminho parcial que ele removeu da fila, A * gera vários outros caminhos novos, executando etapas da unidade em todas as direções possíveis. Ele coloca esses novos caminhos de volta na fila de prioridade e inicia o processo novamente.
Contagem
A * trabalha com um
gráfico : um conjunto de
nós conectados por
arestas . Em um mundo baseado em grade, cada nó denota uma célula de malha separada e cada borda é uma conexão com células vizinhas ao norte, sul, leste ou oeste.
Antes de executar A * para a floresta a partir de obstáculos redondos, precisamos convertê-la em um gráfico. Todos os caminhos pela floresta consistem em segmentos alternados de linhas e arcos. Eles são as arestas do gráfico de caminho. Os pontos de extremidade dessas arestas se tornam nós.
Um caminho através de um gráfico é uma série de nós conectados por arestas:
Segmentos e arcos são arestas do gráfico. Vamos chamar os segmentos de
arestas de transição , porque o caminho os usa para se mover entre obstáculos. Chamamos arcos de
bordas envolventes , porque sua tarefa ao longo do caminho é contornar os lados dos obstáculos.
A seguir, exploraremos uma maneira simples de transformar uma floresta com obstáculos em um gráfico: geraremos todas as bordas e envelopes de transição possíveis.
Geração de borda de transição
As arestas da transição entre um par de círculos são segmentos de linha que mal tocam nos dois círculos; esses segmentos são chamados
tangentes a dois pontos e, para cada par de círculos, existem quatro desses tangentes. As tangentes a dois pontos que se cruzam entre os círculos são chamadas
tangentes internas a dois pontos , e as que passam para fora são chamadas
externas .
Tangentes internas em dois pontos
No passado, a busca de tangentes internas era importante para o cálculo do comprimento da correia que conecta duas polias de tamanhos diferentes, de modo que a tarefa de criar tangentes internas em dois pontos é chamada de
problema das correias . Para encontrar as tangentes internas em dois pontos, é necessário calcular o ângulo
no desenho abaixo.
Como se viu, para círculos com centros
e
e raios
e
cujos centros estão à distância
:
Definindo
podemos encontrar facilmente os pontos
,
,
e
.
Tangentes externas a dois pontos
Ao construir tangentes externas (esta é a
tarefa das polias ), uma técnica semelhante é usada.
Para tangentes externas, podemos encontrar
da seguinte maneira:
Não importa qual dos círculos é maior, A ou B, mas como você pode ver na figura,
colocado no lado A mais próximo de B, mas no lado B mais distante de A.
Linha de visão
Em conjunto, as tangentes interna e externa a dois pontos entre os dois círculos formam as arestas da transição entre os círculos. Mas e se uma ou mais arestas de transição fecharem o terceiro círculo?
Se a aresta de transição for sobreposta por outro círculo, precisamos descartá-la. Para reconhecer esse caso, usamos um cálculo simples da
distância entre um ponto e uma linha . Se a distância da borda de transição até o centro do obstáculo for menor que o raio do obstáculo, o obstáculo se sobrepõe à borda de transição, portanto, devemos descartá-lo.
Para calcular a distância de um ponto
para um segmento de linha reta
usaremos o
seguinte método :
Primeiro, calculamos
- parte da distância ao longo do segmento
onde a perpendicular cruza o ponto
:
Então calculamos a posição
em
:
Distância
de
cortar
É a distância de
antes
:
Desde
, o círculo se sobrepõe à linha de visão de
em
, e a borda deve ser descartada. Se
então a linha de visão de
em
existe e a costela deve ser deixada.
Geração de envelopes de borda
Os nós do gráfico conectam a borda de transição à borda do envelope. Nas seções anteriores, geramos arestas de transição. Para gerar os envelopes das bordas, começamos a partir do ponto final da borda de transição, contornamos o círculo e terminamos no ponto final de outra borda de transição.
Para encontrar o conjunto de envelopes das arestas de um círculo, primeiro encontramos todas as arestas da transição que são tangentes ao círculo. Em seguida, crie os envelopes das arestas entre todos os pontos finais das arestas de transição no círculo.
Juntando tudo
Tendo gerado arestas de transição, envelopes de arestas e nós e descartado todas as arestas de transição sobrepostas, podemos criar um gráfico e começar a procurar o caminho usando o algoritmo A *.
Aprimoramentos
O procedimento de geração de gráfico que examinamos funciona bem o suficiente para explicar o algoritmo, mas pode ser aprimorado em muitos aspectos. Tais melhorias permitirão que o algoritmo gaste menos recursos de CPU e memória, além de lidar com mais situações. Vejamos algumas das situações.
Obstáculos que se preocupam
Você deve ter notado que nos exemplos mostrados acima, os obstáculos redondos não se sobrepunham e nem tocavam. Supondo que os círculos possam se tocar, isso complica a tarefa de encontrar o caminho
Tangentes de dois pontos
Lembre-se de que tangentes com dois pontos podem ser encontradas usando esta fórmula para tangentes internas:
e fórmulas para tangentes externas:
Quando dois círculos se tocam ou se cruzam, não há tangentes internas entre eles. Nesse caso
mais de um. Como o valor da arccosina está fora do domínio da definição
não definido, é importante verificar a interseção dos círculos antes de encontrar a arccosina.
Da mesma forma, se um círculo estiver completamente localizado em outro, não haverá tangentes externas entre eles. Nesse caso
fora de alcance
, isto é, não possui arccosina.
Linha de visibilidade da borda de transição
Se permitirmos a possibilidade de tocar ou atravessar obstáculos, surgem novos casos nos cálculos da linha de visão das arestas de transição.
Lembre-se do cálculo
- parte da distância ao longo da borda da transição na qual a perpendicular ao ponto toca a borda. Se não for permitido tocar nos círculos, o valor
fora de alcance
, ou seja, o círculo não pode tocar na aresta, pois para isso teria que tocar em um dos pontos finais da aresta. Isso não é possível porque os pontos finais de uma aresta já estão tangentes a outros círculos.
No entanto, se permitirmos a possibilidade de sobreposição de círculos, os valores
fora de alcance
pode sobrepor a linha de visão ao longo da borda. Isso corresponde aos casos em que o círculo está localizado além do final da aresta de transição, mas sobrepõe ou toca o ponto final. Para rastrear esses casos matematicamente,
limitaremos intervalo
:
Linha de visão do envelope
Quando obstáculos podem se tocar ou se cruzar, os envelopes das bordas podem ser bloqueados por obstáculos da mesma maneira que as bordas de transição. Considere a borda do envelope da figura abaixo. Se o envelope da nervura tocar outro obstáculo, a nervura está bloqueada e deve ser descartada.
Para determinar se o envelope da borda está bloqueado por outro obstáculo, usamos o
método a
seguir para determinar os pontos nos quais dois círculos se cruzam. Se círculos têm centros em pontos
e
e raios
e
onde
- distância entre
e
, para iniciantes, precisamos verificar vários casos. Se os círculos não se tocam (ou seja,
),
são um dentro do outro (
) ou corresponder (
e
), os círculos não podem afetar os envelopes um do outro.
Se nenhuma dessas condições for atendida, os círculos se cruzam em dois pontos; se os círculos se tocam, esses dois pontos coincidem. Considere o
eixo radical que liga os pontos de interseção; é perpendicular à linha que liga
e
em algum momento
. Podemos calcular a distância
de
antes
da seguinte maneira:
Encontrando
podemos encontrar o ângulo
:
Se
é zero, então os círculos tocam em
. Caso contrário, existem dois pontos de interseção correspondentes a positivo e negativo
.
Em seguida, determinamos se algum dos pontos de interseção está entre os pontos inicial e final do envelope da aresta. Nesse caso, o obstáculo bloqueia a borda do envelope e devemos descartá-la. Observe que não precisamos considerar o caso quando o envelope da aresta está totalmente dentro do obstáculo, porque o recorte ao longo da linha de visão das arestas de transição já descartou essa aresta.
Depois de fazer alterações no cálculo das tangentes em dois pontos e na linha de visão das arestas de transição e dos envelopes das arestas, tudo funciona corretamente.
Raio variável do ator e extensão de Minkowski
Ao calcular a navegação de um objeto redondo no mundo dos obstáculos circulares, pode-se levar em conta observações que simplificam a solução do problema. Primeiro, pode-se simplificar o trabalho observando que o movimento de um círculo de raio
r através da floresta é semelhante ao movimento de um ponto através da mesma floresta com uma única alteração: o raio de cada obstáculo aumenta em
r . Este é um caso extremamente simples de aplicação da
soma de Minkowski . Se o raio do ator for maior que zero, antes de começar, simplesmente aumentamos o tamanho dos obstáculos.
Geração de borda diferida
Em geral, um gráfico para uma floresta de
obstáculos contém
arestas de transição, mas como cada uma delas precisa ser verificada quanto à linha de visão com
obstáculos, o tempo total de geração do gráfico é
. Além disso, pares de arestas de transição podem levar à criação de arestas de envelope e cada uma delas deve ser verificada com cada obstáculo para a linha de visão. No entanto, devido à alta eficiência do algoritmo A *, ele geralmente olha apenas parte deste grande gráfico para criar o caminho ideal.
Podemos economizar tempo gerando pequenas partes do gráfico rapidamente durante a execução do algoritmo A *, em vez de fazer todo o trabalho antecipadamente. Se A * encontrar o caminho rapidamente, geraremos apenas uma pequena parte do gráfico. Fazemos isso movendo a geração de borda para a função
neighbors()
.
Existem vários casos. No início do algoritmo, precisamos de vizinhos do ponto de partida. Essas são as arestas da transição do ponto inicial às arestas esquerda e direita de cada obstáculo.
O próximo caso é quando A * chega ao ponto
à beira de um obstáculo
ao longo da borda de transição: os
neighbors()
devem retornar os envelopes das bordas que saem da
. Para fazer isso, determinamos quais arestas de transição saem do obstáculo calculando as tangentes em dois pontos entre
e todos os outros obstáculos, descartando todos aqueles que não estão na linha de vista. Então encontramos todos os envelopes das bordas conectando
com essas arestas de transição, derrubando as que estão bloqueadas por outros obstáculos. Retornamos todos esses envelopes das bordas, salvando as bordas da transição para retornar em uma chamada subsequente aos
neighbors()
.
O último caso é quando A * contornou a borda do envelope ao longo do obstáculo
e ele precisa sair
ao longo da borda da transição. Como a etapa anterior calculou e salvou todas as arestas de transição, você pode simplesmente encontrar e retornar o conjunto correto de arestas.
Cortamos os envelopes pontiagudos das costelas
As bordas do envelope conectam as bordas de transição que tocam em um círculo, mas acontece que muitas dessas bordas do envelope não são adequadas para o uso ideal. Podemos acelerar o algoritmo eliminando-o.
O caminho ideal através da floresta de obstáculos sempre consiste em alternar arestas de transição e envelopes de arestas. Suponha que insira um nó
e decida como sair dela:
Entrar através
significa que estamos nos movendo
no sentido horário (
) Devemos sair pelo nó, o que nos permite continuar movendo no sentido horário (
), ou seja, só podemos sair pelo nó
ou
. Se você sair pela
então uma
inflexão (
) maneiras que nunca serão ideais. Precisamos filtrar essas arestas pontiagudas.
Primeiro, observe que A * processa cada extremidade não orientada de qualquer maneira.
como duas arestas orientadas
e
. Podemos tirar vantagem disso marcando as bordas e os nós com orientação.
- Nós tornar-se nós com orientação - no sentido horário ( ) ou no sentido anti-horário ( ) setas.
- Bordas de transição não orientadas tornar-se arestas orientadas e onde e São orientações e significa a direção oposta .
- Envelopes de costela não orientados tornar-se arestas orientadas e . É aqui que ocorre a filtragem: não habilitamos e , porque uma mudança de direção cria torções ( )
Em nosso circuito, o nó
vai se transformar em dois nós,
e
tem uma borda de transição de entrada
e borda de transição de saída
. Se pegarmos a estrada através
então deve sair através do nó
que será uma borda de transição
(pela borda do envelope
) ou borda de transição
(pela borda do envelope
) Não podemos sair completamente
, porque o sentido de rotação mudará dessa maneira e filtramos o envelope da borda
.
Ao filtrar esses envelopes pontiagudos de arestas do gráfico, aumentamos a eficiência do algoritmo.
Cortar arestas que se cruzam
Os caminhos parciais podem ser cortados, cujas últimas arestas cruzam a penúltima aresta da transição.
Obstáculos poligonais
Veja
Gemas de Programação de Jogos 2 , Capítulo 3.10, Otimizando a Localização de Pontos de Visibilidade, escrito por Thomas Young. Este capítulo discute nós de recorte, mas não para círculos, mas para polígonos.
Referências