Esse desafio é baseado na detecção de colisão real que tive que escrever recentemente para um jogo simples.
Escreva um programa ou função que, dados dois objetos, retorne um valor verdadeiro ou falso, dependendo de os dois objetos estarem em colisão (ou seja, se cruzarem) ou não.
Você precisa suportar três tipos de objetos:
- Segmentos de linha : representados por 4 pontos flutuantes, indicando os dois pontos finais, ou seja (x 1 , y 1 ) e (x 2 , y 2 ) . Você pode assumir que os pontos de extremidade não são idênticos (portanto, o segmento de linha não é degenerado).
- Discos : ou seja, círculos preenchidos, representados por 3 flutuadores, dois para o centro (x, y) e um (positivo) para o raio r .
- Cavidades : são o complemento de um disco. Ou seja, uma cavidade preenche todo o espaço 2D, exceto uma região circular, especificada por um centro e raio.
Seu programa ou função receberá dois desses objetos na forma de um número inteiro de identificação (de sua escolha) e seus 3 ou 4 carros alegóricos. Você pode receber entradas via STDIN, ARGV ou argumento de função. Você pode representar a entrada de qualquer forma conveniente que não seja pré-processada, por exemplo, 8 a 10 números individuais, duas listas de valores separadas por vírgula ou duas listas. O resultado pode ser retornado ou gravado em STDOUT.
Você pode supor que os objetos estejam com pelo menos 10 a 10 unidades de comprimento ou se cruzam com isso, portanto, não precisa se preocupar com as limitações dos tipos de ponto flutuante.
Isso é código de golfe, então a resposta mais curta (em bytes) vence.
Casos de teste
Representando segmentos de linha com 0
, discos 1
e cavidades com 2
, usando um formato de entrada baseado em lista, todos os itens a seguir devem produzir uma saída verdadeira:
[0,[0,0],[2,2]], [0,[1,0],[2,4]] # Crossing line segments
[0,[0.5,0],[-0.5,0]], [1,[0,0],1] # Line contained in a disc
[0,[0.5,0],[1.5,0]], [1,[0,0],1] # Line partially within disc
[0,[-1.5,0.5],[1.5,0.5]], [1,[0,0],1] # Line cutting through disc
[0,[0.5,2],[-0.5,2]], [2,[0,0],1] # Line outside cavity
[0,[0.5,0],[1.5,0]], [2,[0,0],1] # Line partially outside cavity
[0,[-1.5,0.5],[1.5,0.5]], [2,[0,0],1] # Line cutting through cavity
[1,[0,0],1], [1,[0,0],2] # Disc contained within another
[1,[0,0],1.1], [1,[2,0],1.1] # Intersecting discs
[1,[3,0],1], [2,[0,0],1] # Disc outside cavity
[1,[1,0],0.1], [2,[0,0],1] # Disc partially outside cavity
[1,[0,0],2], [2,[0,0],1] # Disc encircling cavity
[2,[0,0],1], [2,[0,0],1] # Any two cavities intersect
[2,[-1,0],1], [2,[1,0],1] # Any two cavities intersect
enquanto o seguinte deve resultar em uma saída falsa
[0,[0,0],[1,0]], [0,[0,1],[1,1]] # Parallel lines
[0,[-2,0],[-1,0]], [0,[1,0],[2,0]] # Collinear non-overlapping lines
[0,[0,0],[2,0]], [0,[1,1],[1,2]] # Intersection outside one segment
[0,[0,0],[1,0]], [0,[2,1],[2,3]] # Intersection outside both segments
[0,[-1,2],[1,2]], [1,[0,0],1] # Line passes outside disc
[0,[2,0],[3,0]], [1,[0,0],1] # Circle lies outside segment
[0,[-0.5,0.5],[0.5,-0.5]], [2,[0,0],1] # Line inside cavity
[1,[-1,0],1], [1,[1,1],0.5] # Non-intersecting circles
[1,[0.5,0],0.1], [2,[0,0],1] # Circle contained within cavity
[0,[-2,0],[-1,0]], [0,[1,0],[2,0]]