Para detalhar um pouco a resposta de Nick: o conceito principal por trás do algoritmo DDA (que funciona tão bem em três dimensões) é que, para cada eixo da sua grade, você acompanha o próximo 'ponto de cruzamento' desse eixo em termos de parâmetro de linha; cada etapa do algoritmo consiste em descobrir qual eixo tem o próximo ponto de cruzamento (que é uma comparação simples em duas dimensões), executar o passo apropriado e atualizar os valores da próxima travessia para cada eixo.
A linha aqui pode ser escrita como '(x, y) = (x0, y0) + t * (m, n)', onde m = x1-x0 e n = y1-y0. Se as dimensões de uma célula de grade são gx e gy, então dx - a distância (em termos do parâmetro t) necessária para cruzar uma célula de grade - pode ser encontrada com um pouco de álgebra rápida: a partir do par de equações x = x0 + m t, (x + gx) = x0 + m (t + dx) obtemos gx = m * dx, ou seja, dx = gx / m. Da mesma forma, dy = gy / n. O algoritmo controla next_x (a distância até o próximo ponto vermelho ao longo da linha) e next_y (a distância até o próximo ponto azul ao longo da linha) e os atualiza toda vez que atinge outro cruzamento, para que o loop central se pareça com este :
while ( cur_t < t_max) {
if ( next_x < next_y ) {
cell_x++;
cur_t += next_x;
next_y -= next_x;
next_x = dx;
} else {
cell_y++;
cur_t += next_y;
next_x -= next_y;
next_y = dy;
}
// Process the cell (cell_x, cell_y)
}
Observe que esse código está faltando muitos detalhes - ele não informa como inicializar next_x e next_y, por exemplo. Existem maneiras de eliminar a maioria das divisões, facilitando o tratamento de casos especiais, como linhas verticais e horizontais. Se você incrementa ou diminui cell_x e cell_y, depende do quadrante em que sua linha está - observe que, na minha linha de exemplo, você estaria diminuindo cell_x a cada marca, pois m (x1-x0) é negativo. Você também precisa decidir como vai lidar com os casos em que sua linha passa exatamente pelo canto entre as células, em vez de fazer a transição em uma aresta; existem muitos pequenos detalhes que podem dar errado e precisam de muitos testes. Ainda assim, espero que isso lhe dê uma imagem de qual é a idéia principal do algoritmo.