Domanda

ho scritto un po 'di software grafici base in Clojure / Java utilizzando drawLine() sul contesto grafico di un JPanel modificato. Il tracciato si sta lavorando bene, ma sono venuto a un punto morto durante il tentativo di conversione di un pixel selezionato al punto dati più vicino.

Ho una semplice corrispondenza biunivoca tra l'elenco di tutti i pixel che i punti finali marchio delle mie linee e i miei dati grezzi effettivi. Che cosa ho bisogno è un surjection da tutti i pixel (per esempio, 1200x600 px 2 ) della mia finestra del grafico ai pixel nella mia lista dei pixel, che mi dà una mappatura banale da quello ai miei punti di dati effettivi.

per es.

<x,y>(px) ----> <~x,~y>(pixel points) ----> <x,y>(data)

Questa è la situazione come sto immaginando subito:

  • Un pixel si fa clic nella finestra del grafico principale, e il MouseListener cattura quell'evento e mi dà le coordinate <x,y> dell'azione.

  • Questa informazione viene passata ad una funzione che restituisce un predicato che determina se un valore passato è "abbastanza buono", e filtro se la lista con quella pred, e prendere il primo valore che okays.

    • Forse, invece di un predicato, restituisce una funzione che viene passata la lista dei pixel-punti, e restituisce una lista di tuple (x index) che indicano quanto è buono il punto è con la grandezza di x, e dove quel punto è con index. Farei questo con entrambi i punti x e y dei punti. Ho poi filtro però che e trovare quello con la x max, e prendere quello di essere il punto che è più probabile che sia quello che l'utente voleva dire.

Sono queste soluzioni ragionevoli a questo problema? Sembra che la soluzione che prevede feedback di confidenza (distanza da pix-pt, forse) potrebbe essere troppo pesante processore e un pesante bit di memoria, se ho in mano tutti i punti in memoria di nuovo. L'altra soluzione, utilizzando solo il predicato, non sembra che sarebbe sempre accurate.

Questo è un risolto problema, come altre librerie di grafici hanno dimostrato, ma è difficile trovare informazioni su di esso non nella fonte di alcuni di questi programmi, e ci deve essere un modo migliore poi scavare attraverso le migliaia di righe di Java per scoprirlo.

sto cercando soluzioni migliori, o puntatori solo generali e consigli su quelli che ho offerti, se possibile.

È stato utile?

Soluzione

Quindi immagino qualcosa come JFreeChart semplicemente non era il taglio per la vostra applicazione? Se non si è andati su questa strada ancora, io suggerirei di controllare fuori prima di tentare di rotolare il proprio.

In ogni caso, se siete alla ricerca del punto più vicino ad un evento del mouse, ottenendo il punto con il minimo distanza euclidea (se è sotto una certa soglia) e presentando che darà il comportamento più prevedibile per l'utente. Il lato negativo è che la distanza euclidea è relativamente lento per grandi insiemi di dati. È possibile utilizzare trucchi come ignorare la radice quadrata o BSP alberi per accelerarlo un po '. Ma se sono ancora necessarie le ottimizzazioni in realtà dipende da quanti punti di dati si sta lavorando con. Profilo di una soluzione un po 'ingenuo in un tipico caso prima di entrare in modalità di ottimizzazione.

Altri suggerimenti

Credo che il tuo approccio è decente. Questo fondamentalmente richiede solo un'iterazione attraverso l'array di dati, un po 'di matematica semplici e senza allocazioni per ogni passo in modo dovrebbero essere molto veloce.

E 'probabilmente buono come si sta per ottenere a meno di iniziare a utilizzare una qualche forma di schema di partizionamento spaziale come una quadtree, che sarebbe veramente solo senso se l'array di dati è molto grande.

Alcuni codice Clojure che può aiutare:

(defn squared-distance [x y point]
  (let [dx (- x (.x point))
        dy (- y (.y point))]
     (+ (* dx dx) (* dy dy))))

(defn closest 
  ([x y points]
    (let [v (first points)] 
      (closest x y (rest points) (squared-distance x y v) v)))
  ([x y points bestdist best]
    (if (empty? points)
      best
      (let [v (first points)
            dist (squared-distance x y v)] 
        (if (< dist bestdist)
          (recur x y (rest points) dist v)
          (recur x y (rest points) bestdist best))))))
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top