Respostas:
Aqui está a minha tentativa. Os algoritmos a seguir estão longe de serem perfeitos , mas são simples e acredito que você deve começar com isso, verificar se eles funcionam na sua situação e mudar para algo mais rápido e / ou mais preciso posteriormente.
A ideia é a seguinte:
A curva de Bézier é parametrizada por uma função F(t)
usando um conjunto de pontos de controle e um parâmetro variável t
. O número de pontos de geração não é importante.
A linha é parametrizada por dois pontos A
e B
.
Deixe SAMPLES = 10
por exemplo
Comece com t0 = 0
et1 = 1
Deixei dt = (t1 - t0) / SAMPLES
Se dt < 1e-10
(ou qualquer outra condição de precisão que você achar conveniente), o algoritmo será concluído e a resposta seráF(t0)
.
Calcule uma lista de SAMPLES + 1
pontos na curva de Bézier:
L[0] = F(t0)
L[1] = F(t0 + dt)
L[2] = F(t0 + 2 * dt)
L[SAMPLES] = F(t0 + SAMPLES * dt)
Descubra qual ponto do L
índice i
é o mais próximo da linha. Use qualquer método de distância de ponto / linha que você conhece, por exemplo, a distância quadrada ||AB^L[i]A||² / ||AB||²
onde ^
denota produto cruzado e ||…||
é a distância.
Se i == 0
, defina i = 1
; se i == SAMPLES
, definai = SAMPLES - 1
Deixe t1 = t0 + (i + 1) * dt
et0 = t0 + (i - 1) * dt
Volte para a etapa 3.
Desta vez, temos duas curvas de Bézier, parametrizadas por F(t)
e G(t)
.
Deixe SAMPLES = 10
por exemplo
Comece com t0 = 0
, t1 = 1
, s0 = 0
es1 = 1
Deixei dt = (t1 - t0) / SAMPLES
Deixei ds = (s1 - s0) / SAMPLES
Se dt < 1e-10
(ou qualquer outra condição de precisão que você achar conveniente), o algoritmo será concluído e a resposta seráF(t0)
.
SE esta é a primeira execução do loop:
6.1 Calcule uma lista de SAMPLES + 1
pontos F
( veja acima ).
6.2 Calcule uma lista de SAMPLES + 1
pontos G
.
6.3 Descubra qual par de pontos está mais próximo um do outro.
6.4 Atualização t0
, t1
, s0
, s1
como visto acima.
ELSE : alternativamente, calcule uma lista de pontos em F
OU uma lista de pontos G
, depois encontre qual ponto F
está mais próximo G(s0)
e atualiza t0
e t1
, OU qual ponto G
está mais próximo F(t0)
e atualiza s0
e s1
.
Volte para a etapa 3.
Por design, esses algoritmos sempre convergem para um mínimo local. No entanto, não há garantia de que eles convergirão para a melhor solução. Em particular, o algoritmo de curva de Bézier não é muito bom e, no caso de duas curvas estarem próximas umas das outras em muitos lugares, você pode, infelizmente, perder a solução a longo prazo.
Mas como eu disse, antes de começar a pensar em soluções mais robustas, você deve primeiro experimentar essas simples.
1) Traduza tudo para um eixo, portanto, em vez de precisar calcular o comprimento de um ponto para, a 'linha', a 'linha' é, por exemplo, o eixo Y.
Então, dada uma curva mais bezier, eu diria que depende do número de pontos de controle.
Se houver três (início, 'controle' e fim), eu faria algum tipo de verificação (digamos cada um por cento e depois refino entre os mais próximos (digamos, uma abordagem 'binária').
Mais pontos que eu experimentaria o casal mais próximo do (eixo Y traduzido).
Tenho certeza de que um cara de matemática pode lhe dar a solução exata (em matemática), mas se você quiser encontrar a solução / em um videogame, poderá estar melhor com uma solução ligeiramente boa, pois a solução real pode conter várias respostas ( Nem estou falando de poder de processamento).
Algumas respostas da página do blog Algorithmist , que encontra corretamente o ponto mais próximo na curva quadrática de bezier.
Demo .
Para a curva de Bezier - caixa reta, a maneira mais precisa de encontrar a resposta é fazer o seguinte: