Question

J'ai écrit un logiciel de base dans Clojure graphique / Java en utilisant drawLine() le contexte graphique d'un JPanel modifié. Le tracé lui-même travaille bien, mais je suis venu à une impasse tout en essayant de convertir un pixel clicked au point de données le plus proche.

Je simple bijection entre la liste de tous les pixels que les points finaux de la marque de mes lignes et mes données brutes réelles. Ce que je besoin est un surjection de tous les pixels (par exemple, 1200x600 px 2 ) de ma fenêtre graphique aux pixels dans ma liste de pixels, me donnant une cartographie triviale de ce à mes points de données réels.

par exemple.

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

Telle est la situation que je me fais maintenant:

  • Un pixel est cliqué dans la fenêtre principale du graphique, et le MouseListener attrape cet événement et me donne les coordonnées <x,y> de l'action.

  • Cette information est transmise à une fonction qui renvoie un prédicat qui détermine si oui ou non une valeur transmise est « assez bon », et filtre si la liste avec cette pred, et prendre la première valeur qu'il okays.

    • Peut-être, au lieu d'un prédicat, il retourne une fonction qui est passée la liste des pixels points, et retourne une liste de tuples (x index) qui indiquent à quel point le point est l'ampleur de x, et où ce point est avec index. Je ferais cela avec les deux points x et les points y. Je puis filtre bien que et trouver celui avec x max, et que l'on prend pour être le point qui est le plus susceptible d'être celui que l'utilisateur voulait dire.

sont ces solutions raisonnables à ce problème? Il semble que la solution qui implique des cotes de confiance (distance de pix-pt, peut-être) peut-être trop lourd processeur, et un peu lourd mémoire si je tiens tous les points encore en mémoire. L'autre solution, en utilisant simplement le prédicat, ne semble pas que ce serait toujours exact.

est résolu problème, que d'autres bibliothèques graphiques ont montré, mais il est difficile de trouver des informations à ce sujet autre que dans la source de certains de ces programmes, et il doit y avoir une meilleure façon puis de creuser à travers les milliers de lignes de Java pour trouver cela.

Je suis à la recherche de meilleures solutions, ou des pointeurs juste généraux et des conseils sur ceux que j'ai proposé, si possible.

Était-ce utile?

La solution

Alors je devine quelque chose comme JFreeChart juste n'a pas de coupe pour votre application? Si vous n'êtes pas allé dans cette voie encore, je vous suggère de le vérifier avant d'essayer de rouler votre propre.

Quoi qu'il en soit, si vous êtes à la recherche du point le plus proche d'un événement de souris, obtenir le point avec le minimum distance euclidienne (si elle est inférieure à un certain seuil) et la présentation qui donnera le comportement le plus prévisible pour l'utilisateur. L'inconvénient est que la distance euclidienne est relativement lent pour les grands ensembles de données. Vous pouvez utiliser des astuces comme ignorer la racine carrée ou arbres BSP pour accélérer un peu. Mais si ces optimisations sont encore nécessaires dépend vraiment de combien de points de données que vous travaillez avec. Profil d'une solution peu naïve dans un cas typique avant d'entrer dans le mode d'optimisation.

Autres conseils

Je pense que votre approche est bonne. En gros, cela ne nécessite qu'une seule itération dans votre tableau de données, un peu de mathématiques simples et de pas d'allocation à chaque étape devrait donc être très rapide.

Il est probablement aussi bon que vous allez obtenir à moins que vous commencez à utiliser une certaine forme de schéma de partitionnement spatial comme un quadtree, ce qui ne ferait vraiment sens que si votre tableau de données est très grande.

Une partie du code Clojure qui peut aider:

(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))))))
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top