Como descobrir com segurança se duas curvas planares de Bezier se cruzam? Por "confiável", quero dizer que o teste responderá "sim" somente quando as curvas se cruzam e "não" somente quando elas não se cruzam. Não preciso saber em quais parâmetros o cruzamento foi encontrado. Eu também gostaria de usar números de ponto flutuante na implementação.
Encontrei várias respostas no StackOverflow que usam as caixas delimitadoras das curvas para o teste: não é isso que eu procuro, pois esse teste pode relatar interseção, mesmo que as curvas não se cruzem.
A coisa mais próxima que encontrei até agora é a " cunha delimitadora " de Sederberg e Meyers, mas "apenas" distingue entre no máximo uma e duas ou mais interseções, enquanto eu quero saber se existe no máximo zero e uma ou mais interseções.
fonte
Respostas:
Uma maneira alternativa de formular o problema é definir uma função que dê a distância entre os pontos nas duas curvas, em função dos parâmetros das curvas. Em seguida, tente encontrar o mínimo global dessa função. Se as curvas se cruzarem, o mínimo será zero; caso contrário, o mínimo será uma distância positiva.
Para ser expressa, dado um par de curvas 2D definidos por , definir a distância ao quadrado como-c1,c2:[0,1]→R2
fonte
[Aviso: acho que o seguinte deve funcionar, mas não o codifiquei de fato]
Eu não conseguia pensar em um método "trivial" de produzir uma resposta sim / não, mas o seguinte seria uma abordagem razoável para uma solução prática para a pergunta.
Vamos assumir que nossas curvas são A (s) e B (t) com pontos de controle { A0, A1..An } e { B0, .. Bm }, respectivamente.
Parece-me que, dado um par de Beziers 2D para os quais desejamos determinar a interferência ou não, existem seis casos a serem considerados:
Caso em que podemos "trivialmente" determinar que eles não se cruzam.
Caso em que eles cruzam um número finito de vezes e podemos "facilmente" determinar se eles definitivamente cruzam pelo menos uma vez (mas na verdade não nos importamos onde essas interseções ocorrem)
Um dos Beziers é degenerado, ou seja, um ponto (que ocorrerá se todos os pontos de controle forem idênticos). Podemos assumir que já lidamos com o caso em que ambos são pontos.
Uma ou mais das curvas estão fechadas, por exemplo. A0 == An. Para simplificar a vida, subdividiremos essas curvas e começaremos novamente.
Há um número infinito de pontos de interseção porque cada um é um subconjunto de um Bezier "pai" e eles se sobrepõem.
Não temos certeza dos casos acima e precisamos de mais investigações
Por enquanto, ignoraremos 3 e 4, mas voltaremos a eles mais tarde.
Caso 1
Como você sugere na sua pergunta, se as respectivas caixas delimitadoras dos pontos de controle de A e B ) não se cruzam, as curvas não podem se cruzar. Obviamente, este é um teste rápido de rejeição, mas é excessivamente conservador. Como você provavelmente sabe, com uma curva de Bezier, o casco convexo de seus pontos de controle forma um limite (mais apertado) na curva. Assim, podemos usar a técnica do eixo de separação para decidir se os cascos de A e B não se cruzam. (por exemplo, como mostrado na Wikipedia :)
Caso 2
Se o teste do caso 1 falhar, você poderá verificar a existência "trivial" de uma interseção. Agora, provavelmente existem maneiras melhores de fazer isso, mas me ocorreu a seguinte abordagem, relativamente barata:
Considere apenas a curva A:
Se fizermos o mesmo com a curva B, obtemos o seguinte caso (possível):
Caso 6
Caso 3 e 5
É aqui que se torna um pouco mais tedioso.
Se o "caso 3" passar no teste "caso 1", parece-me que você precisa resolver uma interseção real. Dado que existe um processo simples para mapear os N pontos de controle de um Bezier, A (s), para os pontos N-1 do Bezier, A '(s), representando sua primeira derivada então (desde que seja tomado cuidado Em situações relativamente raras, chamadas "degeneradas", onde a 1ª derivada chega a zero), a iteração de Newton (em uma dimensão) pode ser usada para encontrar possíveis soluções.
Observe também que, como os pontos de controle de A '(s) são limitados aos valores derivativos, existe o potencial de eliminar antecipadamente alguns casos.
O caso 5 parece relativamente improvável; talvez apenas após algumas recursões não exista uma prova conclusiva, alguém poderia tentar cada ponto final de A na curva B e vice-versa. Isso daria apenas uma prova de interseção - não uma prova de não interseção.
fonte