Risposte:
Ecco il mio tentativo. I seguenti algoritmi sono tutt'altro che perfetti , ma sono semplici e credo che dovresti iniziare con questo, verificare se funzionano nella tua situazione e passare a qualcosa di più veloce e / o più preciso in seguito.
L'idea è la seguente:
La curva di Bézier è parametrizzata da una funzione che F(t)
utilizza una serie di punti di controllo e un parametro variabile t
. Il numero di punti generatori non è importante.
La linea è parametrizzata da due punti A
e B
.
Lascia SAMPLES = 10
per esempio
Inizia con t0 = 0
et1 = 1
Permettere dt = (t1 - t0) / SAMPLES
Se dt < 1e-10
(o qualsiasi altra condizione di precisione che ritieni appropriata), l' algoritmo è finito e la risposta èF(t0)
.
Calcola un elenco di SAMPLES + 1
punti sulla curva di Bézier:
L[0] = F(t0)
L[1] = F(t0 + dt)
L[2] = F(t0 + 2 * dt)
L[SAMPLES] = F(t0 + SAMPLES * dt)
Trova il punto L
con l'indice i
più vicino alla linea. Utilizzare qualsiasi metodo di distanza punto / linea che si conosce, ad esempio la distanza quadrata ||AB^L[i]A||² / ||AB||²
dove ^
indica il prodotto incrociato ed ||…||
è la distanza.
Se i == 0
impostato i = 1
; se i == SAMPLES
, impostarei = SAMPLES - 1
Let t1 = t0 + (i + 1) * dt
andt0 = t0 + (i - 1) * dt
Torna al passaggio 3.
Questa volta abbiamo due curve di Bézier, parametrizzate da F(t)
e G(t)
.
Lascia SAMPLES = 10
per esempio
Inizia con t0 = 0
, t1 = 1
, s0 = 0
es1 = 1
Permettere dt = (t1 - t0) / SAMPLES
Permettere ds = (s1 - s0) / SAMPLES
Se dt < 1e-10
(o qualsiasi altra condizione di precisione che ritieni appropriata), l' algoritmo è finito e la risposta èF(t0)
.
SE questa è la prima esecuzione del ciclo:
6.1. Calcola un elenco di SAMPLES + 1
punti su F
( vedi sopra ).
6.2. Calcola un elenco di SAMPLES + 1
punti su G
.
6.3. Trova la coppia di punti più vicini tra loro.
6.4. Aggiornamento t0
, t1
, s0
, s1
come visto sopra.
ELSE : in alternativa calcola un elenco di punti su F
OR un elenco di punti su G
, quindi trova quale punto F
è il più vicino G(s0)
e aggiorna t0
e t1
, O quale punto G
è il più vicino F(t0)
e aggiorna s0
e s1
.
Torna al passaggio 3.
In base alla progettazione, questi algoritmi convergeranno sempre al minimo locale. Tuttavia, non vi è alcuna garanzia che convergeranno alla soluzione migliore. In particolare, l'algoritmo della curva di Bézier non è affatto buono, e nel caso in cui due curve siano vicine l'una all'altra in molti punti potresti purtroppo perdere la soluzione da un colpo lungo.
Ma come ho detto, prima di iniziare a pensare a soluzioni più solide, dovresti prima sperimentare quelle semplici.
1) Traduci tutto in un asse, quindi invece di dover calcolare la lunghezza di un punto in, la 'linea', la 'linea' è, diciamo, l'asse Y.
Quindi, data una curva più bezier, direi che dipende dal numero di punti di controllo.
Se ce ne sono tre (inizio, "controllo" e fine), farei una sorta di scansione (diciamo ciascuno un paio di percentuali e poi perfeziono tra quelli più vicini (con un approccio "binario").
Altri punti proverei la coppia più vicina all'asse Y (tradotto).
Sono sicuro che un ragazzo di matematica può darti la soluzione esatta (in matematica) ma se vuoi trovare la / una soluzione in un videogioco potresti stare meglio con una soluzione leggermente ok poiché la soluzione reale potrebbe contenere diverse risposte ( Non sto nemmeno parlando della potenza di elaborazione).
Alcune risposte dalla pagina del blog Algorithmist , che trova correttamente il punto più vicino sulla curva di Bezier quadratica data.
Demo .
Per la curva di Bezier - caso di linea retta, il modo più accurato per trovare la risposta è effettuare le seguenti operazioni: