Estou tentando combinar duas coisas. Estou escrevendo um jogo e preciso determinar os quadrados da grade em uma linha com os pontos finais de ponto flutuante.
Além disso, preciso incluir todos os quadrados da grade em que toca (ou seja, não apenas a linha de Bresenham, mas a linha azul):
Alguém pode me oferecer alguma idéia de como fazer isso? A solução óbvia é usar o algoritmo de linha ingênuo, mas há algo mais otimizado (mais rápido)?
c#
algorithm
grid
interpolation
floating-point
SmartK8
fonte
fonte
Respostas:
Você está procurando um algoritmo de deslocamento de grade. Este artigo fornece uma boa implementação;
Aqui está a implementação básica em 2D encontrada no artigo:
Há também uma versão 3D de projeção de raios no papel.
Caso o link apodreça , você poderá encontrar muitos espelhos com seu nome: Um algoritmo transversal voxel mais rápido para rastreamento de raios .
fonte
A ideia de Blue é boa, mas a implementação é um pouco desajeitada. De fato, você pode fazer isso facilmente sem o sqrt. Vamos supor que você exclua casos degenerados (
BeginX==EndX || BeginY==EndY
) e se concentre apenas nas direções da linha no primeiro quadranteBeginX < EndX && BeginY < EndY
. Você também precisará implementar uma versão para pelo menos outro quadrante, mas isso é muito semelhante à versão do primeiro quadrante - você só verifica outras arestas. No pseudo-código C'ish:Agora, para outros quadrantes, basta alterar a condição
++cx
ou++cy
e do loop. Se você usar isso para colisão, provavelmente precisará implementar todas as 4 versões; caso contrário, poderá se safar de duas trocando adequadamente os pontos inicial e final.fonte
Sua suposição não é necessariamente encontrar as células, mas as linhas que ela cruza nesta grade.
Por exemplo, tirando sua imagem, podemos destacar não as células, mas as linhas da grade que ela cruza:
Isso mostra que, se cruzar uma linha de grade, as células de ambos os lados dessa linha são aquelas preenchidas.
Você pode usar um algoritmo de interseção para descobrir se sua linha de ponto flutuante os cruzará escalando seus pontos em pixels. Se você tiver uma proporção de 1,0: 1 de coordenadas flutuantes: pixels, será classificada e poderá traduzi-la diretamente. Usando o algoritmo de interseção do segmento de linha, você pode verificar se a linha inferior esquerda (1,7) (2,7) cruza com a linha (1.3,6.2) (6.51,2.9).http://alienryderflex.com/intersect/
Alguma tradução de c para C # será necessária, mas você pode obter a ideia nesse documento. Colocarei o código abaixo, caso o link seja quebrado.
Se você precisar descobrir apenas quando (e onde) os segmentos de linha se cruzam, você pode modificar a função da seguinte maneira:
fonte
Demonstração JS:
Mostrar snippet de código
fonte
Encontrei o mesmo problema hoje e fiz uma grande montanha de espaguete de uma colina, mas acabei com algo que funciona: https://github.com/SnpM/Pan-Line-Algorithm .
No Leiame:
O Leia-me explica a solução muito melhor que o código. Estou pensando em revisá-lo para ser menos indutor de dor de cabeça.
Sei que estou com um ano de atraso para essa pergunta, mas espero que isso chegue a outras pessoas que estão procurando uma solução para esse problema.
fonte