Abaixo está um exemplo de imagem, se eu tiver um ponto do ponto branco no meio e desejar encontrar o local mais próximo possível do círculo azul (que obviamente está no local em que o coloquei), se todos os círculos vermelhos já existirem . Como posso encontrar esse local?
O desempenho para mim não é uma grande preocupação para este aplicativo.
design
design-patterns
algorithms
performance
geometry
Botânico
fonte
fonte
Respostas:
Esta não é uma solução geral, pois há várias situações em que não fornecerá a posição do círculo azul a menor distância do ponto branco. Por exemplo, se você tiver 100 bolas vermelhas agrupadas e o ponto branco estiver longe desse grupo de bolas vermelhas, nenhuma delas terá influência na posição do círculo azul que pode ser centralizada no ponto branco . Nem mostrará todos os detalhes dos cálculos. De qualquer forma, para um subconjunto de configurações, em que a solução (círculo azul) é tangente a dois círculos vermelhos, o seguinte deve funcionar:
1) seja R o raio do círculo azul
2) faça um loop sobre todos os pares de círculos vermelhos, sim Eu sei que isso é O (n2).
3) para cada par de círculos i, j com centros em (xi, yi) e (xj, yj) com o raio respectivo ri e rj, calcule o quadrado da distância entre o par de círculos
4) coloque todos os pares de círculos que
em uma lista.
5) percorra a lista, encontrando as 2 soluções dos círculos do raio R tangentes aos círculos iej. Para fazer isso, use estas equações junto com esta imagem
com as informações acima, você pode encontrar (X1ij, Y1ij) e (X2ij, Y2ij) os centros dos 2 círculos tangentes aos círculos iej. Para cada candidato, o círculo azul passa por todos os outros círculos vermelhos e verifique se não se sobrepõem. Caso contrário, verifique a distância do círculo branco. Se você mantiver a distância menor, acho que terá a solução ao terminar de percorrer a lista de pares de círculos. O algoritmo parece O (n3).
fonte
O posicionamento mais próximo ao ponto estará no ponto ou tocando em um círculo.
portanto, verifique primeiro o ponto, depois role o novo círculo em torno da borda de cada círculo existente, calculando a distância do ponto e se você se sobrepuser à medida que avança e mantendo o controle do ponto de distância mínimo. Pare quando você percorrer todos os círculos.
ie verifique todos os pontos nas linhas verdes, além do círculo branco. onde a linha verde é um círculo com raio do vermelho mais o azul
você precisa verificar toda a linha verde, não apenas as interseções para cobrir esses casos de arestas.
Obviamente, o tamanho da etapa da sua travessia será importante em termos de desempenho. Mas como você declara que o desempenho não é um problema, escolha o valor correspondente à resolução do seu valor de saída. ou seja, flutuar, longo?
esclarecimento:
minha sugestão é a força bruta de todos os pontos ao redor de cada círculo, testando a sobreposição com todos os outros círculos em cada ponto. sem esperteza.
Se a foto de exemplo é indicativa do número de círculos e da resolução, não deve ser um problema para um PC padrão
temos 20 círculos de raio médio 200, ou seja, aproximadamente 20 * 2 π * 200 pontos * 20 testes de interseção = 4800000 iterações
Nota:
Abordagens iterativas como essa são falhas, pois o tamanho da sua etapa, neste caso a resolução da sua saída, pode afetar muito o resultado.
Digamos que eu tenha dois círculos vermelhos separados por 2 pixels e um círculo azul de raio de 1 pixel para espremer entre eles. Claramente, com um dos dois pixels como centro do círculo azul, ele se sobrepõe a um dos vermelhos. mas obviamente há espaço para o círculo se o centro estiver entre os dois pixels.
Daí o meu comentário perguntando sobre a resolução da saída. que você disse que poderia ser qualquer coisa.
você também pode resolver a equação simultânea para cada par de círculos com raio aumentado pelo raio do círculo azul.
isso fornecerá os pontos em que o círculo azul tocará nos dois círculos vermelhos com mais precisão do que na iteração.
Contudo. existem várias condições em que, se você fizer isso, obtém a resposta errada ou não. ie
1 ou nenhum círculo
2 ou mais círculos, mas com o ponto alvo distante e fora deles.
muitos círculos, mas com o ponto alvo próximo à superfície
fonte
Esse plunk contém código de trabalho,
Conceito
Os círculos dados são C1, C2 .... Cn
e coordenadas do círculo Cn é Cnx, Cny e raio é Cr
e o raio do círculo requerido é R
se o círculo azul estiver no local X, Y e se não entrar em conflito com outros círculos, as equações a seguir serão verdadeiras
mudando a primeira equação,
para que as equações possam reescrever como,
Implementação
comece pela coordenada do ponto branco (Xw, Yw),
a primeira coordenada encontrada para satisfazer todas as equações é a localização do círculo azul
fonte
círculo estendido é um dos círculos com raio estendido por r
Há algum trabalho extra se O não estiver no centro do círculo. Então, no momento, assuma O == C0
Calcule todas as interseções de todos os círculos com C0, usando seus respectivos raios mais r , ou seja, intercepte os círculos estendidos com o C0 estendido. Se não houver interseções, o ponto que você procura estará em C0, se houver interseções, para cada interseção, verifique se está dentro de outro círculo estendido (você pode limitar-se aos círculos que tiveram interseções com C0). Pegue a primeira interseção que não está em outro círculo estendido como P, pode haver outras.
Se não houver interseções entre os círculos estendidos e C0 que não estão dentro de outro círculo estendido, calcule as interseções de todos os círculos estendidos entre si. Em seguida, verifique essas interseções na ordem da distância para O, novamente se alguma das interseções se encontra dentro de outro círculo estendido, se sim, descarte, se não, esse é o seu resultado.
Se você imaginar isso, desenhe uma linha ao redor de todos os círculos que indicam uma possível localização para o seu círculo azul, a união de todos os círculos estendidos indicará a área que seu círculo azul não pode estar. O ponto que você está procurando é o ponto mais próximo que não está nessa união. Se houver algum ponto em C0 que não esteja nessa união que é a solução, se C0 estiver totalmente coberto, P deverá estar em uma interseção entre dois outros círculos estendidos e deve estar em uma área não coberta por esta união (ou seja, não em um círculo estendido ).
Este é O (n ^ 2), existem algumas maneiras de melhorar isso, porém, uma grade pode ser usada para reduzir o esforço da pesquisa em pares, também acho que classificar os círculos pela proximidade com O (a distância entre o dois círculos reduzidos pelo rádio) ajudariam a limitar o espaço de pesquisa para a pesquisa de cobertura e interseção
fonte
Possíveis soluções lookup
Pesquisa real da solução entre as possíveis soluções
Agora você tem um conjunto de pontos que são possíveis soluções , percorra-os e verifique cada um.
NB: Não estou dizendo que a implementação do algoritmo deva ser exatamente descrita. Você pode tentar melhorar o desempenho usando programação dinâmica ou ignorando possíveis soluções, onde é óbvio que elas não funcionarão.
fonte