Questo è in origine un commento alla ricerca di chiarimenti, ma è troppo lungo per adattarsi. Così ho postato ogni domanda qui, insieme con le mie risposte "what-if" per ogni domanda in base alle possibili risposte.
Prima di chiedere chiarimenti, tutti dovrebbero vedere che l'attuale implementazione ha una complessità temporale quadratica nel numero di waypoint. La notazione è O(N^2)
.
Per dirla semplicemente, se il numero di waypoint è raddoppiato (aumentato a due volte), il tempo di esecuzione sarà approssimativamente quadruplicato (aumentato a quattro volte).
(1) Qual è il numero tipico di waypoint che devi gestire? Se non esiste un numero tipico, indicare il numero massimo possibile di waypoint che il proprio codice deve supportare.
Ad esempio, se si scopre che il problema di prestazioni non si verifica quando N (numero di waypoint) è inferiore a diverse centinaia, è possibile imporre una restrizione software che il movimento del mouse non può essere più lungo di quel numero di pixel. Se questo è accettabile o meno dipende dallo scopo del tuo software.
(2) Ti è permesso usare tecniche di semplificazione della linea per ridurre il numero di waypoint prima di verificare le intersezioni?
La tecnica di semplificazione della linea può ridurre il numero di waypoint di dieci volte (un decimo) o più (meno), quando il movimento del mouse viene utilizzato come input. L'utente dovrà spostare il mouse molto freneticamente per far fallire questa riduzione.
(3) Sai come implementare e utilizzare QuadTree da solo?
Un quadrilatero consente una query O(log N)
caso medio in una raccolta (struttura ad albero) di riquadri di delimitazione che si sovrappongono alla casella di delimitazione della query. Per trovare tutti i riquadri di delimitazione sovrapposti a coppie, prima si aggiungono tutti i riquadri di delimitazione e quindi si esegue una query su ciascun riquadro di delimitazione. Questo dà un totale che è in media caso O(N log N)
, che è migliore dell'implementazione originale che è O(N^2)
.
(4) Qual è la larghezza e l'altezza dell'area di movimento, misurata in pixel, che devi supportare?
Se l'area di movimento totale (in pixel quadrati, ovvero il prodotto di larghezza e altezza) è inferiore a qualche milione, e se è consentito allocare un array che può contenere alcuni milioni di byte (o bit) solo bisogno che ogni elemento sia vero o falso), quindi si può allocare una tale matrice per agire come una bitmap (letteralmente una mappa di bit).
La bitmap verrà inizializzata con false. Quindi, mentre l'utente "dipinge" con il movimento del mouse, i pixel corrispondenti nella bitmap verranno impostati su true.
Avvertenza Si noti che se la traccia pixel dell'utente è di un solo pixel (1 per 1) di larghezza, si verificherà il seguente caso limite:
Supponiamo che la traccia vada da (10, 10)
a (11, 11)
. Più avanti nella traccia, attraversa quel segmento passando (10, 11)
a (11, 10)
. Poiché i pixel stessi non si sovrappongono, questo schema basato su bitmap non riuscirà a rilevare un'intersezione di questo tipo.
La soluzione al caveat è che si deve controllare un quartiere 3 per 3 per i pixel che sono stati dipinti prima. Mentre lo fai, devi anche ricordare di ignorare i pixel che sono appena stati dipinti di recente. È possibile che sia necessario utilizzare un byte per pixel (anziché un bit per pixel) per archiviare informazioni aggiuntive per aiutare a risolvere questo avvertimento.