Podemos fazer uma varredura radial de linha para resolver o problema -
Classifique os pontos finais dos segmentos de linha com o ângulo da união da linha P e o ponto final Q fazer, quebrar laços wrt distância de P. Agora, quando varremos radialmente (no sentido horário), mantemos dois tipos de eventos 'abertos' e 'fechados', que correspondem à abertura e fechamento de algum novo segmento de linha. Acompanhe quantos segmentos de linha estão 'ativos' a qualquer momento ('ativo' significa que encontramos o ponto final que corresponde ao evento 'aberto' do segmento de linha, mas não encontramos o outro ponto final no varrer ainda). Se em algum momento tivermos exatamente um segmento de linha 'ativo', esse segmento será visível emP.
Devemos tomar cuidado para que, ao iniciar a varredura, sempre comecemos em algum evento 'aberto'.
Haverá 2 nesses eventos e acompanhar o número de segmentos ativos podem ser realizados em tempo constante por segmento (por meio de uma tabela de hash ou tempo de logaritmo, usando uma BST balanceada). Portanto, o passo dominante no algoritmo é a classificação que levaO (n) tempo conforme necessário.
Como em todos os problemas de geometria computacional, pode haver alguns casos de esquecimento que eu negligenciei, mas a ideia geral de que, em algum ponto do tempo durante a varredura radial da linha, se tivermos exatamente um segmento de linha ativo, será visível a partir de P é o ponto crucial para resolver esse problema.